CMake默认环境变量及选择编译器和设置编译器选项
CMake内置变量与系统变量对应关系
变量名称 | CMake变量 | 系统变量 |
C编译器 | CMAKE_C_COMPILER |
CC |
C++编译器 | CMAKE_CXX_COMPILER |
CXX |
生成器 | -G "*******" | CMAKE_GENERATOR(CMAKE 3.15+才支持) |
C编译选项 | CMAKE_C_FLAGS | CFLAGS |
C++编译选项 | CMAKE_CXX_FLAGS | CXXFLAGS |
一、设置编译器的版本
在实际的项目平台中可能安装有多个版本的编译器,可以通过如下两种方式设置编译器的版本
1、直接在命令行中指定编译器
cmake .. -DCMAKE_CXX_COMPILER=/usr/local/gcc/bin/g++
2、在cmake中指定编译器
- set (CMAKE_C_COMPILER "/usr/local/gcc/bin/gcc")
- set (CMAKE_CXX_COMPILER "/usr/local/gcc/bin/g++")
注:这两条命令应该放在文件的开始位置(cmake_minimum_required命令之下,其他命令之上),否则可能无效。
解释:
CMAKE_C_COMPILER
原本是保存环境变量"CC"值的变量,而CC是编译C语言的首选编译器。
CMAKE_CXX_COMPILER
与CMAKE_C_COMPILER类似,不过这个变量对应的环境变量是CXX,是编译C++语言的编译器
生成的结果
二、设置编译参数
假设我们使用g++编译器,想添加"-std=c++11", “-Wall"和”-Werror"等参数。
2.1 使用add_compile_options命令
通过在CMakeLists.txt文件中添加add_compile_options命令可以起到添加参数的作用,如:
add_compile_options(-std=c++11 -Wall -Werror)
但是这个命令是针对所有类型编译器的,也就是说这里添加的选项会在所有的编译器中运用,比如-std=c++11是针对C++的编译器参数,也会被运用在C语言编译器中。所以在编译c代码时,就会产生如下warning
- [ 50%] Building C object libb64/CMakeFiles/b64.dir/libb64-2.1/src/cdecode.c.obj
- cc1.exe: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C
- [100%] Building C object libb64/CMakeFiles/b64.dir/libb64-1.2.1/src/cencode.c.obj
- cc1.exe: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C
- Linking C static library libb64.a
- [100%] Built target b64
虽然不一定会报错但是终究体验感不好。要消除这个warning,就不能使用add_compile_options
,而是只针对c++编译器添加这个option。
2.2 通过设置CMAKE_CXX_FLAGS来配置
CMAKE_CXX_FLAGS是针对C++编译器的参数选项,默认保存环境变量CXX_FLAGS的内容,但是如果直接修改这个参数值,那么系统会忽略原CXX_FLAGS的内容。设置方式如下:
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Werror")
这个变量只在当前文件有效,如果项目中有多个模块,多个编译文件,那么需在每一个CMakeLists.txt文件中都添加对应的命令和参数。
两种方式比较
综上,对于一些在整个项目中通用的编译选项可以使用add_compile_options命令来添加比较方便,对于各个模块中的独立选项则使用CMAKE_CXX_FLAGS变量更好。
三、CMAKE__FLAGS变量
这里用到的CMAKE_CXX_FLAGS变量是只针对C++编译器的选项,对于其他编程语言,只要替换部分就可以,在当前cmake版本(3.17.2)中支持如下语言:
CMAKE_C_FLAGS:C语言编译器选项,对应于环境变量CFLAGS
CMAKE_CXX_FLAGS:C++语言编译器选项,对应于环境变量CXXFLAGS
CMAKE_CUDA_FLAGS:CUDA语言编译器选项,对应于环境变量CUDAFLAGS
CMAKE_Fortran_FLAGS:Fortran语言编译器选项,对应于环境变量FFLAGS
四、实例
- # 判断编译器类型,如果是gcc编译器,则在编译选项中加入c++11支持
- if(CMAKE_COMPILER_IS_GNUCXX)
- add_compile_options(-std=c++11)
- message(STATUS "optional:-std=c++11")
- endif(CMAKE_COMPILER_IS_GNUCXX)
- cmake_minimum_required(VERSION 3.5)
- project(eignface_demo)
- ## The common options using by both c and cxx
- set(COMPILE_FLAGS "-O2 -march=armv7-a -mcpu=cortex-a9 -mlittle-endian -mfloat-abi=soft -mno-sched-prolog -mno-unaligned-access -fPIC -fno-exceptions \
- -fno-common -fno-inline -fno-omit-frame-pointer -fno-strict-aliasing -fno-merge-constants \
- -freg-struct-return -fno-delete-null-pointer-checks -fstack-protector-strong -pipe\
- -Wtrampolines -Wall -Wfloat-equal -Wshadow"
- )
- ## The options for the shared library
- set(LINK_FLAGS "-rdynamic -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lstdc++ -lm")
- set(OPENCV_LIB opencv_highgui opencv_objdetect opencv_core opencv_imgproc opencv_contrib)
- set(SRC_CPP EigenFace.cpp)
- set(GCC_PATH D:/code/mingw)
- if (HISI)
- set(CMAKE_C_COMPILER $(GCC_PATH)/bin/gcc.exe)
- set(CMAKE_CXX_COMPILER $(GCC_PATH)/bin/g++.exe)
- set(TOOLCHAIN_DIR "/opt/hisi-linux-nptl/arm-hisiv100-linux/target")
- set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN_DIR})
- set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
- set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
- set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
- include_directories(./hisi_opencv/include/)
- link_directories(./hisi_opencv/lib/)
- message("-- Use hisi compile demo")
- add_executable(eignface_hisi ${SRC_CPP})
- target_link_libraries(eignface_hisi ${OPENCV_LIB})
- else()
- set(CMAKE_C_COMPILER "/usr/bin/gcc")
- include_directories(./gcc_opencv/include/)
- link_directories(./gcc_opencv/lib/)
- message("-- Use gcc compile demo")
- add_executable(eignface_gcc ${SRC_CPP})
- target_link_libraries(eignface_gcc ${OPENCV_LIB})
- endif()
参考:
CMake进阶(一)设置编译选项_qinbo1234567890的博客-CSDN博客_cmake 设置编译顺序
cmake(5):选择编译器及设置编译器选项_翔底的博客-CSDN博客_cmake设置编译器
cmake:设置编译选项的讲究(add_compile_options和CMAKE_CXX_FLAGS的区别)_10km的博客-CSDN博客_cmake_cxx_flags