Как я могу сказать, если структура C имеет член в Perl XS?
Есть ExtUtils::*
или же Module::Build
(или другой) аналог Ruby's mkmf.have_struct_member
?
Я хотел бы сделать что-то вроде (в виде подсказки / файла):
....
if struct_has_member("msghdr", "msg_accrights") {
$self->{CCFLAGS} = join(' ', $self->{CCFLAGS}, "-DTRY_ACCRIGHTS_NOT_CMSG");
}
...
Config.pm
не отслеживает конкретную информацию, которую я ищу, и ExtUtils::FindFunctions
здесь не совсем уместно...
2 ответа
Я знаю, что это не встроено ни в MakeMaker, ни в Module::Build. На CPAN может быть что-то, что можно сделать, но обычным способом является использование ExtUtils::CBuilder для компиляции небольшой тестовой программы и проверки ее запуска.
use ExtUtils::CBuilder;
open my $fh, ">", "try.c" or die $!;
print $fh <<'END';
#include <time.h>
int main(void) {
struct tm *test;
long foo = test->tm_gmtoff;
return 0;
}
END
close $fh;
$has{"tm.tm_gmtoff"} = 1 if
eval { ExtUtils::CBuilder->new->compile(source => "try.c"); 1 };
Вероятно, хотите сделать это во временном файле и очистить после него и т.д...
Я написал обертку ExtUtils::CBuilder
для выполнения "этот код C компилируется?" тесты типа в Build.PL
или же Makefile.PL
скрипты, называемые ExtUtils:: CChecker.
Например, вы можете легко проверить вышеупомянутое:
use Module::Build;
use ExtUtils::CChecker;
my $cc = ExtUtils::CChecker->new;
$cc->try_compile_run(
define => "TRY_ACCRIGHTS_NOT_CMSG",
source => <<'EOF' );
#include <sys/types.h>
#include <sys/socket.h>
int main(void) {
struct msghdr cmsg;
cmsg.msg_accrights = 0;
return 0;
}
EOF
$cc->new_module_build(
configure_requires => { 'ExtUtils::CChecker' => 0 },
...
)->create_build_script;