I have a C++ project divided into multiple library targets and one executable target. I've been dynamically linking those libraries and am trying to switch to static linking but running into "undefined reference" errors.
One of those errors involved a class named Effect, which is in a library named shading. The library typography has a class named Type_Effect, which is derived from Effect. When processing typography the linker cannot find any symbols for the Effect class.
I verified that the libraries are being included like so:
.../shading/libshading.a .../typography/libtypography.a ...
I ran the linker with the -verbose command and part of the output for shading was:
attempt to open .../shading/libshading.a succeeded
(.../shading/libshading.a)Shader_Manager.cpp.obj
(.../shading/libshading.a)Shader.cpp.obj
(.../shading/libshading.a)Program.cpp.obj
Effect.cpp.obj was missing. I checked the shading.a file and it did include Effect.cpp and all of the related Effect symbols. Next, I added dummy code for creating an Effect object into my main executable cpp file, and sure enough the linker output now included:
([...]/shading/libshading.a)Effect.cpp.obj
Alternatively, preceeding linklibs.rsp with --whole-archive
forced the linker to load Effect.cpp.obj, but loading everything introduces other problems beyond the scope of this question.
The evidence points to some breakdown in the linker determining which object files to include. The shading library is not directly used in my main executable target, so the presence of some shader objects being loaded indicates that at least some of the dependency tracing is working.
In the ld flag documentation for --whole-archive
, it mentions how that flag
include[s] every object file in the archive in the link, rather than searching the archive for the required object files.
What is some of the logic behind that searching? What factors could make or break it?