cmakeCMakeList添加库|添加头文件|添加路径|add_executableadd_librarytarget_link_libraries|添加编译选项|宏开关
Posted bandaoyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cmakeCMakeList添加库|添加头文件|添加路径|add_executableadd_librarytarget_link_libraries|添加编译选项|宏开关相关的知识,希望对你有一定的参考价值。
目录
add_library(生成库),target_link_libraries(生成目标连接的库),set_target_properties
Cmake设置优化等级| cmake 生成 debug和 release 版
@bandaoyu:本文持续更新,本文链接:https://blog.csdn.net/bandaoyu/article/details/115165199
官网查阅
Search — CMake 3.22.0-rc1 Documentation
https://cmake.org/cmake/help/v3.23/manual/cmake-commands.7.html
CMake Cookbook:https://www.bookstack.cn/read/CMake-Cookbook/content-preface-preface-chinese.md
开胃菜例子
生成一个可执行程序的 CMakeList
#添加包含文件的的目录
include_directories($cppzmq_INCLUDE_DIR)
#用$SOURCE_FILES指定的文件,生成可执行文件sample_project
add_executable(sample_project $SOURCE_FILES)
#生成可执行文件sample_project 需要连接 $CMAKE_THREAD_LIBS_INIT指定的库
target_link_libraries (sample_project $CMAKE_THREAD_LIBS_INIT)
生成一个.so动态库的 CMakeList
#用$SRC_LISTS指定的所有的源文件生成一个库,名字叫libsugan
add_library(libsugan $SRC_LISTS)
#生成libsugan库需要链接 $OpenCV_LIBS、 $PROJECT_SOURCE_DIR/lib/libCommonUtilities.so、$PROJECT_SOURCE_DIR/lib/libInuStreams.so
target_link_libraries(libsugan
$OpenCV_LIBS
$PROJECT_SOURCE_DIR/lib/libCommonUtilities.so
$PROJECT_SOURCE_DIR/lib/libInuStreams.so
)
原文链接:https://blog.csdn.net/bandaoyu/article/details/115165199
grep -nR "common" ./ --include=*.txt|grep -vE "src_bak|boost|erasure-code|doc|link.txt"
CMakeLists生成和添加依赖库
1、目录结构
│ CMakeLists.txt │ index.txt │ ├─build ├─include │ hello.h │ hi.h │ └─src hello.cxx hi.cxx
2、CMakeLists.txt
cmake_minimum_required(VERSION 3.1) #项目名 project(libhello) # 1、指定库的目录变量 set(libhello_src src/hello.cxx) # 指定头文件搜索路径 include_directories("$PROJECT_SOURCE_DIR/include") # 2、添加库(对应的两个项目) add_library( hello_shared SHARED $libhello_src) add_library( hello_static STATIC $libhello_src) # 按照一般的习惯,静态库名字跟动态库名字应该是一致的,只是扩展名不同; # 即:静态库名为 libhello.a; 动态库名为libhello.so ; # 所以,希望 "hello_static" 在输出时,不是"hello_static",而是以"hello"的名字显示,故设置如下 # SET_TARGET_PROPERTIES (hello_static PROPERTIES OUTPUT_NAME "hello") # 3、cmake在构建一个新的target时,会尝试清理掉其他使用这个名字的库, # 因此,在构建libhello.a时,就会清理掉libhello.so. # 为了回避这个问题,比如再次使用SET_TARGET_PROPERTIES定义 CLEAN_DIRECT_OUTPUT属性。 SET_TARGET_PROPERTIES (hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1) SET_TARGET_PROPERTIES (hello_shared PROPERTIES CLEAN_DIRECT_OUTPUT 1) # 4、按照规则,动态库是应该包含一个版本号的, # VERSION指代动态库版本,SOVERSION指代API版本。 SET_TARGET_PROPERTIES (hello_static PROPERTIES VERSION 1.1 SOVERSION 1) SET_TARGET_PROPERTIES (hello_shared PROPERTIES VERSION 1.1 SOVERSION 1) # 5、若将libhello.a, libhello.so.x以及hello.h安装到系统目录,才能真正让其他人开发使用, # 本例中,将hello的共享库安装到<prefix>/lib目录; # 将hello.h安装<prefix>/include/hello目录。 #INSTALL (TARGETS hello hello_shared LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) #INSTALL (TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) #INSTALL (FILES hello.h DESTINATION include/hello)
3、configure and generate
xxx/to/path cd build cmake ..
4、截图:
mac没有电了, 来个Windows10的截图吧:
5、其他设置
若需要指定输出路径,尝试下面的示例指令:
# 设置VS会自动新建Debug和Release文件夹 set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY $CMAKE_BINARY_DIR/Lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY $CMAKE_BINARY_DIR/Lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $CMAKE_BINARY_DIR/Bin) # 设置分别设置Debug和Release输出目录 set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG $CMAKE_BINARY_DIR/Lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG $CMAKE_BINARY_DIR/Lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG $CMAKE_CURRENT_SOURCE_DIR/../../build/Debug) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE $CMAKE_BINARY_DIR/Lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE $CMAKE_BINARY_DIR/Lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE $CMAKE_CURRENT_SOURCE_DIR/Bin)
简单例子:
一、生成.so共享库文件
下面是我的几个文件:
1hello.cpp
//hello.cpp
int Calculate_sum_Of_Two_Number(int x,int y)
int z=0;
z=x+y;
return (z);
2hello.hpp
//hello.hpp
#ifndef __HELLO_H
#define __HELLO_H
int Calculate_sum_Of_Two_Number(int x,int y);
#endif
3 main.cpp
//main.cpp
#include "hello.hpp"
#include <stdio.h>
int main(void)
int a=0,b=0,c=0;
printf("please input two parameter:");
scanf("%d",&a);
scanf("%d",&b);
c=Calculate_sum_Of_Two_Number(a,b);
printf("the sum is : %d",c);
return 0;
4 CMakeLists.txt
#要求的Cmake最低版本
CMAKE_MINIMUM_REQUIRED( VERSION 2.8)
#工程名称
PROJECT(main)
#设置编译器编译模式:
set( CMAKE_BUILD_TYPE "Debug" )
#生成共享库
#get the shared package
#here needs no .hpp
add_library(calculate_shared SHARED hello.cpp)
#生成可以执行的文件
add_executable(main main.cpp)
#连接共享库
target_link_libraries(main calculate_shared)
上面CmakeLists.txt里面, 共享库的名称是calculate_shared,这个是我们可以自己更改的。生成的可执行文件是main, 这个名称也是可以更改的。
不过需要注意的是,hello.cpp里面不用在包含hello.hpp 了。(汗,因为这个导致出错,提示说是重复定义函数了);
编译生成:
mkdir build
cd build
cmake ..
make
我们就可以看到build生成了 如下的文件:
CMakeCache.txt cmake_install.cmake main
CMakeFiles libcalculate_shared.so Makefile
libcalculate_shared.so就是生成的共享库文件。
他们的路径是:/home/fan/dev/cmake/4-exer/
下面有build文件夹,以及main.cpp, hello.cpp, hello.hpp,
build文件夹下面有共享库 libcalculate_shared.so.so
二、调用共享库文件
所有的外部依赖库都是这样的,比如opencv ,openni, eigen等等,原理是一样的,只不过他们已经安装在系统里面了,可以查找,而这个则是需要我们自己去配置。
即我上面生成的共享库文件本质上和opencv的库是相同的。只不过这个共享库需要自己手动配置。
比如我又新建了一个工程,需要调用上面的共享库 libcalculate_shared.so。
main.cpp如下:
//main.cpp
#include <stdio.h>
#include <iostream>
#include "hello.hpp"
using namespace std;
int main(void)
int x=2,y=3;
int z=0;
z=Calculate_sum_Of_Two_Number(x,y);
cout<<"the result is:"<<z<<endl;
return 0;
那么在CMakeLists.txt里面,我需要告诉CMake, 这个头文件可以在哪里找到,头文件所定义的函数又可以在哪里找到。
上面hello.hpp的路径是:/home/fan/dev/cmake/4-exer/hello.hpp
libcalculate_shared.so的路径是/home/fan/dev/cmake/4-exer/build/libcalculate_shared.so
则CMakeLists.txt如下:
CMAKE_MINIMUM_REQUIRED( VERSION 2.8)
PROJECT(main)
#设置编译器编译模式:
SET( CMAKE_BUILD_TYPE "Debug" )
SET(HELLO_INCLUE
/home/fan/dev/cmake/4-exer/)
SET(HELLO_SO
/home/fan/dev/cmake/4-exer/build/libcalculate_shared.so)
INCLUDE_DIRECTORIES($HELLO_INCLUE)
add_executable(main main.cpp)
target_link_libraries(main $HELLO_SO)
这里要注意一些细节(对于我这个渣渣来说的)
1、$ 这种形式代表一个变量,比如上面的,HELLO_INCLUE ,就是我自己定义的一个变量。
2、头文件包含到头文件所在的文件夹,即 /home/fan/dev/cmake/4-exer/
3、共享库要指明具体的共享库 ,精确到.so
其实主要的就是指明这个调用这个共享库的时候,使用的头文件,以及共享库本身所在的位置,然后包含链接就可以了。
安装过的共享库(例如opencv)就不用这么麻烦了,因为它的地址都放在了变量里面。
Opencv的依赖添加
比如Opencv, 它的头文件和.so文件都已经放在了系统变量里面,不用向上面自己定义了(上面例子里面的头文件和共享库文件的地址都是我自己设置的)
它的CMakeLists.txt如下:
find_package(OpenCV REQUIRED)
include_directories($OPENCV_INCLUDE_DIRS)
target_link_libraries(MAIN $OpenCV_LIBS)
只需要查找就可以了,OpenCV_LIBS 和 OPENCV_INCLUDE_DIRS 都是系统帮我们已经定义好的,所以比较容易
参考博客:
1、如何写自己的CmakeLists.txt https://www.cnblogs.com/chaofn/p/10160555.html
2、 【OpenCV】使用CMake链接自己路径下面的OpenCV库 https://blog.csdn.net/twt520ly/article/details/81981473
原文链接:https://blog.csdn.net/qq_37761077/article/details/88750711
add_library(生成库),target_link_libraries(生成目标连接的库),set_target_properties
生成静态库:
add_library(libsugan $SRC_LISTS) #用$SRC_LISTS生成静态库libsugan
或
ADD_LIBRARY(static_lib STATIC $DIR_SUB_SRCS)
生成动态库(加SHARED ):
add_library(libsugan SHARED $SRC_LISTS) #用$SRC_LISTS生成动态库libsugan
target_link_libraries(libsugan #生成静态库libsugan还需链接依赖库$OpenCV_LIBS…
$OpenCV_LIBS
$PROJECT_SOURCE_DIR/lib/libCommonUtilities.so
$PROJECT_SOURCE_DIR/lib/libInuStreams.so
)
#上面的配置生成名字为libsugan的静态库,但Linux下对库的存储格式是lib+name.a,所以库libsugan存储出来的结果就是liblibsugan.a,看着很别扭。用下面这句,保证了存储出来的静态库叫做libsugan.a:
set_target_properties(libsugan PROPERTIES OUTPUT_NAME "sugan")
#但是请千万注意,在整个CmakeLists.txt里
#如果想链接生成的这个库必须使用 “add_library(libsugan $SRC_LISTS)”指明的名字。
set_target_properties(libsugan PROPERTIES OUTPUT_NAME "sugan")
add_executable(demo ./src/main.cpp)
target_link_libraries(demo libsugan)
连接库:
target_link_libraries(demo libsugan)
target_link_libraries(app libsort.a) #生成app 链入 libsort.a静态库
TARGET_LINK_LIBRARIES(app libsort.a)
原例子:
#工程名字
project(Camera_sugan)
#编译最低cmake版本
cmake_minimum_required(VERSION 2.6)
#设置c++编译器
set( CMAKE_CXX_FLAGS "$CMAKE_CXX_FLAGS -std=c++11" )
#在整个电脑上找opencv包
find_package(OpenCV REQUIRED)
#包含头文件路径
include_directories(
./include/inudev/
./src/
)
#将所有的源文件列为一个集合,集合名字叫做SRC_LISTS
set(SRC_LISTS
./src/inuitive.cpp
./src/runCamera_Qfeeltech.cpp
)
#将集合里的所有的源文件生成一个静态库,该静态库的名字libsugan,
注意,在整个CmakeLists里都要用libsugan这个
add_library(libsugan $SRC_LISTS)
#名字来代替之前那个集合生成的库。
target_link_libraries(libsugan #链接静态库需要的依赖库
$OpenCV_LIBS
$PROJECT_SOURCE_DIR/lib/libCommonUtilities.so
$PROJECT_SOURCE_DIR/lib/libInuStreams.so
)
原文链接:https://blog.csdn.net/michaelhan3/article/details/69568362
CMAKE 添加编译选项|-g编译参数/选项
add_definitions 和add_compile_options,二者添加的编译选项是针对所有编译器的(包括c和c++编译器)。
add_definitions 和add_compile_options的区别是:
add_definitions 可用于添加任何标志,但旨在添加预处理器定义。
此命令已被替代方案取代:
使用 add_compile_definitions() 添加预处理器定义。
使用 include_directories() 添加包含目录。
使用 add_compile_options() 添加其他选项。
add_definitions — CMake 3.22.0-rc1 Documentation
添加 -g编译参数/选项
方法一:add_definitions("-g")/ add_compile_options
在文件 CMakeLists.txt添加下面一条语句
add_definitions("-g")
添加其他编译参数/选项
例如下面的代码
#判断编译器类型,如果是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)
使用add_compile_options添加-std=c++11选项,是想在编译c++代码时加上c++11支持选项。但是因为add_compile_options是针对所有类型编译器的,所以在编译c代码时,就会产生如下warning
J:\\workspace\\facecl.gcc>make b64
[ 50%] Building C object libb64/CMakeFiles/b64.dir/libb64-1.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。
方法二:set
所以如下修改代码,则警告消除。
#判断编译器类型,如果是gcc编译器,则在编译选项中加入c++11支持
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "-std=c++11 $CMAKE_CXX_FLAGS")
message(STATUS "optional:-std=c++11")
endif(CMAKE_COMPILER_IS_GNUCXX)
原文链接:https://blog.csdn.net/qinglongzhan/article/details/80743731
包含文件的的目录include_directories
include_directories($cppzmq_INCLUDE_DIR) //添加包含文件的的目录
add_definitions 可用于添加任何标志,但旨在添加预处理器定义。
此命令已被替代方案取代:
使用 add_compile_definitions() 添加预处理器定义。
使用 include_directories() 添加包含目录。
使用 add_compile_options() 添加其他选项。
优化项|优化等级
更多和详细解释:https://blog.csdn.net/bandaoyu/article/details/123700034
-O0禁止编译器进行优化。默认为此项。
-O1尝试优化编译时间和可执行文件大小。
-O2更多的优化,会尝试几乎全部的优化功能,但不会进行“空间换时间”的优化方法。
-O3在 -O2 的基础上再打开一些优化选项:-finline-functions, -funswitch-loops 和 -fgcse-after-reload 。
-Os对生成文件大小进行优化。它会打开 -O2 开的除了会那些增加文件大小的全部选项。
可以通过下面的命令查找工程中设置优化项的地方:
grep -nR "\\-O" ./ --include=*.txt
过滤掉含有 build、boost、erasure-code、doc、link.txt字样的结果
grep -nR "\\-O" ./ --include=*.txt|grep -vE "build|src_bak|boost|erasure-code|doc|link.txt"
Cmake设置优化等级| cmake 生成 debug和 release 版
cmake 设置优化等级:
【gcc】gcc优化等级 -O1 -O2 -O3 -Os -Ofast -Og_bandaoyu的博客-CSDN博客
CMake 中有一个变量 CMAKE_BUILD_TYPE ,可以的取值是 Debug 、Release、 RelWithDebInfo 和 MinSizeRel。
当这个变量值为 Debug 的时候,CMake 会使用变量 CMAKE_CXX_FLAGS_DEBUG 和 CMAKE_C_FLAGS_DEBUG 中的字符串作为编译选项生成 Makefile ,
当这个变量值为 Release 的时候,工程会使用变量 CMAKE_CXX_FLAGS_RELEASE 和 CMAKE_C_FLAGS_RELEASE 选项生成 Makefile。
提供的级别为:
Release - Adds the-O3 -DNDEBUG
flags to the compilerDebug - Adds the-g
flagMinSizeRel - Adds-Os -DNDEBUG
RelWithDebInfo - Adds-O2 -g -DNDEBUG
flags
链接:https://www.jianshu.com/p/d761232e8e90
CMakeCache.txt:89:CMAKE_ASM_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
CMakeCache.txt:92:CMAKE_ASM_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
CMakeCache.txt:95:CMAKE_ASM_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
CMakeCache.txt:123:CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
CMakeCache.txt:126:CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
CMakeCache.txt:129:CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
CMakeCache.txt:150:CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
CMakeCache.txt:153:CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
CMakeCache.txt:156:CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
cmake设置默认CMAKE_BUILD_TYPE
原文:[CMake] Set default build type in CMakeLists.txt
在CMakeLists.txt
里写入
IF (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING
"Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
ENDIF()
设置默认构建类型
CMake提供的默认构建类型是不包含用于优化的编译器标志。对于某些项目,您可能需要设置默认生成类型,以便不必记住设置它。
为此,您可以将以下内容添加到CMakeLists.txt文件顶层
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message("Setting build type to 'RelWithDebInfo' as none was specified.")
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
"MinSizeRel" "RelWithDebInfo")
endif()
作者:xingxingRealzyx
链接:https://www.jianshu.com/p/d761232e8e90
CMake设置编译参数/选项
而set命令设置CMAKE_C_FLAGS或CMAKE_CXX_FLAGS变量则是分别只针对c和c++编译器的
对c编译器的
set(CMAKE_C_FLAGS"-O3 -fopenmp -fPIC -Wno-deprecated -Wenum-compare -std=c++14")
针对c++编译器的
set(CMAKE_CXX_FLAGS "-O3 -fopenmp -fPIC -Wno-deprecated -Wenum-compare -std=c++14")
如何在cmakelists中加入-ldl编译选项
cmakelists.txt中,在增加可执行程序后增加TARGET_LINK_LIBRARIES
eg:
add_executable(xx $ALL_F $WE_F)
TARGET_LINK_LIBRARIES(dl)
TARGET_LINK_LIBRARIES(m)
set(CMAKE_C_FLAGS "-ldl")
在add_executable($PROJECT_NAME "main.cpp")后面添加
target_link_libraries($PROJECT_NAME dl)
target_link_libraries(exe1 -Wl, - -whole-archive lib1 -Wl, - no-whole-archive)
CMake指定gcc,g++版本编译
系统默认的gcc/g++在/usr/bin目录下。
我们升级安装的gcc目录在/usr/local/bin目录下,现在我们希望使用升级后的gcc。
通过百度搜索出来的结果,大多是如下操作:
在CMakeLists.txt中调用编译器之前添加:
1 2 |
|
然而经过本人亲自实践,该方法不起作用,正确的做法是:
执行cmake命令之前,在shell终端先设置如下两个变量:
1 2 |
|
然后再执行cmake等后续命令,这样就可以用指定的编译器版本了。
【已解决】CMake指定gcc,g++版本编译 | 勤奋的小青蛙
CMake 关闭警告的方法
在CMakeLists.txt中添加add_definitions(-w)
应用于单个target
if(CMAKE_COMPILER_IS_GNUCC)
target_compile_options(main PRIVATE"-Wall")
endif()
if(MSVC)
target_compile_options(main PRIVATE"/ W4")
endif()
应用于所有target
if(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_CXX_FLAGS"$ CMAKE_CXX_FLAGS -Wall")
endif()
if(MSVC)
set(CMAKE_CXX_FLAGS"$ CMAKE_CXX_FLAGS / W4")
endif()
注意:为GCC或/ WX添加-Werror以便MSVC将所有警告视为错误。这会将所有警告视为错误。这对于新项目来说可以方便地执行严格的警告。
另外, -Wall 并不意味着"所有错误";从历史意义上讲,它意味着"每个人都可以达成一致的所有错误""。从 -Wall -Wextra 开始,然后仔细阅读您的版本的GCC手册,并找到 else 编译器可以为您提供关于警告的信息。
CMake和编译器警告 - IT屋-程序员软件开发技术分享社区
关闭编译器优化
(未验证)
1)add_compile_options(-fno-elide-constructors) #关闭编译器优化
2)set(CMAKE_CXX_FLAGS "-fno-elide-constructors $CMAKE_CXX_FLAGS")
Debug和Release 方案
About table
Configurations in terms of gcc/clang compilers (CMake 3.4.1):
- Debug: -g
- Release: -O3 -DNDEBUG
- RelWithDebInfo: -O2 -g -DNDEBUG
- MinSizeRel: -Os -DNDEBUG
It means:
+---------------+--------------+--------------+----------+ | | optimization | assert works | stripped | +---------------+--------------+--------------+----------| | Debug | no | yes | no | | Release | full | no | yes | | RelWithDebInfo| good | no | no | | MinSizeRel | size | no | yes | +---------------+--------------+--------------+----------+
So I don't agree with your MinSizeRel description because in this case I think both MinSizeRel and Release are stripped.
About question
As far as I understand you want no extra flags at all (no -g, -O* or -DNDEBUG). For Makefile-like generators:
> cmake -H. -B_builds -DCMAKE_BUILD_TYPE=MyConf -DCMAKE_CXX_FLAGS_MYCONF=""
> cmake --build _builds
CMakeLists 实现动态宏开关
去掉编译优化
在CMakeList中添加:
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
set(CMAKE_CXX_FLAGS "-Wall -Wextra")
set(CMAKE_CXX_FLAGS_DEBUG "-g")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
执行的时候
cmake -DCMAKE_BUILD_TYPE=Release
也可以在上一层(调用本CMakeList.txt的)的CMakeList.txt中添加下面:
option (CMAKE_BUILD_TYPE "Use tutorial provided math implementation" ON)
表示启用CMAKE_BUILD_TYPE 宏。
option (CMAKE_BUILD_TYPE "Use tutorial provided math implementation" OFF) #表示关
参考:
c++ - Optimize in CMake by default - Stack Overflow
debugging - How to compile without optimizations -O0 using CMake - Unix & Linux Stack Exchange
例子
最近在工作中需要通过一份C代码控制逻辑走向,网上找了一下资料,发现可以通过在CMakeLists文件中动态定义宏开关,从而能够达到编译出不同逻辑流的代码。
具体步骤:
首先,我在src代码里编写了若干debug的输出:
#IFDEF DEBUG
some print command;
#ENDIF
然后,在CMakeLists文件中添加DEBUG的定义:
IF (CMAKE_BUILD_TYPE STREQUAL DEBUG)
ADD_DEFINITIONS(-DDEBUG)
ENDIF()
最后,在cmake的时候设置参数 -DCMAKE_BUILD_TYPE 为 DEBUG:
$ cmake .. -DCMAKE_BUILD_TYPE=DEBUG
$ make -j4
这样再运行可执行文件时就会打印出some print command的debug信息了。如果不想看到debug信息,只需在参数中不设置DEBUG参数,或者将DEBUG参数设置为其它值即可(以下两种方式二者选其一):
$ cmake ..
$ cmake .. -DCMAKE_BUILD_TYPE=RELEASE
到此 CMakeLists 实现动态宏开关介绍完成。
原文链接:https://blog.csdn.net/qq_19734597/article/details/104461963
CMake--List用法
CmakeLists.txt单行注释和多行注释
单行注释:使用“#”
多行注释:使用“#[[ ]]”
CMakeList 通配符
$<TARGET_OBJECTS:A>:
说明:
$<TARGET_OBJECTS:objLib>¶
New in version 3.1.
List of objects resulting from build of objLib.
构建 objLib 产生的对象列表
add_executable(test test.cc $<TARGET_OBJECTS:A>),表示使用 test.cc和构建A产生的对象 联合编译出test。
add_executable(test2 $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B> ),表示使用构建A产生的对象 和 构建B产生的对象 联合编译出test。
例子:某个工程如下
- CMakeLists.txt
- include
- a.hh
- lib
- CMakeLists.txt
- a.cc
- src
- CMakeLists.txt
- main.cc
- test
- CMakeLists.txt
- test.cc
使用 CMake 使用命令编译 test.cc
add_executable(test test.cc $<TARGET_OBJECTS:A>)
使用的A.o 的编译为
add_library(A OBJECT A.cc)
来自:https://stackoverflow.com/questions/35696103/cmake-wildcard-for-target-objects
其他未归类
add_custom_target 自定义命令
https://www.bookstack.cn/read/CMake-Cookbook/content-chapter5-5.4-chinese.md
add_custom_target(finish
COMMAND $CMAKE_COMMAND -E echo compile finish
COMMAND $CMAKE_COMMAND -E copy_directory $SOURCE_DIR/config $SOURCE_DIR/etc
COMMAND $CMAKE_COMMAND -E copy $SOURCE_DIR/log.txt $SOURCE_DIR/etc
)
定义了一个自定义命令:finish ,执行该命令就会进行以下操作:
COMMAND $CMAKE_COMMAND -E echo compile finish
COMMAND $CMAKE_COMMAND -E copy_directory $SOURCE_DIR/config $SOURCE_DIR/etc
COMMAND $CMAKE_COMMAND -E copy $SOURCE_DIR/log.txt $SOURCE_DIR/etc
单独执行命令的方式是: cmake --build <dir> [<options>] [-- <build-tool-options>]
cmake --build /home/mydir --target finish
与 add_executable(main main.cpp) 、add_library(mylib mylib.cpp) 的不同是,这两个会生成(产出)main、mylib文件。add_custom_target(comandname ……)只会执行列出的操作,不会产生comandname文件
add_dependencies
如果main 依赖a.so b.so TARGET_LINK_LIBRARIES(main a.so b.so c.so d.so)
而a.so b.so 的生成晚于main(即编译脚本的顺序把a.so b.so 安排在后面编译),则需要ADD_DEPENDENCIES(main a.so b.so) 提前为main编译a.so b.so,否则可能会报错:符号的定义找不到 (这些符号恰恰就在a.so 和 b.so中)
详情见:https://blog.csdn.net/KingOfMyHeart/article/details/112983922
Cmake条件判断指令|if 判断优先级
cmake(十六)Cmake条件判断指令:https://blog.csdn.net/wzj_110/article/details/116105719
一 基础语法
① 基本框架
② 优先级
③ 条件的类型
以上是关于cmakeCMakeList添加库|添加头文件|添加路径|add_executableadd_librarytarget_link_libraries|添加编译选项|宏开关的主要内容,如果未能解决你的问题,请参考以下文章