gdraheim / zziplib

The ZZIPlib provides read access on ZIP-archives and unpacked data. It features an additional simplified API following the standard Posix API for file access
Other
62 stars 50 forks source link

make check fails on macOS because dylib cannot be found #34

Closed mojca closed 4 years ago

mojca commented 6 years ago

The make check command doesn't work correctly on macOS:

export LD_LIBRARY_PATH="../zzip/.libs:$LD_LIBRARY_PATH" \
    ; ./zzshowme readme >readme.out 2>readme.err ; true
/bin/sh: line 1: 16246 Trace/BPT trap          ./zzshowme readme > readme.out 2> readme.err
diff readme.out ../../zziplib/README || grep "libzzip-" readme.err
dyld: Library not loaded: /usr/lib/libzzip-0.13.dylib
gdraheim commented 6 years ago

Well, it may simply be that the library RPATH is hardcoded on mac.

On linux it is not there at all

objdump -x zzip/.libs/libzzip-0.so.13 | grep RPATH

 readelf -d zzip/.libs/libzzip-0.so.13 

Dynamic section at offset 0x6dc0 contains 27 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libz.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000e (SONAME)             Library soname: [libzzip-0.so.13]
 0x000000000000000c (INIT)               0x2388
 0x000000000000000d (FINI)               0x5068
 0x0000000000000019 (INIT_ARRAY)         0x206ce8
 0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x206cf0
 0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
 0x0000000000000004 (HASH)               0x1f0
 0x000000006ffffef5 (GNU_HASH)           0x550
 0x0000000000000005 (STRTAB)             0x12d0
 0x0000000000000006 (SYMTAB)             0x7d8
 0x000000000000000a (STRSZ)              1423 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000003 (PLTGOT)             0x207000
 0x0000000000000002 (PLTRELSZ)           1536 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x1d88
 0x0000000000000007 (RELA)               0x1980
 0x0000000000000008 (RELASZ)             1032 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x1950
 0x000000006fffffff (VERNEEDNUM)         1
 0x000000006ffffff0 (VERSYM)             0x1860
 0x000000006ffffff9 (RELACOUNT)          30
 0x0000000000000000 (NULL)               0x0
mojca commented 6 years ago

Yes, it's hardcoded (unless instructed otherwise):

$ ../zziplib/configure --prefix=/tmp/zziplib-testinst && make
...
$ otool -L test/zzshowme 
test/zzshowme:
    /tmp/zziplib-testinst/lib/libzzip-0.13.dylib (compatibility version 14.0.0, current version 14.68.0)
    /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.3)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.11)

There are other ways (@rpath-based etc.), none entirely ideal. I can think about it a bit.

gdraheim commented 6 years ago

So essentially that defeats doing a "make check" before "make install". I had known about such a problem on some old unix systems as well (aix, hpux).

Some part of "make check" is to run the zziptests.py ... that one could easily be expanded to run with the installed binaries. So one could atleast get an indicator of the state of the project.

gdraheim commented 6 years ago

So you can try now

../zziplib/configure --prefix=/tmp/zziplib-testinst && make install
cd tests && python zziptests.py --bindir=/tmp/zziplib-testinst/bin
mojca commented 6 years ago

For an insight ...

I have no clue how autotools are supposed to be handling the problem. If CMake is used correctly, this is the binary you get in the build fodler:

$ otool -L libtestlib.1.0.dylib 
libtestlib.1.0.dylib:
    @rpath/libtestlib.1.0.dylib (compatibility version 0.0.0, current version 1.0.0)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.0.0)
$ otool -L testbin 
testbin:
    @rpath/libtestlib.1.0.dylib (compatibility version 0.0.0, current version 1.0.0)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.0.0)

and this is what you get after the binary is installed:

export PREFIX=/tmp/inst
export DESTDIR=/tmp/dest
cmake -DCMAKE_INSTALL_PREFIX=$PREFIX ../src
make && make install DESTDIR=$DESTDIR

$ otool -L $DESTDIR$PREFIX/lib/libtestlib.1.0.dylib
/tmp/dest/tmp/inst/lib/libtestlib.1.0.dylib:
    /tmp/inst/lib/libtestlib.1.0.dylib (compatibility version 0.0.0, current version 1.0.0)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.0.0)

$ otool -L $DESTDIR$PREFIX/bin/testbin 
/tmp/dest/tmp/inst/bin/testbin:
    /tmp/inst/lib/libtestlib.1.0.dylib (compatibility version 0.0.0, current version 1.0.0)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.0.0)

CMake makes sure that binaries are "relinked" at make install. Link

You can adjust @rpath, but not the absolute paths. Or rather: a whole lot of things can go wrong if you do.

mojca commented 6 years ago

Bottomline: if you switch to CMake anyway, you should not bother fixing this in autotools.

gdraheim commented 6 years ago

I known that autotools (really libtool) can do relinking as well.

The sad thing is that I have decades of experiences with autotools but not with cmake. So I can not make the change myself anytime soon.

gdraheim commented 4 years ago

Latest release was tested with cmake.