cmake编译总结
项目目录结构:
--project/
--build/
build.sh
--src/
main.cpp
--test/
main.cpp
CMakeLists.txt
首先进入build目录,然后使用cmake编译的指令一般为:
#/opt/cmake-3.21.1/bin/cmake -DBUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../platforms/linux/rv1126-toolchain-mky.cmake ..
/opt/cmake-3.21.1/bin/cmake \
-DBUILD_TESTS=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DAUTHOR=hcz \
-DBOOK_TIME=$(date "+%Y-%m-%d %H:%M:%S") \
-DEMAIL=2292805202@qq.com \
-DPROJECT_VERSION=2.0.2d \
-DCMAKE_TOOLCHAIN_FILE=../platforms/linux/rk3588-toolchain.cmake \
-DCMAKE_INSTALL_PREFIX=../bin \
..
cmake --build build/ -j --target install #或者是make -j install
指定版本的cmake,后面-D接的是一些编译参数,最后的… 是CMakeLists.txt 所在路径,一般是build目录的上一层,所以是…
第一次cmake过后,生成了MakeList.txt文件,最后执行cmake --build build/ -j --target install或者make -j install 生成并安装可执行文件。
-DBUILD_TESTS #指定是否开启tese目录的测试程序的编译,删除或者在CMakeList.txt指定都行
-DCMAKE_BUILD_TYPE #可选值包括:
1、Debug:用于在没有优化的情况下,使用带有调试符号构建库或可执行文件
2、Release:用于构建的优化的库或可执行文件,不包含调试符号
3、RelWithDebInfo:由于构建较少的优化库或可执行文件,包含调试符号
4、MinSizeRel:用于不增加目标代码大小的优化方式,来构建或可执行文件
使用方法
set(CMAKE_BUILD_TYPE "Debug") # CMakeLists.txt中指定
或者
cmake .. -D CMAKE_BUILD_TYPE="Debug" # 生成时命令行指定
常用配置
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb") # 启用GDB
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall") # 启用优化(1~3)
-DAUTHOR #作者
-DBOOK_TIME #设置时间
-DEMAIL #邮件
-DPROJECT_VERSION #程序版本
-DCMAKE_TOOLCHAIN_FILE #指定交叉编译的文件,这个文件里面指定了CMAKE_SYSROOT、PKG_CONFIG_PATH、PKG_CONFIG_EXECUTABLE、CMAKE_C_COMPILER和CMAKE_CXX_COMPILER等
-DCMAKE_INSTALL_PREFIX #指定安装的目录,也可以在CMakeList.txt里面设置 CMAKE_INSTALL_PREFIX 变量
SET(CMAKE_INSTALL_PREFIX <install_path>)
设置完 install 的安装目录之后,执行 install 时可以通过 DESTINATION 直接指定安装目录之下的目录
例子:
SET(CMAKE_INSTALL_PREFIX /usr/local)
INSTALL(TARGETS test DESTINATION bin) #将 test 安装到 /usr/local/bin 目录下
这种-D设置的编译参数,可以简单理解为设置了一个宏定义或者是一个变量,可以在CMakeList.txt文件里直接使用,也可以在CMakeList.txt文件用set()设置。
其中最重要的应该是-DCMAKE_TOOLCHAIN_FILE,指定交叉编译的文件,这些文件一般长这样:
每个文件对应一种版本的交叉编译,里面设置不同的交叉编译器和环境变量
如rv1126版本的交叉编译:
MESSAGE(STATUS "Configure Cross Compiler")
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_PROCESSOR arm)
SET(SYSROOT_PATH /opt/rv1126_sdk/host/arm-buildroot-linux-gnueabihf/sysroot)
SET(CMAKE_SYSROOT "${SYSROOT_PATH}")
MESSAGE(STATUS "Using sysroot path as ${SYSROOT_PATH}")
SET(ENV{PKG_CONFIG_PATH} ${SYSROOT_PATH}/usr/lib/pkgconfig:$ENV{PKG_CONFIG_PATH})
SET(PKG_CONFIG_EXECUTABLE "/opt/rv1126_sdk/host/bin/pkg-config")
SET(CMAKE_C_COMPILER /opt/rv1126_sdk/cross-compiler/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER /opt/rv1126_sdk/cross-compiler/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++)
# set searching rules for cross-compiler
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
SET(YOUR_TARGET_OS linux)
SET(YOUR_TARGET_ARCH armv7-a)
SET(CMAKE_SKIP_BUILD_RPATH TRUE)
SET(CMAKE_SKIP_RPATH TRUE)
# set g++ param
# -fopenmp link libgomp
SET(CMAKE_CXX_FLAGS "-std=c++11 -march=armv7-a -mfloat-abi=hard -mfpu=neon-vfpv4 \
-ffunction-sections \
-fdata-sections -O2 -fstack-protector-strong -lm -ldl -lstdc++\
${CMAKE_CXX_FLAGS}")
重点是CMAKE_SYSROOT、PKG_CONFIG_PATH、PKG_CONFIG_EXECUTABLE、CMAKE_C_COMPILER 、CMAKE_CXX_COMPILER这几个变量的设置Pink
CMAKE_SYSROOT: 这个选项是用来设置目标平台根目录,会对编译和链接过程中,查找头文件和链接库造成影响。
例如:原本默认会从/usr/include目录中搜索头文件、从/usr/lib中搜索依赖库,当设置了–sysroot=dir(gcc是–sysroot,camek是CMAKE_SYSROOT) 后则会从dir/usr/include搜索头文件、从dir/usr/lib中搜索依赖库。
PKG_CONFIG_PATH :指定依赖配置文件的绝对路径,就是存放.pc配置文件的地方
PKG_CONFIG_EXECUTABLE:指定pkg-config配置程序,作用是找到.pc文件,解析其内容,然后对底层构建工具(C/C++编译器、链接器)或高层构建工具(cmake)提供具体配置项目。通常是在POSIX系统(Linux,MacOS等)使用pkg-config,解决第三方依赖项配置问题。
CMAKE_C_COMPILER :指定交叉编译的gcc编译器
CMAKE_CXX_COMPILER :指定交叉编译的g++编译器
还可以设置目标系统YOUR_TARGET_OS和目标版本YOUR_TARGET_ARCH,用来在CMakeList.txt找到对应的第三方软件库