CMakeList模板(二):编译多个工程

编译多个库和可执行文件

分别编译出动态库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()

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页