This is an archive of the discontinued LLVM Phabricator instance.

[llvm-mt] Fix link failure in unusual situations.
AbandonedPublic

Authored by simon_tatham on Oct 19 2021, 6:12 AM.

Details

Summary

Trying to build llvm-mt with libxml2 enabled, on a system where
libxml2 and zlib had to be provided as static libraries, I found that
linking llvm-mt failed, because cmake had set up the link line so that
zlib.a came before libxml2.a. But libxml2 refers to zlib, and Unix ld
semantics only search each library once, so it was too late for ld to
go back to zlib and satisfy the unresolved references from libxml2.

This is the smallest fix I could find: reorder llvm-mt's
LLVM_LINK_COMPONENTS so that WindowsManifest (which adds the libxml2
dependency) comes before Support (which adds the zlib one). That way,
they end up on the link line in the opposite order, and the link
works.

I'm not very happy with this as a means of making sure it _stays_
fixed, on the other hand! I'd prefer to write some kind of explicit
rule that says libxml2 must appear before zlib. But I don't know if
cmake has such a thing.

Diff Detail

Event Timeline

simon_tatham created this revision.Oct 19 2021, 6:12 AM
simon_tatham requested review of this revision.Oct 19 2021, 6:12 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 19 2021, 6:12 AM

I am not familiar with CMake. I think LLVM_LINK_COMPONENTS is better to be treated as an unordered collection.

Is there a way to tell that WindowsManifest has an indirect dependency on zlib? Or let WindowsManifest depend on Support

I don’t mind this workaround in itself, but…

The fact that the support library happens to use and link zlib is entirely independent from the fact that libxml2 might rely on it too (as it’s an implementation detail of libxml2 here, if I’m understanding the issue correctly)? I’m not familiar with which way the libxml2 dependency is picked up here, but if libxml2 only exists in static form, and that static library requires zlib, then the libxml2 package (pkg-config? cmake package files?) should provide zlib among its announced dependencies too. If libxml2 is installed in both static and shared form, and the static one is picked due to a used provided -static or similar, it’s harder of course.

If WindowsManifest depends on libxml2, and we at the cmake level know whether zlib is available, we could also add an explicit dependency there, just in case.

simon_tatham abandoned this revision.Oct 20 2021, 1:16 AM

In fact, it turns out that libxml2 optionally uses zlib – it's a configure-time option. And I've been able to work around this issue another way now on the platform where I had the problem, by recompiling the libxml2 static library using configure --without-zlib, which doesn't seem to have lost any of the libxml2 functionality that llvm-mt needs.

So you're clearly right that only libxml2 is capable of knowing what extra libraries libxml2 needs (since the answer isn't even always the same), so if I did still need this problem fixing then I'd have to look at the libxml2 detection stage and see what was going wrong there.

I'll abandon this, since it's definitely the wrong answer and I don't even need it as a temp workaround any more. Thanks for the responses.