前期准备
系统环境: centos 7.2
安装cmake ref: CentOS之—— CentOS7源码安装cmake
cmake世界的HelloWorld
demo过程
- 在centos系统的任意位置处创建cmake_learning文件夹:
- 在文件夹下创建1个mian.c文件和1个CMakeLists.txt文件, 内容如下:
// main.c
#include <stdio.h>
int main(){
printf("Hello World from Main!\n");
return 0;
}
//CMakeLists.txt
PROJECT (HELLO)
SET(SRC_LIST main.c)
MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})
MESSAGE(STATUS "This is SOURCE dir " ${HELLO_SOURCE_DIR})
ADD_EXECUTABLE(hello ${SRC_LIST})
- 开始构建
当前目录运行命令: cmake .
终端输出内容为:
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- This is BINARY dir /opt/learningNotes/cmake_learning
-- This is SOURCE dir /opt/learningNotes/cmake_learning
-- Configuring done
-- Generating done
-- Build files have been written to: /opt/learningNotes/cmake_learning
此时,当前目录生成若干文件:
CMakeCache.txt cmake_install.cmake main.c
CMakeFiles CMakeLists.txt Makefile
最重要的是生成了MakeFile文件,接着在当前目录继续输入命令: make
终端输出内容为:
(ps:如果想看到make构建的详细过程,可以使用make VERBOSE=1或者VERBOSE=1
make命令来进行构建。)
此时,目标文件hello已经生成于当前目录,运行该文件: ./hello
终端输出:
Hello World from Main!
简单解释
CMakeLists.txt是cmake的构建定义文件,文件名对大小写敏感。
当你的工程存在多级目录时,每个目录下都要存在一个CMakeLists.txt。
回顾一下CMakeLists.txt的内容:
//CMakeLists.txt
PROJECT (HELLO)
SET(SRC_LIST main.c)
MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})
MESSAGE(STATUS "This is SOURCE dir " ${HELLO_SOURCE_DIR})
ADD_EXECUTABLE(hello ${SRC_LIST})
PROJECT指令
PROJECT(工程名 [CXX] [C] [java]) //默认支持全语言
该指令隐含地定义了2个cmake变量:
- <projectname>_BINARY_DIR
- <projectname>_SOURCE_DIR
而且,目前采用内部编译,这2个变量均指向当前目录,后面会涉及外部编译方式
同时,cmake 系统预定义了 PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR 变量,它们的值与上述2个变量一致
SET指令
SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
set指令用来显示地定义变量
存在多个源文件时,定义为:
SET(SRC_LIST main.c t1.c t2,c)
MESSAGE指令
MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display" ...)
MESSAGE指令用于向终端输出用户定义的信息,包含了3种类型:
SEND\_ERROR,产生错误,生成过程被跳过。
SATUS,输出前缀为\-的信息。
FATAL_ERROR,立即终止所有cmake过程
### ADD_EXECUTABLE指令
ADD\_EXECUTABLE(hello ${SRC\_LIST})
定义了这个工程会生成一个文件名为hello的可执行文件,相关的源文件是SRC\_LIST中定义的源文件列表, 本例中你也可以直接写成ADD_EXECUTABLE(hello main.c)
### 清理工程
make clean
基本语法规则

ps:
内部构建和外部构建
上述构建方式属于内部构建,但cmake强烈推荐外部构建方式
1,首先,请清除当前目录中除main.c CmakeLists.txt之外的所有中间文件,最关键的是CMakeCache.txt
2. 在当前目录下建立build子目录,当然你也可以在任何地方建立build目录,不一定必须在工程目录中
3.进入build目录,运行cmake ..
(注意,..代表父目录,因为父目录存在我们需要的CMakeLists.txt,如果你在其他地方建立了build目录,需要运行cmake <工程的全路径>),查看一下build目录,就会发现了生成了编译需要的Makefile以及其他的中间文件
4.运行make构建工程,就会在当前目录(build目录)中获得目标文件hello
工程的全路径>
上述过程就是所谓的out-of-source外部编译,一个最大的好处是,对于原有的工程没有任何影响,所有动作全部发生在编译目录。通过这一点,也足以说服我们全部采用外部编译方式构建工程。
这里需要特别注意的是:
通过外部编译进行工程构建,HELLO_SOURCE_DIR仍然指代工程路径,即
/opt/learningNotes
而HELLO_BINARY_DIR则指代编译路径,即 /opt/learningNotes/build
