Subproject of a linked library is linked as GLOBAL when it should be LOCAL


I have a project containing a static library and a testing application. The static library has several sub projects.

add_library(NewLibrary STATIC)

When I generate an eclipse project and build it, the library builds well, but i get a linker error, when I’m trying to build the test application:

/usr/bin/ld: cannot find -lsubproject1: No such file or directory
/usr/bin/ld: cannot find -lsubproject2: No such file or directory

The problem is, that two of the subprojects are linked as global libraries while the other are linked as subprojects.

/usr/bin/c++ -g CMakeFiles/NewLibrary_Tests.dir/tests/NewLibraryTests.cpp.o -o NewLibrary_Tests libNewLibrary.a lib/libgtest_maind.a -lsubproject1 -lsubprojects2 _deps/subproject3-build/libsubproject3.a _deps/subproject4-build/libsubproject4.a _deps/subproject5-build/libsubproject5.a lib/libgtestd.a

I’ve noticed that the project names of those two subprojects where starting with lowercase letter while the other subprojects had names starting with uppercase letters. I’ve changed both of that names to all-uppercase. Strangely that did only help with the second of the subprojects. The problem remains with the first subproject.

On what basis does cmake make that decision?
How can I force cmake to link subproject1 the same way as the others?

Kind regards

I was just able to work around the problem by renaming the first subproject again. However, that is a very unsatisfying solution. I’d like to understand, what I’ve done wrong or what possibly causes that kind of problem and how I prevent similar problems in the future.

The name you give to FetchContent_Declare() is the name of the dependency. You need to look inside the dependency to see what CMake targets it defines. Those target names are independent of whatever you named the dependency in the FetchContent_Declare() call. You need to link to the target names, not to the dependency name.

Thank you very much for that explanation, Craig. Actually I didn’t notice that after all my name changes, the FetchContent_Declare names and the target_link_libraries now happen to exactly match the targets inside the dependencies. So that is it, what caused the problem. I’m glad to understand that know.

There is something, that is not part of this thread’s topic but that I observed when I was trying around with the information you gave me. Just out of curiosity I’ve renamed all the FetchContent_Declare names and kept the target_link_libraries exactly as the target names. In my case, that led to a problem because subproject4 was already depending on subproject5 and I got the following error:

  add_library cannot create target "subproject5" because another target with
  the same name already exists.  The existing target is a static library
  created in source directory

That is of course something that I could have prevented by not fetching a content that is already fetched by another subproject. However, I’ve noticed that cmake automatically avoids that error if the FetchContent_Declare names exactly match the target_link_libraries (and also the names of the targets in the fetched content - case sensitive).