怎样编写cmake list append的配置文件cmake list appendlist.txt

总结CMake的常用命令,并介绍有用的CMake资源。
CMake意为cross-platform make,可用于管理c/c++工程。CMake解析配置文件CMakeLists.txt生成Makefile,相比直接用Makefile管理工程,CMake更灵活和简单。
简单的例子
一个完整的Demo可参考。
假设当前目录的结构为
./include/common.h
./include/defines.h
./other/c.cpp
./other/d.cpp
./lib/libB.a
./lib/libBd.a
./lib/libA.so
./lib/libAd.so
./lib/libB.so
./lib/libBd.so
./lib/libC.so
./lib/libCd.so
使用下面的CMakeLists.txt文件,目标是编译当前目录和./other目录下的所有源文件,并链接./lib目录下的相应库文件到最终的可执行文件./bin/hello(或./bin/hellod)。
cmake_minimum_required(VERSION 2.8)
project(helloworld)
set(CMAKE_VERBOSE_MAKEFILE on)
set(CMAKE_CXX_COMPILER "g++")
set(CMAKE_CXX_FLAGS "-Wall")
set(CMAKE_CXX_FLAGS_DEBUG "-g3")
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
aux_source_directory(./ SRC_LIST)
aux_source_directory(./other OTHER_SRC_LIST)
list(APPEND SRC_LIST ${OTHER_SRC_LIST})
include_directories(${PROJECT_SOURCE_DIR}/include)
link_directories(${PROJECT_SOURCE_DIR}/lib)
if(${CMAKE_BUILD_TYPE} MATCHES "debug")
add_executable(hellod ${SRC_LIST})
target_link_libraries(hellod Ad Bd.a Cd.so)
add_executable(hello ${SRC_LIST})
target_link_libraries(hello A B.a C.so)
执行命令cmake -DCMAKE_BUILD_TYPE=debug .生成Makefile,make之后生成./bin/hellod(调试版本),或执行cmake .最后生成./bin/hello。
常用的CMake变量
详细内容请参考。
PROJECT_SOURCE_DIR 工程的源文件目录,通常是包含CMakeLists.txt(有Project命令的)的目录。
自定义变量
可在命令行下向CMake传递自定义变量
cmake -DMY_VAR=hello .
然后在CMakeLists.txt中使用,注意大小写。
message(${MY_VAR})
cmake默认支持多种构建类型(build type),每种构建类型都有专门的编译参数变量,详情见下表:
CMAKE_BUILD_TYPE
对应的c编译选项变量
对应的c++编译选项变量
CMAKE_C_FLAGS
CMAKE_CXX_FLAGS
CMAKE_C_FLAGS_DEBUG
CMAKE_CXX_FLAGS_DEBUG
CMAKE_C_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELEASE
RelWithDebInfo
CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_RELWITHDEBINFO
MinSizeRel
CMAKE_C_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_MINSIZEREL
在CMakeLists.txt中可以自定义编译选项变量
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
然后运行cmake的时候,传入相应的构建类型即可
cmake -DCMAKE_BUILD_TYPE=Release
详情可参考对应版本的。
检查CMake版本
cmake版本至少为2.8
cmake_minimum_required(VERSION 2.8)
定义工程名称
工程名为helloworld
project(helloworld)
查找源文件
查找当前目录下所有的源文件并保存到SRC_LIST变量里
aux_source_directory(. SRC_LIST)
查找src目录下所有以cmake开头的文件并保存到CMAKE_FILES变量里
file(GLOB CMAKE_FILES "src/cmake*")
file命令同时支持目录递归查找
file(GLOB_RECURSE CMAKE_FILES "src/cmake*")
按照官方文档的说法,不建议使用file的GLOB指令来收集工程的源文件,原文解释如下
We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.
大意就是,GLOB收集的源文件增加或删除,而CMakeLists.txt没有发生修改时,CMake不能识别这些文件。其实,当CMakeLists.txt使用aux_source_directory和file glob查找工程源文件时,如果添加或删除源文件,都需要重新运行CMake。
经常配合set命令使用的CMake变量,使用set(variable value)进行设置。
CMAKE_VERBOSE_MAKEFILE on 输出详细的编译和链接信息
CMAKE_CXX_COMPILER "g++" c++编译器
CMAKE_CXX_FLAGS "-Wall" c++编译器参数
CMAKE_CXX_FLAGS_DEBUG 除CMAKE_CXX_FLAGS外,debug版本的额外编译器参数
CMAKE_CXX_FLAGS_RELEASE 除CMAKE_CXX_FLAGS外,release版本的额外编译器参数
EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin 可执行文件的输出目录
LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib 链接库的输出目录
set命令还可以设置自定义变量,比如
set(MY_GREETINGS "hello world")
包含目录和链接目录
将./include和./abc加入包含目录列表
include_directories(
将./lib加入编译器链接阶段的搜索目录列表
link_directories(
添加生成目标
使用SRC_LIST源文件列表里的文件生成一个可执行文件hello
add_executable(hello ${SRC_LIST})
使用SRC_LIST源文件列表里的文件生成一个静态链接库libhello.a
add_library(hello STATIC ${SRC_LIST})
使用SRC_LIST源文件列表里的文件生成一个动态链接库libhello.so
add_library(hello SHARED ${SRC_LIST})
将若干库文件链接到生成的目标hello(libhello.a或libhello.so)
target_link_libraries(hello A B.a C.so)
需要注意的是,target_link_libraries里库文件的顺序符合gcc链接顺序的规则,即被依赖的库放在依赖它的库的后面,比如上面的命令里,libA.so可能依赖于libB.a和libC.so,如果顺序有错,链接时会报错。还有一点,B.a会告诉CMake优先使用静态链接库libB.a,C.so会告诉CMake优先使用动态链接库libC.so,也可直接使用库文件的相对路径或绝对路径。使用绝对路径的好处在于,当依赖的库被更新时,make的时候也会重新链接。
自定义链接选项
有时候需要自定义链接选项,比如需要单独对B.a使用--whole-archive选项,可以
target_link_libraryies(hello A -Wl,--whole-archive B.a -Wl,--no-whole-archive C.so)
自定义Makefile目标
运行下面的whatever目标make whatever,会先创建一个目录./hello,然后将当前目录的a.txt拷贝到新建的./hello目录里。
add_custom_command(
OUTPUT ./hello/a.txt
COMMAND mkdir -p ./hello
cp a.txt ./hello
DEPENDS a.txt
add_custom_target(whatever DEPENDS ./hello/a.txt)
自定义目标还可以使用add_dependencies命令加入到其他目标的依赖列表里,当执行make demo时,whatever目标会被自动调用。
add_executable(demo ${SRC_LIST})
add_dependencies(demo whatever)
其他常用命令
包含其他目录的CMakeLists.txt
include(/path/to/another/CMakeLists.txt)
if(${CMAKE_BUILD_TYPE} MATCHES "debug")
list(APPEND SRC_LIST
list(REMOVE_ITEM SRC_LIST
更多的例子
自定义Makefile目标的完整例子
下面的CMakeLists.txt添加一个自定义目标proto,该目标在编译工程前,会先调用protobuf程序编译先生成Google Protocol Buffers的消息解析器。
cmake_minimum_required(VERSION 2.6)
project(protobuf-demo)
# compile proto files
set(PROTO_IN
news.proto)
set(PROTO_SRC news.pb.cc)
set(PROTO_OUT news.pb.h news.pb.cc proto/)
add_custom_command(
OUTPUT ${PROTO_OUT}
COMMAND protoc --cpp_out . --java_out . ${PROTO_IN}
DEPENDS ${PROTO_IN}
add_custom_target(proto DEPENDS ${PROTO_OUT})
aux_source_directory(. SRC_LIST)
list(APPEND SRC_LIST
${PROTO_SRC}
set(CMAKE_CXX_COMPILER "g++")
set(CMAKE_CXX_FLAGS "-Wall")
set(CMAKE_VERBOSE_MAKEFILE on)
add_executable(demo ${SRC_LIST})
add_dependencies(demo proto)
target_link_libraries(demo protobuf)CMAKE的使用 - DoubleLi - 博客园
一、&&&&&&基本使用
安装:下载二进制包后可直接解压使用
从源码安装则执行命令:./ make install&&尝试执行bootstrap失败
使用:cmake dir_path,生成工程文件或makefile文件
二、&&&&&&概念
out-of-source&build,与in-source build相对,即将编译输出文件与源文件放到不同目录中;
三、&&&&&&基本结构
1,依赖CMakeLists.txt文件,项目主目标一个,主目录中可指定包含的子目录;
2,在项目CMakeLists.txt中使用project指定项目名称,add_subdirectory添加子目录
3,子目录CMakeLists.txt将从父目录CMakeLists.txt继承设置(TBD,待检验)
四、&&&&&&语法
1.&&&&&&&#注释
2.&&&&&&&变量:使用set命令显式定义及赋值,在非if语句中,使用${}引用,if中直接使用变量名引用;后续的set命令会清理变量原来的值;
3.&&&&&&&command (args ...)&&#命令不分大小写,参数使用空格分隔,使用双引号引起参数中空格
4.&&&&&&&set(b;c) &=& set(var a b c)&&#定义变量var并赋值为a;b;c这样一个string list
5.&&&&&&&Add_executable(${var}) &=& Add_executable(a b c)&&&#变量使用${xxx}引用
6.&&&&&&&条件语句:
if(var) #var&非empty 0 N No OFF FALSE... #非运算使用NOT
else()/elseif() & endif(var)
7.&&&&&&&循环语句
Set(VAR a b c)
Foreach(f ${VAR})&&&&&&&&Endforeach(f)
8.&&&&&&&循环语句
WHILE() & ENDWHILE()
五、&&&&&&内部变量
CMAKE_C_COMPILER:指定C编译器
CMAKE_CXX_COMPILER:
CMAKE_C_FLAGS:编译C文件时的选项,如-g;也可以通过add_definitions添加编译选项
EXECUTABLE_OUTPUT_PATH:可执行文件的存放路径
LIBRARY_OUTPUT_PATH:库文件路径
CMAKE_BUILD_TYPE::build&类型(Debug, Release, ...),CMAKE_BUILD_TYPE=Debug
BUILD_SHARED_LIBS:Switch between shared and static libraries
内置变量的使用:
&&&在CMakeLists.txt中指定,使用set
&& cmake命令中使用,如cmake -DBUILD_SHARED_LIBS=OFF
六、&&&&&&命令
project&(HELLO)&&&#指定项目名称,生成的VC项目的名称;
&&使用${HELLO_SOURCE_DIR}表示项目根目录
include_directories:指定头文件的搜索路径,相当于指定gcc的-I参数
&& include_directories (${HELLO_SOURCE_DIR}/Hello)&&#增加Hello为include目录
link_directories:动态链接库或静态链接库的搜索路径,相当于gcc的-L参数
&&&&&&&&& link_directories (${HELLO_BINARY_DIR}/Hello)&&&&&#增加Hello为link目录
add_subdirectory:包含子目录
&&&&&&&&& add_subdirectory (Hello)
add_executable:编译可执行程序,指定编译,好像也可以添加.o文件
&&&&&&&&& add_executable (helloDemo demo.cxx demo_b.cxx)&&&#将cxx编译成可执行文件&&
add_definitions:添加编译参数
&& add_definitions(-DDEBUG)将在gcc命令行添加DEBUG宏定义;
&& add_definitions( &-Wall -ansi &pedantic &g&)
target_link_libraries:添加链接库,相同于指定-l参数
&& target_link_libraries(demo Hello) #将可执行文件与Hello连接成最终文件demo
add_library:
&& add_library(Hello hello.cxx)&&#将hello.cxx编译成静态库如libHello.a
add_custom_target:
message( status|fatal_error, &message&):
set_target_properties( ... ): lots of properties... OUTPUT_NAME, VERSION, ....
link_libraries( lib1 lib2 ...): All targets link with the same set of libs
七、&&&&&&说明
1,CMAKE生成的makefile能够处理好.h文件更改时只编译需要的cpp文件;
八、&&&&&&FAQ
1)&&怎样获得一个目录下的所有源文件
&& aux_source_directory(&dir& &variable&)
&&&将dir中所有源文件(不包括头文件)保存到变量variable中,然后可以add_executable (ss7gw ${variable})这样使用。
2)&&怎样指定项目编译目标
&&&&project命令指定
3)&&怎样添加动态库和静态库
&& target_link_libraries命令添加即可
4)&&怎样在执行CMAKE时打印消息
&& message([SEND_ERROR | STATUS | FATAL_ERROR] "message to display" ...)
&&&注意大小写
5)&&怎样指定头文件与库文件路径
&& include_directories与link_directories
&&可以多次调用以设置多个路径
&& link_directories仅对其后面的targets起作用
6)&&怎样区分debug、release版本
&&建立debug/release两目录,分别在其中执行cmake -DCMAKE_BUILD_TYPE=Debug(或Release),需要编译不同版本时进入不同目录执行make即可;
Debug版会使用参数-g;Release版使用-O3 &DNDEBUG
&&&另一种设置方法&&例如DEBUG版设置编译参数DDEBUG
IF(DEBUG_mode)
&&&&add_definitions(-DDEBUG)
在执行cmake时增加参数即可,例如cmake -D DEBUG_mode=ON
7)&&怎样设置条件编译
例如debug版设置编译选项DEBUG,并且更改不应改变CMakelist.txt
&&&使用option command,eg:
option(DEBUG_mode "ON for debug or OFF for release" ON)
IF(DEBUG_mode)
&&&&add_definitions(-DDEBUG)
&&&使其生效的方法:首先cmake生成makefile,然后make edit_cache编辑编译选项;Linux下会打开一个文本框,可以更改,该完后再make生成目标文件&&emacs不支持make edit_cache;
&&&局限:这种方法不能直接设置生成的makefile,而是必须使用命令在make前设置参数;对于debug、release版本,相当于需要两个目录,分别先cmake一次,然后分别make edit_cache一次;
&&&期望的效果:在执行cmake时直接通过参数指定一个开关项,生成相应的makefile&&可以这样做,例如cmake &DDEBUGVERSION=ON
8)&&怎样添加编译宏定义
&&&使用add_definitions命令,见命令部分说明
9)&&怎样添加编译依赖项
用于确保编译目标项目前依赖项必须先构建好
&&add_dependencies
10)&&&&&&&&怎样指定目标文件目录
&&&建立一个新的目录,在该目录中执行cmake生成Makefile文件,这样编译结果会保存在该目录&&类似
&& SET_TARGET_PROPERTIES(ss7gw PROPERTIES
&&&&&&&&&&&&&&&&&&&&&&RUNTIME_OUTPUT_DIRECTORY "${BIN_DIR}")
11)&&&&&&&&很多文件夹,难道需要把每个文件夹编译成一个库文件?
&&&可以不在子目录中使用CMakeList.txt,直接在上层目录中指定子目录
12)&&&&&&&&怎样设定依赖的cmake版本
&&cmake_minimum_required(VERSION 2.6)
13)&&&&&&&&相对路径怎么指定
&& ${projectname_SOURCE_DIR}表示根源文件目录,${ projectname _BINARY_DIR}表示根二进制文件目录?
14)&&&&&&&&怎样设置编译中间文件的目录
15)&&&&&&&&怎样在IF语句中使用字串或数字比较
&&数字比较LESS、GREATER、EQUAL,字串比STRLESS、STRGREATER、STREQUAL,
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
set(AAA abc)
IF(AAA STREQUAL abc)
&&&&message(STATUS "true")&&&#应该打印true
16)&&&&&&&&更改h文件时是否只编译必须的cpp文件
17)&&&&&&&&机器上安装了VC7和VC8,CMAKE会自动搜索编译器,但是怎样指定某个版本?
18)&&&&&&&&怎样根据OS指定编译选项
&& IF( APPLE ); IF( UNIX ); IF( WIN32 )
19)&&&&&&&&能否自动执行某些编译前、后命令?
&& 可以,TBD
20)&&&&&&&&怎样打印make的输出
make VERBOSE=1
参考文献:
[1]&CMake_Tutorial.pdf
[2]&CMake使用总结,http://blog.csdn.net/keensword007/archive//2663235.aspx
[4]&安装包中文档
[5]&Andrej Cedilnik,: Cross-Platform Software Development Using CMake,October, 2003
[6] Cjacker,CMake实践.PDF怎样编写Cmake的配置文件Cmakelist.txt_百度知道
怎样编写Cmake的配置文件Cmakelist.txt
提问者采纳
一章将从软件开发者的角度来描述如何实用CMake,请阅读这一章。典型的,对与每一个项目的目录。 CMake的输入 COMMAND(args) 这里的 COMMAND 是命令行的名称,args是用空格分割的参数列表。也就是说.,如果你的目标是用CMake来管理你的生成过程.
其他类似问题
为您推荐:
cmake的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁当前访客身份:游客 [
这个人很懒,啥也没写
:cmake可以实现自动搜索cpp并自动生成的,当然这需...
今日访问:0
昨日访问:0
本周访问:2
本月访问:14
所有访问:187
编写CMakeLists.txt实践的一些笔记
发表于3个月前( 15:42)&&
阅读(40)&|&评论()
0人收藏此文章,
采用外部构建项目时候编写的CMakeLists.txt:
1、在项目文件夹下新建一个CMakeLists.txt,同时新建一个文件夹build在此文件夹中执行cmake ..即可进行项目构建;(前提是项目文件夹下源文件已经准备好)
set(TARGET_NAME rimeserver);设置项目的变量名字; PROJECT(${TARGET_NAME}); cmake_minimum_required(VERSION 2.8.12)
2、CMakeLists.txt文件中依赖库及文件的设置:
&&&& (1)include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) 包含CMakeLists.txt文件同级目录的include文件夹,相当于在VS中设置包含文件;
&&&& (2)add_executable(${TARGET_NAME} ${SOURCES});${TARGET_NAME}代表你设置的项目名称变量;
${SOURCES}代表你的源文件变量;add_executable代表项目生成一个可执行文件;
&&&& (3)add_dependencies(${TARGET_NAME} deploy);deploy代表你项目依赖的项目,保证deploy目标在其他的目标之前被构建;
&&&& (4)target_link_libraries(${TARGET_NAME}& 依赖的lib);代表项目依赖的lib文件,相当于在VS中设置连接器下面的lib依赖;
&&&& (5)set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "/SUBSYSTEM:WINDOWS")
设置项目系统属性;
更多开发者职位上
1)">1)">1" ng-class="{current:{{currentPage==page}}}" ng-repeat="page in pages"><li class='page' ng-if="(endIndex<li class='page next' ng-if="(currentPage
相关文章阅读怎样编写Cmake的配置文件Cmakelist.txt_百度知道
怎样编写Cmake的配置文件Cmakelist.txt
提问者采纳
对与每一个项目的目录。也就是说.,args是用空格分割的参数列表,如果你的目标是用CMake来管理你的生成过程。 CMake的输入 COMMAND(args) 这里的 COMMAND 是命令行的名称.,请阅读这一章。典型的这一章将从软件开发者的角度来描述如何实用CMake
来自团队:
其他类似问题
为您推荐:
cmake的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁

我要回帖

更多关于 cmakelist.txt作用 的文章

 

随机推荐