add_library(生成库),target_link_libraries(生成目标连接的库),set_target_properties
CMAKE添加编译选项|-g编译参数/选项
包含文件的的目录include_directories
CMake设置编译参数/选项
如何在cmakelists中加入-ldl编译选项
CMake指定gcc,g++版本编译
CMake关闭警告的方法
关闭编译器优化
Debug和Release方案
Abouttable
Aboutquestion
CMakeLists实现动态宏开关
去掉编译优化
CMake--List用法
CmakeLists.txt单行注释和多行注释
Search—CMake3.22.0-rc1Documentation
生成一个可执行程序的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
)
原文;cmake之生成动态库-mohist-博客园
│CMakeLists.txt
│index.txt
│
├─build
├─include
│hello.h
│hi.h
└─src
hello.cxx
hi.cxx
cmake_minimum_required(VERSION3.1)
#项目名
project(libhello)
#1、指定库的目录变量
set(libhello_srcsrc/hello.cxx)
#指定头文件搜索路径
include_directories("${PROJECT_SOURCE_DIR}/include")
#2、添加库(对应的两个项目)
add_library(hello_sharedSHARED${libhello_src})
add_library(hello_staticSTATIC${libhello_src})
#按照一般的习惯,静态库名字跟动态库名字应该是一致的,只是扩展名不同;
#即:静态库名为libhello.a;动态库名为libhello.so;
#所以,希望"hello_static"在输出时,不是"hello_static",而是以"hello"的名字显示,故设置如下
#SET_TARGET_PROPERTIES(hello_staticPROPERTIESOUTPUT_NAME"hello")
#3、cmake在构建一个新的target时,会尝试清理掉其他使用这个名字的库,
#因此,在构建libhello.a时,就会清理掉libhello.so.
#为了回避这个问题,比如再次使用SET_TARGET_PROPERTIES定义CLEAN_DIRECT_OUTPUT属性。
SET_TARGET_PROPERTIES(hello_staticPROPERTIESCLEAN_DIRECT_OUTPUT1)
SET_TARGET_PROPERTIES(hello_sharedPROPERTIESCLEAN_DIRECT_OUTPUT1)
#4、按照规则,动态库是应该包含一个版本号的,
#VERSION指代动态库版本,SOVERSION指代API版本。
SET_TARGET_PROPERTIES(hello_staticPROPERTIESVERSION1.1SOVERSION1)
SET_TARGET_PROPERTIES(hello_sharedPROPERTIESVERSION1.1SOVERSION1)
#5、若将libhello.a,libhello.so.x以及hello.h安装到系统目录,才能真正让其他人开发使用,
#本例中,将hello的共享库安装到
#将hello.h安装
#INSTALL(TARGETShellohello_sharedLIBRARYDESTINATIONlibARCHIVEDESTINATIONlib)
#INSTALL(TARGETShellohello_staticLIBRARYDESTINATIONlibARCHIVEDESTINATIONlib)
#INSTALL(FILEShello.hDESTINATIONinclude/hello)
xxx/to/path
cdbuild
cmake..
mac没有电了,来个Windows10的截图吧:
若需要指定输出路径,尝试下面的示例指令:
#设置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
intCalculate_sum_Of_Two_Number(intx,inty)
{
intz=0;
z=x+y;
return(z);
}
2hello.hpp
//hello.hpp
#ifndef__HELLO_H
#define__HELLO_H
intCalculate_sum_Of_Two_Number(intx,inty);
#endif
3main.cpp
//main.cpp
#include"hello.hpp"
#include
intmain(void)
inta=0,b=0,c=0;
printf("pleaseinputtwoparameter:");
scanf("%d",&a);
scanf("%d",&b);
c=Calculate_sum_Of_Two_Number(a,b);
printf("thesumis:%d",c);
return0;
4CMakeLists.txt
#要求的Cmake最低版本
CMAKE_MINIMUM_REQUIRED(VERSION2.8)
#工程名称
PROJECT(main)
#设置编译器编译模式:
set(CMAKE_BUILD_TYPE"Debug")
#生成共享库
#getthesharedpackage
#hereneedsno.hpp
add_library(calculate_sharedSHAREDhello.cpp)
#生成可以执行的文件
add_executable(mainmain.cpp)
#连接共享库
target_link_libraries(maincalculate_shared)
上面CmakeLists.txt里面,共享库的名称是calculate_shared,这个是我们可以自己更改的。生成的可执行文件是main,这个名称也是可以更改的。
不过需要注意的是,hello.cpp里面不用在包含hello.hpp了。(汗,因为这个导致出错,提示说是重复定义函数了);
编译生成:
mkdirbuild
make
我们就可以看到build生成了如下的文件:
CMakeCache.txtcmake_install.cmakemain
CMakeFileslibcalculate_shared.soMakefile
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如下:
#include
usingnamespacestd;
intx=2,y=3;
z=Calculate_sum_Of_Two_Number(x,y);
cout<<"theresultis:"< 那么在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如下: SET(CMAKE_BUILD_TYPE"Debug") SET(HELLO_INCLUE /home/fan/dev/cmake/4-exer/) SET(HELLO_SRC /home/fan/dev/cmake/4-exer/build/libcalculate_shared.so) INCLUDE_DIRECTORIES(${HELLO_INCLUE}) target_link_libraries(main${HELLO_SRC}) 这里要注意一些细节(对于我这个渣渣来说的) 1、${}这种形式代表一个变量,比如上面的,HELLO_INCLUE,就是我自己定义的一个变量。 2、头文件包含到头文件所在的文件夹,即/home/fan/dev/cmake/4-exer/ 3、共享库要指明具体的共享库,精确到.so 其实主要的就是指明这个调用这个共享库的时候,使用的头文件,以及共享库本身所在的位置,然后包含链接就可以了。 安装过的共享库(例如opencv)就不用这么麻烦了,因为它的地址都放在了变量里面。 Opencv的依赖添加 比如Opencv,它的头文件和.so文件都已经放在了系统变量里面,不用向上面自己定义了(上面例子里面的头文件和共享库文件的地址都是我自己设置的) 它的CMakeLists.txt如下: find_package(OpenCVREQUIRED) include_directories(${OPENCV_INCLUDE_DIRS}) target_link_libraries(MAIN${OpenCV_LIBS}) 只需要查找就可以了,OpenCV_LIBS和OPENCV_INCLUDE_DIRS都是系统帮我们已经定义好的,所以比较容易 参考博客: add_library(libsugan${SRC_LISTS})#用${SRC_LISTS}生成静态库libsugan target_link_libraries(libsugan#生成静态库libsugan还需链接依赖库${OpenCV_LIBS}… #上面的配置生成名字为libsugan的静态库,但Linux下对库的存储格式是lib+name.a,所以库libsugan存储出来的结果就是liblibsugan.a,看着很别扭。用下面这句,保证了存储出来的静态库叫做libsugan.a: set_target_properties(libsuganPROPERTIESOUTPUT_NAME"sugan") #但是请千万注意,在整个CmakeLists.txt里 #如果想链接生成的这个库必须使用“add_library(libsugan${SRC_LISTS})”指明的名字。 add_executable(demo./src/main.cpp) target_link_libraries(demolibsugan) 原例子: add_library,target_link_libraries,set_target_properties,target_link_libraries使用联系_michaelhan3的博客-CSDN博客 #工程名字 project(Camera_sugan) #编译最低cmake版本 cmake_minimum_required(VERSION2.6) #设置c++编译器 set(CMAKE_CXX_FLAGS"${CMAKE_CXX_FLAGS}-std=c++11") #在整个电脑上找opencv包 #包含头文件路径 include_directories( ./include/inudev/ ./src/ #将所有的源文件列为一个集合,集合名字叫做SRC_LISTS set(SRC_LISTS ./src/inuitive.cpp ./src/runCamera_Qfeeltech.cpp #将集合里的所有的源文件生成一个静态库,该静态库的名字libsugan, 注意,在整个CmakeLists里都要用libsugan这个 #名字来代替之前那个集合生成的库。 target_link_libraries(libsugan#链接静态库需要的依赖库 add_definitions和add_compile_options,二者添加的编译选项是针对所有编译器的(包括c和c++编译器)。 add_definitions和add_compile_options的区别是: add_definitions可用于添加任何标志,但旨在添加预处理器定义。 此命令已被替代方案取代: 使用add_compile_definitions()添加预处理器定义。 使用include_directories()添加包含目录。 使用add_compile_options()添加其他选项。 add_definitions—CMake3.22.0-rc1Documentation 添加-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>makeb64 [50%]BuildingCobjectlibb64/CMakeFiles/b64.dir/libb64-1.2.1/src/cdecode.c.obj cc1.exe:warning:commandlineoption‘-std=c++11’isvalidforC++/ObjC++butnotforC [100%]BuildingCobjectlibb64/CMakeFiles/b64.dir/libb64-1.2.1/src/cencode.c.obj LinkingCstaticlibrarylibb64.a [100%]Builttargetb64 虽然并不影响编译,但看着的确是不爽啊,要消除这个warning,就不能使用add_compile_options,而是只针对c++编译器添加这个option。 方法二:set 所以如下修改代码,则警告消除。 set(CMAKE_CXX_FLAGS"-std=c++11${CMAKE_CXX_FLAGS}") include_directories(${cppzmq_INCLUDE_DIR})//添加包含文件的的目录 而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.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-archivelib1-Wl,-no-whole-archive) 系统默认的gcc/g++在/usr/bin目录下。 我们升级安装的gcc目录在/usr/local/bin目录下,现在我们希望使用升级后的gcc。 通过百度搜索出来的结果,大多是如下操作: 在CMakeLists.txt中调用编译器之前添加: 1 2 SET(CMAKE_C_COMPILER"/usr/local/bin/gcc") SET(CMAKE_CXX_COMPILER"/usr/local/bin/g++") 然而经过本人亲自实践,该方法不起作用,正确的做法是: 执行cmake命令之前,在shell终端先设置如下两个变量: exportCC=/usr/local/bin/gcc exportCXX=/usr/local/bin/g++ 然后再执行cmake等后续命令,这样就可以用指定的编译器版本了。 【已解决】CMake指定gcc,g++版本编译|勤奋的小青蛙 在CMakeLists.txt中添加add_definitions(-w) 应用于单个target if(CMAKE_COMPILER_IS_GNUCC) target_compile_options(mainPRIVATE"-Wall") endif() if(MSVC) target_compile_options(mainPRIVATE"/W4") 应用于所有target set(CMAKE_CXX_FLAGS"${CMAKE_CXX_FLAGS}-Wall") set(CMAKE_CXX_FLAGS"${CMAKE_CXX_FLAGS}/W4") 注意:为GCC或/WX添加-Werror以便MSVC将所有警告视为错误。这会将所有警告视为错误。这对于新项目来说可以方便地执行严格的警告。 另外,-Wall并不意味着"所有错误";从历史意义上讲,它意味着"每个人都可以达成一致的所有错误""。从-Wall-Wextra开始,然后仔细阅读您的版本的GCC手册,并找到else编译器可以为您提供关于警告的信息。 (未验证) 1)add_compile_options(-fno-elide-constructors)#关闭编译器优化 2)set(CMAKE_CXX_FLAGS"-fno-elide-constructors${CMAKE_CXX_FLAGS}") Configurationsintermsofgcc/clangcompilers(CMake3.4.1): Debug:-g Release:-O3-DNDEBUG RelWithDebInfo:-O2-g-DNDEBUG MinSizeRel:-Os-DNDEBUG Itmeans: +---------------+--------------+--------------+----------+ ||optimization|assertworks|stripped| +---------------+--------------+--------------+----------| |Debug|no|yes|no| |Release|full|no|yes| |RelWithDebInfo|good|no|no| |MinSizeRel|size|no|yes| AsfarasIunderstandyouwantnoextraflagsatall(no-g,-O*or-DNDEBUG).ForMakefile-likegenerators: >cmake-H.-B_builds-DCMAKE_BUILD_TYPE=MyConf-DCMAKE_CXX_FLAGS_MYCONF="" >cmake--build_builds 在CMakeList中添加: if(NOTCMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPERelease) 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"Usetutorialprovidedmathimplementation"ON) 表示启用CMAKE_BUILD_TYPE宏。 option(CMAKE_BUILD_TYPE"Usetutorialprovidedmathimplementation"OFF)#表示关 参考: c++-OptimizeinCMakebydefault-StackOverflow debugging-Howtocompilewithoutoptimizations-O0usingCMake-Unix&LinuxStackExchange 例子 最近在工作中需要通过一份C代码控制逻辑走向,网上找了一下资料,发现可以通过在CMakeLists文件中动态定义宏开关,从而能够达到编译出不同逻辑流的代码。 具体步骤: 首先,我在src代码里编写了若干debug的输出: #IFDEFDEBUG someprintcommand; #ENDIF 然后,在CMakeLists文件中添加DEBUG的定义: IF(CMAKE_BUILD_TYPESTREQUALDEBUG) ADD_DEFINITIONS(-DDEBUG) ENDIF() 最后,在cmake的时候设置参数-DCMAKE_BUILD_TYPE为DEBUG: $cmake..-DCMAKE_BUILD_TYPE=DEBUG $make-j4 这样再运行可执行文件时就会打印出someprintcommand的debug信息了。如果不想看到debug信息,只需在参数中不设置DEBUG参数,或者将DEBUG参数设置为其它值即可(以下两种方式二者选其一): $cmake.. $cmake..-DCMAKE_BUILD_TYPE=RELEASE 到此CMakeLists实现动态宏开关介绍完成。 CMake--List用法-narjaja-博客园 单行注释:使用“#” 多行注释:使用“#[[]]” ———————————————— *博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。