编译多个库和可执行文件
分别编译出动态库add与sub,可执行文件main依赖这两个库,目录结构如下:
.
├── CMakeLists.txt
└── source
├── add
│ ├── CMakeLists.txt
│ ├── add.cpp
│ └── add.h
├── sub
│ ├── CMakeLists.txt
│ ├── sub.cpp
│ └── sub.h
└── main
├── CMakeLists.txt
├── main.cpp
- 根目录cmake
cmake_minimum_required(VERSION 3.8)
project(main)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
SET(CMAKE_EXPORT_COMPILE_COMMANDS ON) #导出clangd需要的文件,用于智能提示和基于语议的补全
set(CMAKE_CXX_FLAGS "-std=c++11 -g3 -rdynamic")
set(CMAKE_CXX_FLAGS_DEBUG "-O0")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
#打印信息
message(STATUS "build type:")
message(STATUS "CXX_FLAGS = ${CMAKE_CXX_FLAGS} ")
#设置库文件输出目录
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
#递归目录获取所有h文件
include_directories(${PROJECT_SOURCE_DIR}/source/add)
include_directories(${PROJECT_SOURCE_DIR}/source/sub)
include_directories(${PROJECT_SOURCE_DIR}/source/main)
add_subdirectory(source/add)
add_subdirectory(source/sub)
add_subdirectory(source/main)
#cmake中执行shell指令
execute_process(COMMAND pwd)
- add目录cmake
#递归目录获取所有c文件
file(GLOB_RECURSE c_files *.cpp *.c)
#生成动态库
add_library(add_lib_shared SHARED ${c_files})
#将动态库名字设为add
set_target_properties(add_lib_shared PROPERTIES OUTPUT_NAME "add")
set_target_properties(add_lib_shared PROPERTIES VERSION 1.0 SOVERSION 1)
- sub目录cmake
#递归目录获取所有c文件
file(GLOB_RECURSE c_files *.cpp *.c)
#生成动态库
add_library(sub_lib_shared SHARED ${c_files})
#将动态库名字设为sub
set_target_properties(sub_lib_shared PROPERTIES OUTPUT_NAME "sub")
set_target_properties(sub_lib_shared PROPERTIES VERSION 1.0 SOVERSION 1)
- main目录cmake
#递归目录获取所有c文件
file(GLOB_RECURSE c_files *.cpp *.c)
link_directories(${PROJECT_SOURCE_DIR}/lib)
add_executable(cmakeTest ${c_files})
target_link_libraries(cmakeTest add)
target_link_libraries(cmakeTest sub)
cmake中通配符替代方法
- 通配符替代方法
file(GLOB LIBS "${BOOST_PATH}/libboost*.a")
target_link_libraries(${TARGET} PRIVATE ${LIBS})
- 执行shell命令
execute_process(COMMAND sh ./build.sh WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
递归包含文件夹
#定义函数,用于递归添加头文件
function(include_sub_directories_recursively root_dir)
if (IS_DIRECTORY ${root_dir}) # 当前路径是一个目录吗,是的话就加入到包含目录
message("include dir: " ${root_dir})
include_directories(${root_dir})
endif()
file(GLOB ALL_SUB RELATIVE ${root_dir} ${root_dir}/*) # 获得当前目录下的所有文件,加入ALL_SUB列表中
foreach(sub ${ALL_SUB})
if (IS_DIRECTORY ${root_dir}/${sub})
include_sub_directories_recursively(${root_dir}/${sub}) # 对子目录递归调用,包含
endif()
endforeach()
endfunction()
# 添加头文件
MESSAGE(STATUS "--------------------")
include_sub_directories_recursively(${PROJECT_SOURCE_DIR}/source) # 对子目录递归调用,包含
MESSAGE(STATUS "--------------------")
set(ENV{PATH} $ENV{PATH}:${root_dir}) #在上面的递归查找中,将递归出的目录添加到环境变量
find_path(TEST test.h) #在环境变量中查找文件,将其文件夹路径赋给TEST
message(STATUS "find path---${TEST}") # 打印${TEST}变量,即为test.h文件所在路径,当存在多个同名文件时,以环境变量靠前当路径为准
递归遍历文件夹
file(GLOB_RECURSE all_source_files ${codePath}/*.cpp ${codePath}/*.c ${codePath}/*.h)
判断文件夹是否存在
function(CheckAndCreateDir dir)
if (NOT EXISTS ${dir})
execute_process(COMMAND mkdir ${dir}) #如果要创建文件,将mkdir改为touch指令
message(STATUS "create dir ${dir}")
else()
message(STATUS "find dir ${dir}")
endif ()
endfunction()