[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