2010-01-20 38 views
2

是否有ExtUtils::*Module::Build(或其他)類似於Ruby的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沒」在這裏看起來很合適......

+0

你想知道的話,C庫是一個結構包含一個給定的成員?比如time.h中是否存在'tm.tm_gmtoff'? – Schwern 2010-01-21 07:56:50

+0

@Schwern,是的。在這種特殊情況下,無論'struct msghdr'是否有'msg_accrights'。 – pilcrow 2010-01-21 14:07:06

+0

該AFAIK沒有預建的Perl數據庫。通常你使用ExtUtils :: CBuilder編譯一個測試程序。可能有一個CPAN模塊來完成它,但它沒有內置到MakeMaker或Module :: Build中。 – Schwern 2010-01-21 20:04:43

回答

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 I/O教程。我想我可以計算出我有一個錯誤的次數,因爲我的左手「close」失敗了。這些天我使用autodie,它處理所有事情。 – Schwern 2010-05-19 20:51:55

1

我寫了一個包裝圍繞ExtUtils::CBuilder做「此C代碼編譯?」在Build.PLMakefile.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; 
相關問題