4

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?

3 Answers 3

9

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.

4
  • This seems to be right. I hadn't even thought that an environment variable at the time that I made this question, but I found out later that all the PATH variables work as you describe, so I tested your fix out and it seems to do the trick. Thanks! Jul 25, 2011 at 22:08
  • Thanks for sharing this, it would have taken me ages to figure out... In my case, it was $CPATH, but exactly the same story otherwise. Nov 13, 2013 at 15:53
  • Holy moly! Thank you, gentlebeing, for debugging that problem and posting it. You rescued me from the morass. For Spack to install Python 3.8 (pyenv is not succeeding at it), it needs to install openssl, which needs to install perl, which failed for this very reason. That login script line is perfectly reasonable. C's handling of it is inexcusable.
    – Jerry101
    Jul 1, 2020 at 4:00
  • You saved my sanity! In my case it was also $CPATH, but the rest was the same. Thanks!!! Jan 27, 2023 at 21:26
1

I discovered that perl comes with a local poll.h that attempts to emulate the functionality of poll() if you don't have the right headers; this is located at /dist/IO/poll.h (root is located at the root of the tarball). Since RHEL 5.5 has poll.h, /Configure had detected its presence and set itself to use the system poll.h rather than its own. The following diff on /dist/IO/poll.h got it to work:

14c14
< #  include <poll.h>
---
> #  include <sys/poll.h>

I don't really know why <poll.h> doesn't work even though <sys/poll.h> does. My <poll.h> (located at /usr/include/poll.h) is as follows:

#include <sys/poll.h>
1
  • I don't understand it either, but this worked for me.
    – jmd_dk
    Dec 27, 2017 at 19:28
0

My guess is that you're missing poll.h.

Btw, why not using the rpm to install Perl? It would be easier.

Hope this helps.

1
  • I have poll.h (which just includes sys/poll.h), and I'm not root. May 26, 2010 at 0:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .