rdfhdt / hdt-cpp

HDT C++ Library and Tools
117 stars 65 forks source link

./configure --static does not produce static binaries #278

Open donpellegrino opened 8 months ago

donpellegrino commented 8 months ago

Although configure lists --enable-static as default, the resulting tools are dynamically built. Explicitly passing --enable-static to configure does not change the behavior.

$ ldd ./rdf2hdt
        linux-vdso.so.1 (0x00007ffdcf5b1000)
        libhdt.so.0 => /home/user/opt/hdt-cpp-1.3.3/lib/libhdt.so.0 (0x00007fe107bd2000)
        libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fe10799e000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fe10797e000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe107755000)
        libserd-0.so.0 => /lib/x86_64-linux-gnu/libserd-0.so.0 (0x00007fe10773c000)
        libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fe10771e000)
        libcds.so.0 => /home/user/opt/hdt-cpp-1.3.3/lib/libcds.so.0 (0x00007fe106ce5000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe106bfe000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fe107d72000)
kamahen commented 8 months ago

I've only been able to run the stand-alone utilities via the "libtool" script that's built in the tools directory. This script seems to misbehave if I have the gcc runtime in a non-standard location (LD_LIBRARY_PATH et al).

However, I can link the .a file into another library (although it's not entirely "static": libserd-0.so.0):

$ ldd lib/x86_64-linux/hdt4pl.so 
    linux-vdso.so.1 (0x00007ffdf075d000)
    libserd-0.so.0 => /lib/x86_64-linux-gnu/libserd-0.so.0 (0x00007a90cd353000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007a90cd333000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007a90cd152000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007a90cd073000)
    /lib64/ld-linux-x86-64.so.2 (0x00007a90cd4aa000)

As far as I can tell (the build was set up by someone else), I do this by make -C hdt-cpp -j8. And I make this .so file by the following, after symlinking libcds.a and libhdt.a into my directory c ... so that they get picked before the .so files (this is rather inelegant hack):

$ ls -1 c/* | xargs file
c/hdt4pl.cpp: C source, ASCII text
c/hdt4pl.o:   ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), with debug_info, not stripped
c/libcds.a:   symbolic link to /home/peter/src/hdt/hdt-cpp/libcds/.libs/libcds.a
c/libhdt.a:   symbolic link to /home/peter/src/hdt/hdt-cpp/libhdt/.libs/libhdt.a

$ gcc -shared -o lib/x86_64-linux/hdt4pl.so c/hdt4pl.o -Lc -lhdt -lcds  -lserd-0
donpellegrino commented 8 months ago

Some additional observations:

I was using libserd-dev as distributed with Ubuntu 22.04 LTS (jammy) amd64 (https://packages.ubuntu.com/jammy/amd64/libserd-dev/filelist). It only provides the .so and not the .a. Therefore, I removed serd packages from the Ubuntu system and did a custom build of serd that I configured to generate the static library. Then, with pkg-config set to use my custom build, I was able to build hdt-cpp and get it statically linked to serd. I don't know that this should be considering as a bug in hdt-cpp, since the build couldn't statically link with a library that didn't exist. Perhaps the build tooling should have reported the failure rather than automatically falling back on the dynamic library, but I am not sure what to typical convention is for that these days.

I have not figured out the work-around for libz when that is enabled. The Ubuntu zlib1g-dev package does include both the .so and the .a (https://packages.ubuntu.com/jammy/amd64/zlib1g-dev/filelist).

Setting export LDFLAGS="-static -static-libgcc -static-libstdc++" before running make seems to help in that fewer libraries end up dynamically linked in at the end of the build.

kamahen commented 8 months ago

About libz -- I had problems statically linking with libcds.a or libhdt.a ... I was getting libcds.so and libhdt.so (confirmed with ldd); to fix this, I made a copy of libcds.a and libhdt.a in the same directory as my object file -- it seems that the linker either prefers the .so file or it uses which ever it finds first (I tried a few options, such as -static as well). So you might try putting a copy of libz.a in the same directory as your object file. (I don't know if my build has libz enabled (how would I do that?); but my .so file doesn't reference libz.so (is there a way to look at a .so file to find out what .a files were included?).

kamahen commented 8 months ago

I have this line in the Makefiles, so I assume I have libz, and libz.so doesn't appear when I use ldd on any of the executables in the .lib directories:

$ ldd libcds/.libs/* libhdt/tools/*
libcds/.libs/libcds.a:
    not a dynamic executable
libcds/.libs/libcds.la:
    not a dynamic executable
libcds/.libs/libcds.lai:
    not a dynamic executable
libcds/.libs/libcds.so:
    linux-vdso.so.1 (0x00007ffe5129a000)
    libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007c1d62a00000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007c1d63883000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007c1d62c1f000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007c1d63863000)
    /lib64/ld-linux-x86-64.so.2 (0x00007c1d6397a000)
libcds/.libs/libcds.so.0:
    linux-vdso.so.1 (0x00007ffd99303000)
    libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x0000796336a00000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x000079633784f000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x0000796336c1f000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x000079633782f000)
    /lib64/ld-linux-x86-64.so.2 (0x0000796337946000)
libcds/.libs/libcds.so.0.0.0:
    linux-vdso.so.1 (0x00007ffd5994c000)
    libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x000078fd69000000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x000078fd69321000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x000078fd68e1f000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x000078fd69e29000)
    /lib64/ld-linux-x86-64.so.2 (0x000078fd69e61000)
libhdt/tools/hdt2rdf:
    not a dynamic executable
libhdt/tools/hdt2rdf.cpp:
    not a dynamic executable
libhdt/tools/hdt2rdf.o:
    not a dynamic executable
libhdt/tools/hdtInfo:
    not a dynamic executable
libhdt/tools/hdtInfo.cpp:
    not a dynamic executable
libhdt/tools/hdtInfo.o:
    not a dynamic executable
libhdt/tools/hdtSearch:
    not a dynamic executable
libhdt/tools/hdtSearch.cpp:
    not a dynamic executable
libhdt/tools/hdtSearch.o:
    not a dynamic executable
libhdt/tools/Makefile:
    not a dynamic executable
libhdt/tools/Makefile.am:
    not a dynamic executable
libhdt/tools/Makefile.in:
    not a dynamic executable
libhdt/tools/modifyHeader:
    not a dynamic executable
libhdt/tools/modifyHeader.cpp:
    not a dynamic executable
libhdt/tools/modifyHeader.o:
    not a dynamic executable
libhdt/tools/rdf2hdt:
    not a dynamic executable
libhdt/tools/rdf2hdt.cpp:
    not a dynamic executable
libhdt/tools/rdf2hdt.o:
    not a dynamic executable
libhdt/tools/replaceHeader:
    not a dynamic executable
libhdt/tools/replaceHeader.cpp:
    not a dynamic executable
libhdt/tools/replaceHeader.o:
    not a dynamic executable
libhdt/tools/searchHeader:
    not a dynamic executable
libhdt/tools/searchHeader.cpp:
    not a dynamic executable
libhdt/tools/searchHeader.o:
    not a dynamic executable
kamahen commented 8 months ago

This is the line in the Makefiles that makes me think that libz was detected:

$ cd hdt/hdt-cpp
$ find . -type f -name Makefile -print0 | xargs -0 grep -nH HAVE_LIBZ
./libcds/tests/Makefile:469:EXTRAFLAGS =  -DHAVE_LIBZ -DHAVE_SERD
./libcds/Makefile:552:EXTRAFLAGS =  -DHAVE_LIBZ -DHAVE_SERD
./libhdt/tests/Makefile:470:EXTRAFLAGS =  -DHAVE_LIBZ -DHAVE_SERD
./libhdt/tools/Makefile:246:EXTRAFLAGS =  -DHAVE_LIBZ -DHAVE_SERD
./libhdt/Makefile:429:EXTRAFLAGS =  -DHAVE_LIBZ -DHAVE_SERD
./Makefile:247:EXTRAFLAGS =  -DHAVE_LIBZ -DHAVE_SERD