Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Perplexed by Inline::C/MakeMaker LD path

by halfcountplus (Hermit)
on Mar 02, 2014 at 18:35 UTC ( [id://1076725]=perlquestion: print w/replies, xml ) Need Help??

halfcountplus has asked for the wisdom of the Perl Monks concerning the following question:

The following short C program can be compiled gcc test.c -lmpg123 and run without error:

#include <stdio.h> #include <mpg123.h> int main (void) { int check = mpg123_init(); if (check != MPG123_OK) fprintf(stderr,"fail: %s\n", mpg123_plain_strerror(check)); return 0; }

And yet, on the exact same system, the following perl program fails with undefined symbol: mpg123_init, indicating libmpg123 has not been linked:

#!/usr/bin/perl use strict; use warnings FATAL => qw(all); use Inline 'C' => Config => CLEAN_AFTER_BUILD => 0, LIBS => '-lmpg123'; use Inline 'C'; Inline->init(); test(); __DATA__ __C__ #include <mpg123.h> void test () { fprintf(stderr,"%d\n", mpg123_init()); }

If I add -L/usr/local/lib to LIBS, then everything works out.

However, ld --verbose output includes SEARCH_DIR("/usr/local/lib") -- notice, I did not need an to use -L when compiling the C version -- and for what it's worth, ldconfig also includes /usr/local/lib in the runtime path. This means Inline::C or MakeMaker is doing its own thing when looking for the libraries; if I look at the Makefile in the _Inline/build directory, the "MakeMaker const_loadlibs section", which should contain the stuff from LIBS, is empty (unless I use -L). A comment there refers to the ExtUtils::Liblist pod, where EXTRALIBS (from this same section of the Makefile) is described:

List of libraries that need to be linked with when linking a perl binary which includes this extension. Only those libraries that actually exist are included.

But no explanation for how the (non-)existence of a library is determined.

Obviously, I cannot deploy this (without requiring the source be edited on each system) if I cannot be certain that Inline::C will find libraries which are otherwise accessible by the normal rules. Any form of insight is appreciated.

Replies are listed 'Best First'.
Re: Perplexed by Inline::C/MakeMaker LD path
by syphilis (Archbishop) on Mar 02, 2014 at 22:55 UTC
    I have other Inline::C modules which access libs in the exact same /usr/local/lib directory, without specifying -L, that compile fine

    That's the puzzle - if you can work out why it's *only* libmpg123 that's posing the problem, then you've solved the puzzle.

    As AM said, turning on BUILD_NOISY is the first thing to do - and feel free to post full output here if the cause of the problem is still not apparent to you.
    Look for a warning that no library was found for -lmpg123. That would tell you that the mpg123 library was not found, and would mean that MakeMaker has removed the reference to it. Hence there would be no reference to it in the generated Makefile.

    I cannot find an explanation for how the (non-)existence of a library is determined

    The code that deals with this is in ExtUtils/Liblist/Kid.pm.
    If that code fails to locate the library, then EU::MM deems it non-existent and removes the link

    Cheers,
    Rob
      As it turns out I don't have modules which access /usr/local/lib without -L. I was presuming "whereis" would give both locations if there were multiple installs but it does not, it just reports the /usr/local one. However, there are distro versions of those libraries in /usr/lib64 (just not libmpg123). This is good, since that was kind of the most baffling part. WRT BUILD_NOISY, all it says about this is:
      Starting Build Compile Stage Starting "perl Makefile.PL" Stage Warning (mostly harmless): No library found for -lmpg123

      So I ran it through `strace -f` (the dirt is in a child, so just `strace` won't get it). Without `-L`, it stats in order /usr/local/lib64, /lib64, and then /usr/lib64. It's of course my laziness that /usr/local does not follow the convention of dividing 64 and 32 bit libs (since there aren't any of the later).

      However, I still don't see why it doesn't use the actual compile time linker path. In the end, the use of `-L /usr/local/lib` is meaningless; it would have been found anyway if `-lmpg123` was used. But it seems if the afforementioned search failed, Inline leaves the "LIBS" command out entirely of its own accord. I'm on the mailing list so I'll ask about this...

        Inline leaves the "LIBS" command out entirely of its own accord

        It's looking to me that it's just standard EU::MM behaviour - and not the responsibility of Inline. EU::MM can't find '-lmpg123' because it's not in any of the places it's looking.
        Therefore the '-lmpg123' gets wiped out.

        If your perl was configured to include /usr/local/lib in $Config{libpth}, then LIBS => '-lmpg123' should work fine (because EU::MM would then find it).

        Another option (if you're using gcc compiler) would be to set the LIBRARY_PATH environment variable to /usr/local/lib. I'm not sure if that works with older versions of EU::MM, but I *think* it works with recent ones.

        Cheers,
        Rob
Re: Perplexed by Inline::C/MakeMaker LD path
by Anonymous Monk on Mar 02, 2014 at 20:39 UTC

    Be careful not to conflate dynamic loader behavior (LD_LIBRARY_PATH, ld.so.cache, etc.) with that of the program linker (compiler final stage: -L -l flags, and so on).

    Add BUILD_NOISY => 1 to your Inline C statement to see how the compiler is invoked.

      I've straightened that out. So "ld --verbose" (which should be the compile time linker) says it includes SEARCH_DIR("/usr/local/lib").

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1076725]
Approved by davido
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2024-04-24 08:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found