有这样一种情况。自己写了一个库,需要写测试程序。类似如下结构:
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] 参数。