21

This is my CMakeLists.txt:

ADD_SUBDIRECTORY(third)
ADD_SUBDIRECTORY(utils)
ADD_SUBDIRECTORY(rpc)

But the directory 'rpc' will be compiled before directory 'utils', actually the 'rpc' is depends on 'utils', so I will get a link error.

How can I make the 'rpc' compiling after 'utils'?

Thanks.

Vikash Pandey
  • 5,407
  • 6
  • 41
  • 42
Yun Wen
  • 336
  • 1
  • 2
  • 5

4 Answers4

10

When you use target_link_libraries() function and pass it other target name, CMake automatically sets this target as a dependency. You can also use add_dependencies() to specify dependencies manually.

Also note that order of sources compilation have nothing to do with your problem. Link errors (i guess, you are seeing "undefined reference" ones) are because you aren't linking your targets properly.

arrowd
  • 33,231
  • 8
  • 79
  • 110
  • 1
    I agree and just wanted to add the general rule that a header/include dependency most likely needs also a link dependency. And the possibility of [Cyclic Dependencies of Static Libraries](http://cmake.org/cmake/help/v3.3/command/target_link_libraries.html#cyclic-dependencies-of-static-libraries). And one hint that adding `set_property(GLOBAL PROPERTY GLOBAL_DEPENDS_DEBUG_MODE 1)` to the main `CMakeLists.txt` helped me analyzing my dependency problems. – Florian Sep 28 '15 at 09:28
6

if the 'rpc' is depends on 'utils':

utils CMAKELISTS.txt

project(utils)
add_library (utils SHARED ${PROJECT_SOURCE_LIST})

rpc CMAKELISTS.txt

project(rpc)
add_library (rpc SHARED ${PROJECT_SOURCE_LIST})
# must add this command to scan dependencies of target rpc
add_dependencies (rpc utils)
target_link_libraries (${TEST_SOURCE_FILE_NAME} libutils.so)
FreeApe
  • 103
  • 1
  • 5
  • why do you need to explicitly call add_dependencies? wouldn't target_link_libraries create it implicitly for you? – Kobi Aug 01 '22 at 15:44
2
  • I have the same question with you.
  • I have open source libs —— jthread and jrtplib. I want to build them by a main CmakeList.text so I make a folder like:
cpp
├─jrtplib
│  ├─src
│  └─CMakeFiles.txt
├─jthread
│    ├─src
│    └─CMakeFiles.txt
└─CMakeFiles.txt

and cpp/CMakeFiles.txt like:


cmake_minimum_required (VERSION 3.8)


set(JTHREAD_ENABLED 1)

# 包含子项目。

add_subdirectory ("jthread")
add_subdirectory ("jrtplib")

but build error, it build jrtplib first, I think "jr" > "jt", so build jrtplib first, and it can't find libjthread.so , so target_link_libraries error I find a solution :


cmake_minimum_required (VERSION 3.8)

# ↓↓↓↓↓↓↓↓  attention ↓↓↓↓↓↓↓↓

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})

# ↑↑↑↑↑↑↑↑  attention ↑↑↑↑↑↑↑↑

set(JTHREAD_ENABLED 1)
# copy jthread/src/*.h to C:/thirdParty/include/jthread 
set(JTHREAD_INCLUDE_DIRS "C:/thirdParty/include")
set(JTHREAD_LIBRARIES "libjthread.so")


# 包含子项目。
add_subdirectory (jthread)
add_subdirectory (jrtplib)


  • set xx_OUTPUT_DIRECTORY can set library build in main cmake_build folder, so jrtplib can find libjthread.so .
  • build success ...
0

I am assuming that the project named "third" is independent however "utils" depends upon "rpc". Try the following code for a sequential build

ADD_SUBDIRECTORY(third)
ADD_SUBDIRECTORY(utils "${CMAKE_CURRENT_BINARY_DIR}/utils_build")
ADD_SUBDIRECTORY(rpc "${CMAKE_CURRENT_BINARY_DIR}/rpc_build")

this will make a "_build" directory in your given build directory. and will copy the binaries there. For more information try

cmake --help-command ADD_SUBDIRECTORY
Umer Javaid
  • 200
  • 1
  • 7