cmake:add_subdirectory() 注意事项

本文介绍了在CMake中遇到的`add_subdirectory`错误,当试图从非子目录引入库时,需要显式指定binary directory。通过分析错误原因和官方文档,提出了解决方案,即在调用`add_subdirectory`时添加对应的binary directory参数,以确保测试程序能正确链接到库文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有这样一种情况。自己写了一个库,需要写测试程序。类似如下结构:

hello-world/
├── CMakeLists.txt
├── main.c
├── test
│   ├── CMakeLists.txt
│   └── main.c
├── hello
│   ├── CMakeLists.txt
│   ├── hello.c
│   └── hello.h
└── world
    ├── CMakeLists.txt
    ├── world.c
    └── world.h```
hello/ 目录生成 libhello.so

world/ 目录生成 libworld.so

test/ 目录存储测试程序,测试上述两个库功能是否正常。请注意 test/ 与 hello/ 和 world/ 的目录层级关系。

我们只关注 test/CMakeLists.txt 文件。第一反应,是这么写:


```python
cmake_minimum_required(VERSION 3.5)
​
project(test C) 
​
#库目录
set(TOP_DIR ${CMAKE_CURRENT_LIST_DIR}/../)
​
add_subdirectory(${TOP_DIR}/hello)
add_subdirectory(${TOP_DIR}/world)
​
add_executable(${PROJECT_NAME} main.c)
​
target_link_libraries(${PROJECT_NAME} PRIVATE hello)
target_link_libraries(${PROJECT_NAME} PRIVATE world)
​
target_include_directories(${PROJECT_NAME} PRIVATE ${TOP_DIR}/hello)
target_include_directories(${PROJECT_NAME} PRIVATE ${TOP_DIR}/world)

结果:

-- The C compiler identification is GNU 5.3.1
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
CMake Error at CMakeLists.txt:10 (add_subdirectory):
  add_subdirectory not given a binary directory but the given source
  directory "/home/sdc/pro/hello-world/hello" is not a subdirectory of
  "/home/sdc/pro/hello-world/test".  When specifying an out-of-tree source a
  binary directory must be explicitly specified.
​
CMake Error at CMakeLists.txt:11 (add_subdirectory):
  add_subdirectory not given a binary directory but the given source
  directory "/home/sdc/pro/hello-world/world" is not a subdirectory of
  "/home/sdc/pro/hello-world/test".  When specifying an out-of-tree source a
  binary directory must be explicitly specified.-- Configuring incomplete, errors occurred!
See also "/home/sdc/pro/hello-world/test/build/CMakeFiles/CMakeOutput.log".

add_subdirectory 发生错误。

错误原因:hello/ 目录不是 test/ 的子目录。

解决方法:显式指定 binary directory。

不明白什么是 binary directory? 没关系。我们先看一下 add_subdirectory() 官方说明。

add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
binary directory 就是 add_subdirectory() 命令中的 [binary_dir] 参数。

解决方法

在使用 add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])命令时,如果 source_dir 不是当前目录(CMakeLists.txt 所在目录,例子中的 test/ 目录)的子目录,那么就需要显式指定 [binary_dir] 参数,用于存储 source_dir 相关文件。

修改CMakeLists.txt 文件中的 add_subdirectory()命令为如下方式即可:

#指定 [binary_dir] 参数
add_subdirectory(${TOP_DIR}/hello hello_binary_dir)
add_subdirectory(${TOP_DIR}/world world_binary_dir)

说明

例子中的 hello/ 和world/ 目录与 test/ 目录是平级关系。实际上,只要不是上下级关系(比如,hello/ 和 world/ 目录在其他目录下或者是 test/ 目录的上级),在使用 add_subdirectory() 时都需要指定 [binary_dir] 参数。

zta@zta:~/catkin_ws$ catkin_make clean # 可选:清理之前失败的构建 Base path: /home/zta/catkin_ws Source space: /home/zta/catkin_ws/src Build space: /home/zta/catkin_ws/build Devel space: /home/zta/catkin_ws/devel Install space: /home/zta/catkin_ws/install #### #### Running command: "cmake /home/zta/catkin_ws/src -DCATKIN_DEVEL_PREFIX=/home/zta/catkin_ws/devel -DCMAKE_INSTALL_PREFIX=/home/zta/catkin_ws/install -G Unix Makefiles" in "/home/zta/catkin_ws/build" #### CMake Deprecation Warning at CMakeLists.txt:4 (cmake_minimum_required): Compatibility with CMake < 3.5 will be removed from a future version of CMake. Update the VERSION argument <min> value or use a ...<max> suffix to tell CMake that the project does not need compatibility with older versions. -- Using CATKIN_DEVEL_PREFIX: /home/zta/catkin_ws/devel -- Using CMAKE_PREFIX_PATH: CMake Warning (dev) at /usr/share/catkin/cmake/python.cmake:7 (find_package): Policy CMP0148 is not set: The FindPythonInterp and FindPythonLibs modules are removed. Run "cmake --help-policy CMP0148" for policy details. Use the cmake_policy command to set the policy and suppress this warning. Call Stack (most recent call first): /usr/share/catkin/cmake/all.cmake:164 (include) /usr/share/catkin/cmake/catkinConfig.cmake:20 (include) CMakeLists.txt:58 (find_package) This warning is for project developers. Use -Wno-dev to suppress it. -- Using PYTHON_EXECUTABLE: /usr/bin/python3 -- Using Debian Python package layout -- Using empy: /usr/bin/empy -- Using CATKIN_ENABLE_TESTING: ON -- Call enable_testing() -- Using CATKIN_TEST_RESULTS_DIR: /home/zta/catkin_ws/build/test_results -- GTest is not available. Please install libgtest-dev to enable tests involving GTest. -- GMock is not available. Please install libgmock-dev to enable tests involving GMock. -- nosetests not found, Python tests can not be run (try installing package 'python3-nose') -- catkin 0.8.10 -- BUILD_SHARED_LIBS is on -- BUILD_SHARED_LIBS is on -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- ~~ traversing 1 packages in topological order: -- ~~ - rplidar_ros -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- +++ processing catkin package: 'rplidar_ros' -- ==> add_subdirectory(rplidar_ros) CMake Deprecation Warning at rplidar_ros/CMakeLists.txt:1 (cmake_minimum_required): Compatibility with CMake < 3.5 will be removed from a future version of CMake. Update the VERSION argument <min> value or use a ...<max> suffix to tell CMake that the project does not need compatibility with older versions. -- Could NOT find roscpp (missing: roscpp_DIR) -- Could not find the required component 'roscpp'. The following CMake error indicates that you either need to install the package with the same name or change your environment so that it can be found. CMake Error at /usr/share/catkin/cmake/catkinConfig.cmake:82 (find_package): Could not find a package configuration file provided by "roscpp" with any of the following names: roscppConfig.cmake roscpp-config.cmake Add the installation prefix of "roscpp" to CMAKE_PREFIX_PATH or set "roscpp_DIR" to a directory containing one of the above files. If "roscpp" provides a separate development package or SDK, be sure it has been installed. Call Stack (most recent call first): rplidar_ros/CMakeLists.txt:16 (find_package) -- Configuring incomplete, errors occurred! Invoking "cmake" fail出现其他报错信息
03-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值