Cmake实践(Cmake Practice)第一部分
参考资料地址:https://github.com/Akagi201/learning-cmake/blob/master/docs/cmake-practice.pdf
一、初识cmake
1. Cmake特点
开放源代码
跨平台
能够管理大型项目
简化编译构建和编译过程(常用流程:cmake + make)
高效率
可扩展
每个目录编写一份CMakeLists.txt
二、初试cmake —— helloworld
1. 准备工作
mkdir -p /backup/cmake
cd /backup/cmake
mkdir t1
cd t1
在t1目录建立main.c和CMakeLists.txt文件:
复制代码
//main.c
1 #include
2 int main()
3 {
4 printf("Hello World from t1 Main!\n");
5 return 0;
6 }
复制代码
复制代码
//CMakeLists
1 PROJECT(HELLO)
2 SET(SRC_LIST main.c)
3 MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR}
4 MESSAGE(STATUS "This is SOURCE dir " ${HELLO_SOURCE_DIR})
5 ADD_EXECTUABLE(hello SRC_LIST)
复制代码
2. 开始构建
cmake . //生成Makefile、CMakeFiles、CMakeCache.txt等文件
make [VERBOSE=1] //实际构建工程,VERBOSE=1可查看make构建的详细过程
./hello //运行目标文件
3. CMakeLists.txt代码解释
(1)PROJECT指令的语法
PROJECT(projectname [CXX] [C] [Java]) //定义工程名称,并指定支持的语言(默认支持所有语言)
该指令隐式的定义了两个cmake变量:_BINARY_DIR以及_SOURCE_DIR,内部编译的情况下,两个变量相同,如上述工程中均为/backup/cmake/t1,外部编译则有所不同
同时cmake系统也自动预定义了PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR变量,他们的值分别跟HELLO_BINARY_DIR与HELLO_SOURCE_DIR一致;建议直接使用PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR变量,避免工程名称的影响
(2)SET指令的语法
SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]]) //用来显式的定义变量
如:SET(SRC_LIST main.c),如果有多个源文件:SET(SRC_LIST main.c t1.c t2.c)
(3)MESSAGE指令的语法
MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display"...) //用于向终端输出用户定义的信息
包含了三种类型:
SEND_ERROR,产生错误,生成过程被跳过
SATUS,输出前缀为—的信息。
FATAL_ERROR,立即终止所有cmake过程
(4)ADD_EXECUTABLE(hello ${SRC_LIST}) //生成名为hello的可执行文件,源文件列表由变量SRC_LIST定义,本例等同于ADD_EXECUTABLE(hello main.c)
4. 基本语法规则
(1)变量使用${var}方式取值,但是在IF控制语句中是直接使用变量名
(2)指令(参数1 参数2...) //参数使用括弧括起,参数之间使用空格或分号分开
(3)指令是大小写无关的,参数和变量是大小写相关的。建议全部使用大写指令
5. 清理工程:make clean
6. 内部构建与外部构建(in-source build, out-of-source build)
(1)内部编译不足:生成的中间临时文件与代码文件混在一起,且无法自动删除
(2)外部编译过程
清除上述t1目录中的除main.c和CMakeLists.txt之外的所有中间文件,特别是CMakeCache.txt
在t1目录中新建build目录 //也可以建在其他位置
进入build目录,运行cmake .. //..代表父目录,也可以输入工程代码文件的全路径;最终在build目录中生成编译需要的Makefile和其他中间文件
运行make //在当前目录(build)中生成hello目标文件
//外部编译优势:对原有的工程没有任何影响,所有的活动均发生在编译目录(build)
//注意:此时的HELLO_SOURCE_DIR仍然指代工程路径,即/backup/cmake/t1;而HELLO_BINARY_DIR则指代编译路径,即/backup/cmake/t1/build
三、更好的Hello World
在采用外部构建的基础上(构建目录为build子目录),修改上述Hello World使得更像一个工程,实现目标如下:
为工程添加一个子目录src,用来放置工程源代码
添加一个子目录doc,用来放置这个工程的文档hello.txt
在工程目录添加文本文件COPYRIGHT, README
在工程目录添加一个runhello.sh脚本,用来调用hello二进制
将构建后的目标文件放入构建目录的bin子目录
最终安装这些文件:将hello二进制与runhello.sh安装至/usr/bin,将doc目录的内容以及COPYRIGHT/README安装到/usr/share/doc/cmake/t2
1. 准备工作
mkdir -p /backup/cmake/t2
cd /back/cmake/t1 + cp main.c CMakeLists.txt ../t2
2. 添加子目录src
cd /back/cmake/t2
mkdir src
mv main.c src
每个目录的CMakeLists.txt如下:
// /backup/cmake/t2/CMakeLists.txt
1 PROJECT(HELLO)
2 ADD_SUBDIRECTORY(src bin) //bin目录为编译输出(包含编译中间结果)的目录
// /backup/cmake/t2/src/CMakeLists.txt
1 ADD_EXECUTABLE(hello main.c)
mkdir build + cd build
cmake .. + make //构建生成的hello目标文件位于build/bin目录中
语法解释(ADD_SUBDIRECTORY指令):
ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
用于向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制文件存放的位置,EXCLUDE_FROM_ALL用于将指定目录从编译过程中排除,如工程中的example目录可以在工程构建完成后进行单独构建;如果未指定binary_dir则编译输出(包含中间结果)目录为build/src(与源文件src目录对应)
3. 指定目标二进制的保存位置
利用SET指令重新指定最终生成的目标二进制位置(指hello或者共享库,不包含编译生成的中间文件)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) "build/bin"
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) "build/lib"
注:指令加到哪个CMakeLists.txt?添加原则:在哪里ADD_EXECUTABLE或ADD_LIBRARY,如果需要改变目标存放路径,就在哪里加入上述的定义,本例中为src子目录下的CMakeLists.txt
4. 如何安装?
(1)直接make install //将hello安装到/usr/bin目录
(2)直接make install DESTDIR=/tmp/test //安装到/tmp/test/usr/bin目录(打包时常用)
5. 修改Helloworld支持安装 (用到cmake的INSTALL指令和CMAKE_INSTALL_PREFIX变量)
(1)添加doc目录及文件
cd /backup/cmake/t2
mkdir doc
vim doc/hello.txt //填写任意内容并保存
(2)在工程目录添加runhello.sh脚本、COPYRIGHT和README
cd /backup/cmake/t2
vim runhello.sh //内容为hello
touch COPYRIGHT
touch README
(3)改写各目录下的CMakeLists.txt文件
安装COPYRIGHT和README,直接修改主工程目录CMakeLists.txt文件,加入如下指令:INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/t2)
安装runhello.sh,直接修改主工程目录CMakeLists.txt文件,加入如下指令:INSTALL(PROGRAMS runhello.sh DESTINATION bin)
安装doc中的hello.txt,有两种方式:一是通过在doc目录建立CMakeLists.txt并将doc目录通过ADD_SUBDIRECTORY加入工程来完成;另一种是直接在主工程目录通过INSTALL(DIRECTORY ...)实现——INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake/t2);其中“doc/”表明安装doc目录中的内容,而非整个目录
注:DESTINATION均使用相对路径,安装后的路径为${CMAKE_INSTALL_PREFIX}/,若采用绝对路径则CMAKE_INSTALL_PREFIX其实就无效的
6. 运行修改内容
cd build
cmake -D CMAKE_INSTALL_PREFIX=/tmp/t2/usr .. //CMAKE_INSTALL_PREFIX的默认定义是/usr/local
make
make install
进入/tmp/t2目录查看安装结果:
./usr
./usr/share
./usr/share/doc
./usr/share/doc/cmake
./usr/share/doc/cmake/t2
./usr/share/doc/cmake/t2/hello.txt
./usr/share/doc/cmake/t2/README
./usr/share/doc/cmake/t2/COPYRIGHT
./usr/bin
./usr/bin/hello
./usr/bin/runhello.sh
转发 https://www.cnblogs.com/hg-love-dfc/p/10242391.html
Cmake实践(Cmake Practice)第一部分的更多相关文章
- Cmake的介绍和使用 Cmake实践【转】
本文转载自:http://www.cppblog.com/Roger/archive/2011/11/17/160368.html Cmake的介绍和使用 Cmake实践 Cmake优点: 1. ...
- 《CMake实践》笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE
<CMake实践>笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE <CMake实践>笔记二:INSTALL/CMAKE_INSTALL_PREFIX &l ...
- 《CMake实践》笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE【转】
本文转载自:http://www.cnblogs.com/52php/p/5681745.html 前言: 开发了5,6年的时间,如果没有KDE4,也许不会有人或者Linux发行版本重视cmake,因 ...
- 《CMake实践》笔记二:INSTALL/CMAKE_INSTALL_PREFIX
<CMake实践>笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE <CMake实践>笔记二:INSTALL/CMAKE_INSTALL_PREFIX &l ...
- 《CMake实践》笔记三:构建静态库(.a) 与 动态库(.so) 及 如何使用外部共享库和头文件
<CMake实践>笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE <CMake实践>笔记二:INSTALL/CMAKE_INSTALL_PREFIX &l ...
- 《CMake实践》笔记二:INSTALL/CMAKE_INSTALL_PREFIX【转】
本文转载自:http://www.cnblogs.com/52php/p/5681751.html 四.更好一点的Hello World 没有最好,只有更好 从本小节开始,后面所有的构建我们都将采用 ...
- 《CMake实践》第三部分的示例代码的错误
<CMake实践>的第三章,初试cmake - cmake的helloworld 中的 PROJECT (HELLO) SET(SRC_LIST main.c) MESSAGE(statu ...
- CMake实践--操作
---<Cmake 实践>--- ---Ubuntu 14.04 1.创建一个cmake文件目录 mkdir -p ~/cmake 2.在cmake文件下创建t1子目录 cd ~/cmak ...
- Cmake的介绍和使用 Cmake实践
Cmake的介绍和使用 Cmake实践http://www.cppblog.com/Roger/archive/2011/11/17/160368.html
随机推荐
- 百度UEditor的config.json
配合自己修改的.net core DLL使用 /* 前后端通信相关的配置,注释只允许使用多行方式 */ { /* 上传图片配置项 */ "imageActionName": &qu ...
- 【C++】Lambda表达式
转自 https://www.cnblogs.com/DswCnblog/p/5629165.html 作者:dsw846 C++11的一大亮点就是引入了Lambda表达式.利用Lambda表达式,可 ...
- kettle无法更新数据库字段解决办法
刚开始使用kettle,遇到一个问题, 在编写一个转换流程时,如果所操作的表字段名发生了变化(例如表student中id变更问userid),但是在kettle中使用时仍然显示是id,如下图, 此时清 ...
- Windows自定义运行命令
1 打开注册表regedit 2 找到:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths 3 新增项,自己运 ...
- MD5加密出现 无法启动:此实现不是Windows平台FIPS验证的加密算法的一部分
出现问题: 出现这个问题的原因是订票助手.NET使用了MD5算法,而系统的组策略安全设置导致无法使用此算法.要修正此问题,请按照如下操作(两种方法任选其一). 注:(来源于 http://ask.f ...
- MFC 使用Skin++ 美化皮肤
查了好几天关于MFC应用程序换肤的资料,经过各种莫名其妙的问题的困扰,现分享一下自己的体会.希望可 以避免一些弯路.另外会在附上一些资源. 环境:Windows 7 + VS2012 + SkinSh ...
- SAS 读取指定目录下文件列表宏
OPTIONS PS=MAX LS=MAX NOCENTER SASMSTORE=SASUSER MSTORED MAUTOSOURCE;/*获取指定文件夹的指定类型的所有文件*/%MACRO GET ...
- vb程序安装时需要在客户端安装MSSOAP30.dll,但注册不上,请问怎么处理
現在想打包发布,在客戶沒有這個控件時,注冊一下,主要是不想在客户机器上安装SoapToolkit30.EXE文件 ?? 推荐解决方案 如果使用 InstallShield 工具来打包,安装完MSSOA ...
- VS2017离线版的SSDT安装包(包括SSIS)
VS2017离线版的SSDT安装包(包括SSIS) 装好SQL2016和VS2017后发现没有创建SSIS项目的接口,原来VS2017里是没有包含SSDT的安装包的. 下面是我整理好的包含中英文的VS ...
- [STM31F103]独立看门狗
独立看门狗步骤: l 取消寄存器写保护: n IWDG_WriteAccessCmd(); l 设置独立看门狗的预分频系数,确定时钟: n IWDG_SetPrescaler(); l 设置看门狗重装 ...