Redhat – Make error when compiling Perl 5.12.1 (RHEL 5.5)

perlredhat

I am trying to compile Perl 5.12.1 in my home directory on Red Hat Enterprise Linux 5.5. However, when I try to make, I eventually receive the following error:

    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

What could be causing this?

Best Answer

I just ran into this same problem and tracked down the root cause: the C_INCLUDE_PATH environment variable. Mine happened to be set as follows:

% printenv C_INCLUDE_PATH
C_INCLUDE_PATH=/home/me/REDACTED/include:

This came from a login script somewhere that was doing something like

export C_INCLUDE_PATH=$HOME/REDACTED/include:$C_INCLUDE_PATH

while setting up my environment. That looks correct at first glance; unfortunately, it seems to be the case that foo: is equivalent to foo:. in this context-- that is, the empty string in that two-item colon-separated list seems to be implicitly treated the same as .. Which effectively adds the current directory to the system include path, which makes #include <poll.h> do the same thing as #include "poll.h", which is bad.

In Perl's case, the rogue include path causes Perl's poll.h to include itself instead of /usr/include/poll.h. Since Perl's poll.h has a guard against multiple inclusion, the second include silently does nothing, and you end up with no poll.h at all, which quickly leads to the compiler error we both saw. This also explains why your patch makes the problem go away: there is no ./sys/poll.h in the build directory, so the compiler ends up finding /usr/include/sys/poll.h, which ultimately happens to be what you wanted.

My solution was to get rid of the stray colon in C_INCLUDE_PATH. In my case, I found the script that was setting it incorrectly and fixed it so that it explicitly checks for the case where the previous C_INCLUDE_PATH was empty, and not add a colon in that case. Of course, as a quick one-off fix, I could also have manually run export C_INCLUDE_PATH=/home/me/REDACTED/include or just unset C_INCLUDE_PATH before building Perl.