本篇包括三部分内容:
一、语法介绍
详细介绍移步:CMake介绍
CMakeLists的语法如下:
# cmake 版本
cmake_minimum_required(VERSION 2.6)
####
# CMake中指令不区分大小写
# ${} 表示取出变量中的值
####
# 项目名称, 名称后面为支持的语言,不写时默认支持所有语言
PROJECT(project_name [CXX][C][java])
# 或者
PROJECT(name )
# PROJECT(...)语句运行之后,会默认定义两个变量,后面可以直接使用
# name_BINARY_DIR 编译目录
# name_SOURCE_DIR 工程目录
# set表示设置变量名
SET(LIBRARIES /usr/lib/x86_64-linux-gnu/libm.so)
# 变量中只保存一个源文件
SET(SRC_LIST main.c) # 或者 SET(SRC_LIST “main.c”) # 把main.c保存到变量SRC_LIST中
# 也可以是保存多个源文件
SET(SRC_LIST main.c func.c func.h)
# 当然也可以保存所有的源文件,将所有源文件保存到SRC_LIST变量中
AUX_SOURCE_DIRECTORY(directory SRC_LIST)
# 把当前目录下所有源文件全部保存到SRC_LIST变量中
AUX_SOURCE_DIRECTORY(. SRC_LIST)
# 选择指定目录下的源文件保存到变量中
AUX_SOURCE_DIRECTORY(./dir/main.c SRC_LIST)
# message 表示输出提示信息
MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message")
# STATUS 参数较为常用,输出前缀为-的信息
# 第一个参数是消息类型,后面的参数是一条或多条要显示的消息。错误类型有3种:
# SEND_ERROR:表示产生错误信息
# STATUS:表示一般的状态信息
# FATAL_ERROR:我们知道肯定是严重错误信息,cmake会立即停止执行
# 生成可执行文件
ADD_EXECUTABLE(result ${SRC_LIST})
# 添加可执行文件所需要的库
TARGET_LINK_LIBRARIES(result ${LIBRARIES})
# 更改可执行文件的输出目录
SET(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/bin")
# 其中CMAKE_BINARY_DIR 变量中的CMAKE_表示项目名的统称,等价于上面所说的 name_BINARY_DIR
make clean 可以对构建的结果进行清理,但是Cmake 无法跟踪中间文件,故而不能清理中间文件,但在使用git bush代码时需要清理掉中间文件,怎么办呢?
可以使用外部构建(out-of-source build)的方式来解决这个问题:就是在外部任意一个位置建立编译目录,然后cmake指向此目录便可,比如:
# 在当前目录下创建个build文件夹,并进入到build文件夹 此时的build为编译目录
mkdir build && cd build
# 对上级目录进行cmake 中间文件会生成到编译目录(./build)文件夹下
cmake ..
在进行外部构建时:
name_BINARY_DIR变量是指编译目录
name_SOURCE_DIR变量则是指工程源码目录
二、单目录下工程构建
创建一个文件夹,并在该文件夹下依次创建四个文件:
//main.cpp
#include<iostream>
#include"func.h"
using namespace std;
int main(){
cout<<"hello world, hello cmake."<<endl;
func();
return 0;
}
//func.h
#include<iostream>
using namespace std;
void func();
//func.cpp
#include"func.h"
void func(){
cout<<"this is cout from func.."<<endl;
return;
}
# CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
PROJECT(test_cmake)
SET(SRC_LIST main.cpp func.cpp func.h)
ADD_EXECUTABLE(result ${SRC_LIST})
MESSAGE(STATUS "this is a cmake test")
MESSAGE(STATUS "project_directory_is:" ${CMAKE_SOURCE_DIR})
MESSAGE(STATUS "build_directory_is:" ${CMAKE_BINARY_DIR})
依次执行以下命令:
mkdir build && cd build
cmake ..
make
最后、中间文件会生成在build文件夹下,由于没有特指可执行文件的生成路径,默认可执行文件result也生成在了编译目录文件夹(build)下。
./result
hello world, hello cmake.
this is cout from func..
三、多目录下工程构建
ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
向当前工程中添加源文件的子目录,并可以指定中间二进制文件和目标二进制文件存放的位置
如果没有指定binary_dir, binary_dir的值将会是没有任何相对路径展开的source_dir,这也是通常的用法
EXCLUDE_FROM_ALL参数的含义是将这个目录从编译过程中排除,如果指定了EXCLUDE_FROM_ALL选项,在子目录下的目录默认不会被包含到父目录的ALL目录里,并且也会被排除在IDE工程文件之外。用户必须显示构建在子目录下的目标
例如:
ADD_SUBDIRECTORY(src bin)
那么src目录下的构建过程产生的中间文件和输出文件都会出现在build/bin文件夹下
ADD_SUBDIRECTORY(src)
src目录的构建过程产生的中间文件和输出文件都会出现在build/src文件夹下
LIST:
LIST(APPEND <list> <element)...)
将<element> 添加到LIST
├── CMakeLists.txt
├── src1
│ ├── CMakeLists.txt
│ ├── func1.cpp
│ └── func1.h
└── src2
├── CMakeLists.txt
├── func2.cpp
└── func2.h
# 从此语句可以判断该CMakeLists为主目录
cmake_minimum_required(VERSION 2.6)
PROJECT(test3)
SET(CPP_LIST ${})
MESSAGE(STATUS "1. initial_cpplist= "${CPP_LIST})
ADD_SUBDIRECTORY(./core)
MESSAGE(STATUS "4. cpplist_after_core= " ${CPP_LIST})
ADD_SUBDIRECTORY(./example)
MESSAGE(STATUS "9. EXT_LIB_main= " ${EXT_LIB})
MESSAGE(STATUS "10.CMAKE_BINARY_DIR= " ${CMAKE_BINARY_DIR})
MESSAGE(STATUS "11.PROJECT_BINARY_DIR= "${PROJECT_BINARY_DIR})
MESSAGE(STATUS "12.PROJECT_SOURCE_DIR= "${PROJECT_SOURCE_DIR})
MESSAGE(STATUS "13. cpplist_last= " ${CPP_LIST})
INCLUDE_DIRECTORIES(.)
AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/src1 CORE_CPP_LIST)
LIST(APPEND CPP_LIST ${CPP_LIST} ${CORE_CPP_LIST})
MESSAGE(STATUS "2. cpplist_core= " ${CPP_LIST})
SET(CPP_LIST ${CPP_LIST} PARENT_SCOPE)
SET(EXT_LIB /usr/lib/x86_64-gnu/libm.so)
SET(EXT_LIB ${EXT_LIB} PARENT_SCOPE)
MESSAGE(STATUS "3. EXT_LIB_core=" ${EXT_LIB})
# src2 CMakeLists.txt
INCLUDE_DIRECTORIES(.)
AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/src2 EXAM_CPP_LIST)
MESSAGE(STATUS "5. EXAM_CPP_LIST= " ${EXAM_CPP_LIST})
MESSAGE(STATUS "6. before exam cpp_list= " ${CPP_LIST})
LIST(APPEND CPP_LIST ${EXAM_CPP_LIST})
MESSAGE(STATUS "7. cpplist_example= " ${CPP_LIST})
SET(CPP_LIST ${CPP_LIST} PARENT_SCOPE)
ADD_EXECUTABLE(test3 ${CPP_LIST})
SET(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/bin")
MESSAGE(STATUS "8. EXT_LIB_example=" ${EXT_LIB})
TARGET_LINK_LIBRARIES(test3 ${EXT_LIB})
-- 1. initial_cpplist=
-- 2. cpplist_core= /home/xwang/Tools/My_code/cmake/test3/src1/func1.cpp
-- 3. EXT_LIB_core=/usr/lib/x86_64-gnu/libm.so
-- 4. cpplist_after_core= /home/xwang/Tools/My_code/cmake/test3/src1/func1.cpp
-- 5. EXAM_CPP_LIST= /home/xwang/Tools/My_code/cmake/test3/src2/func2.cpp
-- 6. before exam cpp_list= /home/xwang/Tools/My_code/cmake/test3/src1/func1.cpp
-- 7. cpplist_example= /home/xwang/Tools/My_code/cmake/test3/src1/func1.cpp/home/xwang/Tools/My_code/cmake/test3/src2/func2.cpp
-- 8. EXT_LIB_example=/usr/lib/x86_64-gnu/libm.so
-- 9. EXT_LIB_main= /usr/lib/x86_64-gnu/libm.so
-- 10.CMAKE_BINARY_DIR= /home/xwang/Tools/My_code/cmake/test3/build
-- 11.PROJECT_BINARY_DIR= /home/xwang/Tools/My_code/cmake/test3/build
-- 12.PROJECT_SOURCE_DIR= /home/xwang/Tools/My_code/cmake/test3
-- 13. cpplist_last= /home/xwang/Tools/My_code/cmake/test3/src1/func1.cpp/home/xwang/Tools/My_code/cmake/test3/src2/func2.cpp
-- Configuring done
-- Generating done
-- Build files have been written to: /home/xwang/Tools/My_code/cmake/test3/build
updating...