2010-01-20 4 views
2

Есть ли ExtUtils::* или Module::Build (или другой) аналог Ruby's mkmf.have_struct_member?Как узнать, имеет ли структура C член в Perl XS?

Я хотел бы сделать что-то подобное (в манере в подсказки/ файл):

.... 
if struct_has_member("msghdr", "msg_accrights") { 
    $self->{CCFLAGS} = join(' ', $self->{CCFLAGS}, "-DTRY_ACCRIGHTS_NOT_CMSG");  
} 
... 

Config.pm не отслеживает конкретную информацию я ищу, и ExtUtils::FindFunctions Ждут» t кажется вполне уместным здесь ...

+0

Вы хотите знать, если структура в библиотеке C содержит заданный элемент? Например, существует ли 'tm.tm_gmtoff' во времени. H? – Schwern

+0

@ Шварн, да. В этом своеобразном случае, имеет ли 'struct msghdr'' msg_accrights' или нет. – pilcrow

+0

Нет встроенной базы данных Perl для этого AFAIK. Обычно вы используете ExtUtils :: CBuilder для компиляции тестовой программы. Для этого может быть модуль CPAN, но он не встроен в MakeMaker или Module :: Build. – Schwern

ответ

3

Я знаю, что это не встроено в 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 }; 

Вероятно, хотят, чтобы сделать это в временный файл и убирать за ним, и т.д ...

+0

Не проверяйте значение 'close'? – 2010-05-19 00:24:42

+0

@ Kinopiko Это не значит, что это полный учебник по безопасному вводу/выводу Perl. Я думаю, что могу подсчитать количество случаев, когда у меня была ошибка, потому что «закрыть» не удалось на левой руке. В эти дни я использую autodie, и он заботится обо всем. – Schwern

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;