[Interest] Link failure with undefined references, on Ubuntu but not macOS
Ben Haller
bhaller at mac.com
Thu Apr 30 14:37:52 CEST 2020
Hi Thiago. Thanks for this. My link dependencies do presently obey this constraint (directed acyclic graph), but I’ll add the setting you suggest to enforce that! :->
Cheers,
-B.
Benjamin C. Haller
Messer Lab
Cornell University
> On Apr 29, 2020, at 11:43 PM, Thiago Macieira <thiago.macieira at intel.com> wrote:
>
> On Wednesday, 29 April 2020 18:57:24 PDT Ben Haller via Interest wrote:
>> Aha! And I figured out that the order in which I declare the dependencies
>> in my .pro file determines the order in which those dependencies appear in
>> the link command. I fixed that, and now it builds.
>>
>> I guess this was not biting me before because I used to link these
>> internal libraries dynamically instead; perhaps the link order is not
>> important with dynamic linking?
>
> Correct, searching for symbols in dynamic libraries is different because the
> linker searches all of them. It doesn't need to solve from one to the other,
> since that was resolved when each library was itself linked.
>
> Hint: make sure you're using -Wl,--no-undefined. In your .pro file, for each
> library and plugin:
>
> QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
>
>> So when I recently changed to static
>> linking for these internal libraries, the link order suddenly mattered, and
>> my build broke. And I guess perhaps the linker on macOS doesn’t have this
>> requirement, and so the build continued to work there?
>
> I don't know how the Apple linker works.
>
> The traditional linker works sequentially to avoid a very long link time.
> After it's created the list of all outstanding undefined symbols from your
> binary's .o files, it iterates over the library list. For each one, it checks
> if the library solves some symbols and then each individual .o in the static
> library to the build. After that, it promptly forgets about the library and
> moves on to the next one. That's why libB.a can't depend on libA.a: the linker
> won't search it again.
>
> If it did, you could write:
> -lA -lB -lA
>
> Then the linker will search libA.a again for other .o that have symbols that
> libB requires.
>
> Note that this may add .o that need more symbols from libB.a that haven't been
> added to the build yet. That means your linker line would need to be:
>
> -lA -lB -lA -lB
>
> This isn't infinite because there's a finite number of .o files in each
> library. The GNU linker has a shorthand for this but I won't mention it here.
> Read the docs if needed.
>
> Conclusion: break the cycle. The library dependency graph should be one way
> (directed acyclic graph). That's why I recommended that --no-undefined for
> dynamic linking: it'll prevent you from making the cycles.
>
> --
> Thiago Macieira - thiago.macieira (AT) intel.com
> Software Architect - Intel System Software Products
>
>
>
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> https://lists.qt-project.org/listinfo/interest
More information about the Interest
mailing list