0

I have two cmake projects on Windows. PROJECT_A outputs an executable and PROJECT_B outputs a static lib. Project_B has its own cmake file and can be built on its own.

PROJECT_B is in a subfolder of PROJECT_A and PROJECT_A includes PROJECT_B using the cmake function add_subdirectory().

PROJECT_B sets an environment variable (PROJECT_B_BUILD_DIR) which contains the value of PROJECT_B's CMAKE_CURRENT_BINARY_DIR so that PROJECT_A can locate and link against the static library it generates.

When running cmake from the command line to build PROJECT_A, PROJECT_B outputs the lib to Debug or Release subdirectories inside PROJECT_B_BUILD_DIR and so PROJECT_A links against the output of PROJECT_B using the following:

set(LIBS
   debug ${PROJECT_B_BUILD_DIR}/Debug/project_b.lib
   optimized ${PROJECT_B_BUILD_DIR}/Release/project_b.lib
)
target_link_libraries(project_a ${LIBS})

However when running cmake from within CLion the Debug and Release subdirectories are not created and the libs are output directly into PROJECT_B_BUILD_DIR and so PROJECT_A fails to link against project_b because the paths passed into target_link_libraries() are now wrong.

I could resolve the issue by removing the Debug and Release portions of the paths passed into target_link_libraries() however this would break the build for anyone building the project from the command line.

What would be a good strategy around this problem?

2
  • If you PROJECT_A uses PROJECT_B via add_subdirectory command, it is better (and simpler) to link with the PROJECT_B's library using its target name: target_link_libraries(project_a project_b). When actual linking will be performed, CMake will automatically insert proper path to the project_b library. Commented Feb 23, 2019 at 15:41
  • I didn't know you could do that. Completely resolved my issue. Thanks very much! If you add this as the question answer I'll accept it :) Commented Feb 24, 2019 at 20:17

1 Answer 1

1

If you include other project with add_subdirectory command, you may link with the libraries, created in that project, using their target names:

target_link_libraries(project_a project_b)

When CMake will construct command line for the linker invocation, it will replace project_b with proper linker flags, taking into account build type and many other things, which one even doesn't know.

Sign up to request clarification or add additional context in comments.

1 Comment

Great answer. This fixed my issue as it removes the need for me to manually add the MSVC Debug and Release portions of the link target path. My cmake files are now much cleaner and more portable as a result. Thanks very much.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.