Configure/Build System Madness under *nix

来源:互联网 发布:佳能cr2软件下载 编辑:程序博客网 时间:2024/06/07 23:58

Just keep a record of someone's nice insight to build system. Read more details if interested or have time, which I doubt...


kdelibs4 @4.6.3: Undefined symbols _uncompress _compress


https://trac.macports.org/ticket/29550


by michaelld

libtool (GNU's, not Apple's), when told to link a library or executable, is looking at the requested libraries & figuring out whether or not they exist as dynamic and/or static, as well as whether or not dynamic and/or static have been requested for linking. by the user (or, port in this case). When libtool cannot find all of the required dynamic ones, and the requested static ones all exist (as in your case), it tries to build a static library only. When it can find both static and dynamic, it builds both if it has been told to do so (which is usually the case). Now, at least with the OpenEXR and ilmbase ports, the build system it trying to build as both dynamic and static, but only static dependencies exist so that's what libtool builds. I would guess that some prior dependent of KDELIBS4 took issue with /bin/f77 not responding as it expected, and decided to not build dynamic libraries -- because f77 is erroring out when checking for dynamic linking capabilities as determined by some 'configure' script. Hence why you ended up with static libraries; just a guess, of course.

When linking libraries (whether static or dynamic) there are 2 basic ways of including external dependencies: the new library can be linked such that the dependency -must- be included after it, or it can be linked such that all of the dependency is included in it. In the distant past, the latter approach was taken since most libraries were static, and having a single dependent library was much easier than having multiple dependencies. In more recent years, the trend has moved towards the former and using dynamic libraries -- ones that can be loaded a runtime and then unloaded after they are no longer necessary. This method uses less in-RAM memory (since a given library can be shared across multiple applications), and also allows for developers to recompile a given library & test it out, without having to recompile an executable that depends on it. I think in the case of OpenEXR, which relies on 'libz' for compress and uncompress, it was being linked using the former method such that to create an executable one would need to specify "-lopenexr -lz" -- the 'libz' was not implied by the "libopenexr". For static libraries, there is no way to know this chain of dependencies without having some external file, such as that provided by PKGCONFIG, to define it -- or, just to know what the dependencies are beforehand.

Now, that leads us back to why KDELIBS4 failed: Most configure scripts these days are written to use PKGCONFIG when available. PKGCONFIG files provides info on how to include headers and link with install libraries for a given project via a specifically named file -- no matter if using static or dynamic linking. The configure for OpenEXR and ilmbase are very clever, and check for PKGCONFIG first & if not available, then it does the checking manually. KDELIBS4 uses CMake, which in general -does not- use PKGCONFIG, instead relying on its internal scripts for determining how to include headers and link with installed libraries. Time and again in my dealings with CMake, I've found very poorly written scripts that barely function and are easy to break -- some are installed by CMake itself, while others are found in the local project. I think what happens with KDELIBS4 is that the CMake script only checks to see if the openexr library is available, and not whether it has dependencies that need to be met.

Combining the various parts: KDELIBS4's configure script finds the static OpenEXR library, but does not know that it is dependent on 'libz'. Because the OpenEXR static library was linked such that libz was also required, and CMake doesn't know about this dependency, during linking in KDELIBS4 only the OpenEXR static library is used & thus linking fails due to undefined symbols (those found in libz).