我正在尝试在 Red Hat Enterprise Linux 5.5 上的主目录中编译 Perl 5.12.1。但是,当我尝试执行 make 时,最终收到以下错误:
Making IO (all)
make[1]: Entering directory `/users/rmi1/build/perl-5.12.0/dist/IO'
make[1]: Leaving directory `/users/rmi1/build/perl-5.12.0/dist/IO'
Making all in dist/IO
make all PERL_CORE=1 LIBPERL_A=libperl.a LINKTYPE=dynamic
make[1]: Entering directory `/users/rmi1/build/perl-5.12.0/dist/IO'
cc -c -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -DVERSION=\"1.25_02\" -DXS_VERSION=\"1.25_02\" -fPIC "-I../.." IO.c
IO.xs: In function ‘XS_IO__Poll__poll’:
IO.xs:249: error: invalid application of ‘sizeof’ to incomplete type ‘struct pollfd’
IO.xs:253: error: invalid use of undefined type ‘struct pollfd’
IO.xs:253: error: dereferencing pointer to incomplete type
IO.xs:255: error: invalid use of undefined type ‘struct pollfd’
IO.xs:255: error: dereferencing pointer to incomplete type
IO.xs:257: error: invalid use of undefined type ‘struct pollfd’
IO.xs:257: error: dereferencing pointer to incomplete type
IO.xs:261: error: invalid use of undefined type ‘struct pollfd’
IO.xs:261: error: dereferencing pointer to incomplete type
IO.xs:262: error: invalid use of undefined type ‘struct pollfd’
IO.xs:262: error: dereferencing pointer to incomplete type
make[1]: *** [IO.o] Error 1
make[1]: Leaving directory `/users/rmi1/build/perl-5.12.0/dist/IO'
Unsuccessful make(dist/IO): code=512 at make_ext.pl line 449.
make: *** [lib/auto/IO/IO.so] Error 2
这可能是什么原因造成的?
答案1
我刚刚遇到了同样的问题,并找到了根本原因:C_INCLUDE_PATH
环境变量。我的设置如下:
% printenv C_INCLUDE_PATH
C_INCLUDE_PATH=/home/me/REDACTED/include:
这来自某个登录脚本,该脚本正在执行类似以下操作
export C_INCLUDE_PATH=$HOME/REDACTED/include:$C_INCLUDE_PATH
在设置我的环境时。乍一看似乎是正确的;不幸的是,在这种情况下,似乎与 等同——foo:
也就是说foo:.
,该两个冒号分隔列表中的空字符串似乎被隐式地视为与 相同.
。这实际上将当前目录添加到系统包含路径,这与 做了#include <poll.h>
同样的事情#include "poll.h"
,这是不好的。
在 Perl 中,恶意包含路径导致 Perlpoll.h
包含自身而不是/usr/include/poll.h
。由于 Perlpoll.h
具有防止多重包含的保护措施,因此第二个包含不会执行任何操作,最终得到的是 no poll.h
,这很快导致我们都看到的编译器错误。这也解释了为什么您的补丁使问题消失:构建目录中没有./sys/poll.h
,因此编译器最终找到了/usr/include/sys/poll.h
,这最终恰好是您想要的。
我的解决方案是删除 中的多余冒号C_INCLUDE_PATH
。就我而言,我找到了错误设置的脚本并进行了修复,以便明确检查前一个为C_INCLUDE_PATH
空的情况,并且在这种情况下不添加冒号。当然,作为快速的一次性修复,我也可以在构建 Perl 之前手动运行export C_INCLUDE_PATH=/home/me/REDACTED/include
或。unset C_INCLUDE_PATH
答案2
我发现,如果您没有正确的标头,perl 会附带一个本地 poll.h,它会尝试模拟 poll() 的功能;它位于 /dist/IO/poll.h(root 位于 tarball 的根目录)。由于 RHEL 5.5 有 poll.h,/Configure 检测到了它的存在,并将自身设置为使用系统 poll.h 而不是它自己的 poll.h。/dist/IO/poll.h 上的以下 diff 使其正常工作:
14c14
< # include <poll.h>
---
> # include <sys/poll.h>
我真的不知道为什么<poll.h>
即使可以也不起作用<sys/poll.h>
。我的<poll.h>
(位于 /usr/include/poll.h)如下:
#include <sys/poll.h>
答案3
我猜测你缺少 poll.h。
顺便问一下,为什么不使用 rpm 来安装 Perl?这样会更容易一些。
希望这可以帮助。