之前搭建了一个基本的cmake工程,仅使用了一个 CMakeLists.txt 文件来管理整个工程,实际上一个工程里可以包含多个 CMakeLists.txt 文件,这样做的目的是把引入所需文件、生成执行文件/库文件 这两个工作交由两个 CMakeLists.txt 分别实现。
【cmake学习】搭建一个简单的cmake工程(初级版)_仲夏夜之梦~的博客-CSDN博客【cmake学习】搭建一个简单的cmake工程(初级版)https://blog.csdn.net/challenglistic/article/details/130110539?spm=1001.2014.3001.5501
虽然是分多个 CMakeLists.txt 来实现,你可以认为最后cmake会把所有的 CMakeLists.txt 的内容整合到一起,所以某个 CMakeLists.txt 定义的属性或者变量依然可以在其他 CMakeLists.txt 使用。
目录
一、基本思路
二、编写 CMakeLists.txt
1、顶层 CMakeLists.txt
2、vac/CMakeLists.txt
3、vac/util/CMakeLists.txt
4、app1/CMakeLists.txt
一、基本思路
整个工程,大致可以分为三部分。与之前的工程相比,多出了几个 CMakeLists.txt 文件,每个CMakeLists.txt都有各自的作用。
第一部分是源文件,可以看做是当前工程的核心,用于生成执行文件或者库文件。
第二部分是第三方库,封装好的库文件可以直接供第一部分使用。
第三部分是工具库,将相关的函数封装成一个动态库,供第一部分使用。
二、编写 CMakeLists.txt
从上图中可以看到,出了最外层的 CMakeLists.txt,中间的一些子目录下也有 CMakeLists.txt,下面就按照图中的顺序,从外层到内层编写 CMakeLists.txt
1、顶层 CMakeLists.txt
该层的 CMakeLists.txt 主要作用是添加头文件或者库文件的搜索路径,也可以根据不同的环境设置对应的编译选项。
cmake_minimum_required(VERSION 3.0)
project(tool_test)
# 这里添加的头文件路径是全局的,即不光是app1目录下的文件可以使用,vac目录下的文件也可以使用
include_directories(${PROJECT_SOURCE_DIR}/3rd_part/include)
# 添加OpenCV库的搜索路径并引入OpenCV库
list(APPEND CMAKE_PREFIX_PATH /usr/local/opencv/build)
find_package(OpenCV REQUIRED)
if(OpenCV_FOUND)
include_directories(${OpenCV_INCLUDE_DIRS})
endif()
# 告诉cmake,app1 和 vac 目录下也有CMakeLists.txt需要编译
add_subdirectory(app1)
add_subdirectory(vac)
2、vac/CMakeLists.txt
这一层的CMakeLists.txt没有什么特别的地方,只是告诉cmake,util目录下有CMakeLists.txt需要编译。
add_subdirectory(util)
3、vac/util/CMakeLists.txt
该层的CMakeLists.txt主要负责生成动态库供第一部分的源文件使用。这里可以自己选定动态库的输出位置,不指定的话,默认按照当前工程的层级构建输出路径,即放到 build/vac/util 目录下。
# 获取到当前目录下所有的 cpp 和 h 文件
file(GLOB ALL_SOURCES *.cpp *.c)
file(GLOB ALL_INCLUDES *.hpp *.h)
set(ALL_SRCS
${ALL_SOURCES}
${ALL_INCLUDES}
)
# SHARED 表示生成动态库
add_library(mul SHARED ${ALL_SRCS})
# 将生成的动态库放到 ${PROJECT_SOURCE_DIR}/build/lib
set_target_properties(mul
PROPERTIES LIBRARY_OUTPUT_DIRECTORY
${PROJECT_SOURCE_DIR}/build/lib
)
4、app1/CMakeLists.txt
该层的CMakeLists.txt主要是为了生成二进制可执行文件,这里使用的 mul 库就是上面 vac/util/CMakeLists.txt 所生成的动态库。这里同样可以指定可执行文件的输出路径,假设输出到 build/bin目录下。
# 获取到当前目录下所有的 cpp 和 h 文件
file(GLOB ALL_SOURCES *.cpp *.c)
file(GLOB ALL_INCLUDES *.hpp *.h)
set(ALL_SRCS
${ALL_SOURCES}
${ALL_INCLUDES}
)
# 生成二进制可执行文件
add_executable(${PROJECT_NAME} ${ALL_SRCS})
# 链接库文件
target_link_libraries(${PROJECT_NAME}
mul
${OpenCV_LIBS}
)
# 指定二进制执行文件的输出路径
set_target_properties(${PROJECT_NAME}
PROPERTIES RUNTIME_OUTPUT_DIRECTORY
${PROJECT_SOURCE_DIR}/build/bin
)
最终效果如下: