CMakeList.txt模板

CMakeList.txt模板

cmake_minimum_required(VERSION 2.6)
project(Test)
#设置编译选项
set(CMAKE_CXX_FLAGS "-g3 -lpthread -lmysqlclient -lrt -Wl,-rpath,lib -std=c++11")
set(CMAKE_CXX_FLAGS_DEBUG "-g3 -O0 -fsanitize=address -fno-omit-frame-pointer -fsanitize=leak")

set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
#可执行文件存放
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../bin)
#设置要忽略的编译警告
add_compile_options(-Wall -Wno-deprecated-declarations)
#链接动态库目录
link_directories(/usr/lib64/mysql)
#头文件目录
include_directories(${PROJECT_SOURCE_DIR}/../sdk/ffmpeg/include)
include_directories(${PROJECT_SOURCE_DIR}/../sdk/x264/include)

#要编译的文件
aux_source_directory(source/Task/ FILE)
aux_source_directory(source/Startup/ FILE)

#生成的执行文件名称
add_executable(Test ${FILE})

#链接的静态库,动态库也可以放到这里链接
target_link_libraries(Test 
${PROJECT_SOURCE_DIR}/../sdk/ffmpeg/lib/libavformat.a
${PROJECT_SOURCE_DIR}/../sdk/ffmpeg/lib/libavcodec.a
${PROJECT_SOURCE_DIR}/../sdk/ffmpeg/lib/libavdevice.a
${PROJECT_SOURCE_DIR}/../sdk/ffmpeg/lib/libavfilter.a
${PROJECT_SOURCE_DIR}/../sdk/ffmpeg/lib/libpostproc.a
${PROJECT_SOURCE_DIR}/../sdk/ffmpeg/lib/libswresample.a
${PROJECT_SOURCE_DIR}/../sdk/ffmpeg/lib/libswscale.a
${PROJECT_SOURCE_DIR}/../sdk/ffmpeg/lib/libavutil.a
${PROJECT_SOURCE_DIR}/../sdk/x264/lib/libx264.a)
  • Address Sanitizer默认不开启内存泄露检测,需要在执行程序前加上ASAN_OPTIONS=detect_leaks=1 ,如运行1.out程序ASAN_OPTIONS=detect_leaks=1 ./1.out

CMake编译选项

# 指定编译安装目录
cmake .. -DCMAKE_INSTALL_PREFIX=/usr 

# 指定debug或release编译
cmake .. -DCMAKE_BUILD_TYPE=Debug
cmake .. -DCMAKE_BUILD_TYPE=Release

# 编译过程中显示符号
make VERBOSE=1

交叉编译配置

# ------------------交叉编译环境配置 ----------------------
# 定义目标机所在操作系统名称
set(CMAKE_SYSTEM_NAME Linux)
# 编译工具链基准路径
set(TOOLSCHAIN_BASE "/mnt/toolchains/aarch64-linux-gcc6.3")
# 编译器路径
set(TOOLSCHAIN_PATH "${TOOLSCHAIN_BASE}/bin")
# 指定编译器
set(CMAKE_C_COMPILER "${TOOLSCHAIN_PATH}/aarch64-linux-gnu-gcc-6.3.0")
set(CMAKE_CXX_COMPILER "${TOOLSCHAIN_PATH}/aarch64-linux-gnu-g++")
# 指定系统库目录
set(CMAKE_SYSROOT "${TOOLSCHAIN_BASE}/sysroot")
# 告诉cmake是进行交叉编译
set(CMAKE_CROSSCOMPILING TRUE)
# ------------------------------------------------------

编译多个库和可执行文件

分别编译出动态库add与sub,可执行文件test依赖这两个库,目录结构如下:

.
├── CMakeLists.txt
└── source
    ├── add
    │   ├── CMakeLists.txt
    │   ├── add.cpp
    │   └── add.h
    ├── sub
    │   ├── CMakeLists.txt
    │   ├── sub.cpp
    │   └── sub.h
    └── test
        ├── CMakeLists.txt
        ├── test.cpp
        └── test.h
  • 根目录cmake
cmake_minimum_required(VERSION 3.15)
project(cmakeTest)

if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Release")
endif()

set(CMAKE_CXX_FLAGS "-std=c++11 -g3 -O2")
set(CMAKE_CXX_FLAGS_DEBUG "-O0")
set(CMAKE_CXX_FLAGS_RELEASE "-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/test)



add_subdirectory(source/add)
add_subdirectory(source/sub)
add_subdirectory(source/test)

#cmake中执行shell指令
execute_process(COMMAND pwd)

#代码格式化
file(GLOB_RECURSE all_source_files  source/*.cpp source/*.c source/*.h)
execute_process(COMMAND /Users/Shared/astyle -A4 -s4 -w -Y -f -p -H -j -c -k1 -z2 -n ${all_source_files})
  • 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)
  • test目录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})
  • 打印消息
message(STATUS "sh ./build.sh")
  • 执行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()

你可能感兴趣的:(C++)