参考资料地址:https://github.com/Akagi201/learning-cmake/blob/master/docs/cmake-practice.pdfgit
1、初识cmakegithub
1. Cmake特色vim
2、初试cmake —— helloworldui
1. 准备工做spa
mkdir -p /backup/cmake开放源代码
cd /backup/cmakecode
mkdir t1blog
cd t1文档
在t1目录创建main.c和CMakeLists.txt文件:it
//main.c
1 #include<stdio.h> 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变量:<projectname>_BINARY_DIR以及<projectname>_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"...) //用于向终端输出用户定义的信息
包含了三种类型:
(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)外部编译过程
//外部编译优点:对原有的工程没有任何影响,全部的活动均发生在编译目录(build)
//注意:此时的HELLO_SOURCE_DIR仍然指代工程路径,即/backup/cmake/t1;而HELLO_BINARY_DIR则指代编译路径,即/backup/cmake/t1/build
3、更好的Hello World
在采用外部构建的基础上(构建目录为build子目录),修改上述Hello World使得更像一个工程,实现目标以下:
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或者共享库,不包含编译生成的中间文件)
注:指令加到哪一个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文件
注:DESTINATION均使用相对路径,安装后的路径为${CMAKE_INSTALL_PREFIX}/<DESTINATION定义的路径>,若采用绝对路径则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