Search code examples
clinuxstaticcross-platformautotools

How to determine if platform library is static or dynamic from autotools?


Configuration I use autotools (autoreconf -iv and ./configure) to generate correct makefiles. On my development machine (Fedora) everything works correctly. For make check I use the library libcheck and from autotools I use Libtools. On Fedora the library for check is dynamic: libcheck.so.0.0.0 or something such. It works.

The Issue When I push the commits to my repo on github and do a pull request, the result is tested on Travis CI which uses Ubuntu as a platform. Now on Ubuntu the libcheck is a static library: libcheck.a and a libcheck_pic.a.

When Travis does a make check I get the following error message:

/usr/bin/ld: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../.. /../libcheck.a(check.o): relocation R_X86_64_32 against.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC`

/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../libcheck.a: could not read symbols: Bad value

Which means I have to somehow let configure determine what library I need. I suspect I need libcheck_pic.a for Ubuntu and the regular libcheck.so for Fedora.

The question Does anyone know how to integrate this into configure.ac and test/Makefile.am using libtool? I would prefer to stay in line with autotools way of life.

I couldn't find usable information using google, but there is a lot of questions out there about what the difference is between static and dynamic (which is not what I need).

I would much appreciate if anyone could point me in the right direction, or maybe even solved this already?


Solution

  • I suspect you're right that the library you want to use on the CI system is libcheck_pic.a, for its name suggests that the routines within are compiled as position-independent code, exactly as the error message you receive suggests that you do.

    One way to approach the problem, then, would be to use libcheck_pic if it is available, and to fall back to plain libcheck otherwise. That's not too hard to configure your Autotools-based build system to do. You then record the appropriate library name in an output variable, and use that in your (auto)make files.

    Autoconf's SEARCH_LIBS macro specifically serves this kind of prioritized library search requirement, but it has the side effect, likely unwanted in this case, of modifying the LIBS variable. You can nevertheless make it work. Something like this might do it, for example:

    LIBS_save=$LIBS
    AC_SEARCH_LIBS([ck_assert], [check_pic check], [
        # Optional: add a test to verify that the chosen lib really provides PIC code.
    
        # Set LIBCHECK to the initial substring of $LIBS up to but excluding the first space.
        LIBCHECK=${LIBS%% *}
      ], [
        # or maybe make it a warning, and disable your test suite when libcheck
        # is not available.
        AC_MSG_ERROR([A PIC version of libcheck is required])
      ])
    AC_OUTPUT([LIBCHECK])
    LIBS=$LIBS_save
    

    I presume you know what to do with $(LIBCHECK) on the Make side.

    As written, that has the limitation that if there is no PIC version of libcheck available then you won't find out until make or maybe make check. That's undesirable, and you could add Autoconf code to detect that situation if it is undesirable enough.


    As an altogether different approach, you could consider building your tests statically (add -static to the appropriate *_LDFLAGS variable). Of course, this has the opposite problem: if a static version of the library is not available, then the build or tests fail. Also, it requires building a static version of your own code if you're not doing so already, and furthermore, it is the static version that will be tested.

    For greatest flexibility, you could consider combining those two approaches. You might set up a fallback from one to the other, or you might set up separate targets for testing static code and PIC code, and exercise whichever of them (possibly both) is supported by the libraries available on the build system.