一步一步学Cmake之 构建 单目录或多目录 C++工程

本篇包括三部分内容:

一、语法介绍

二、单目录下工程构建

三、多目录下工程构建


一步一步学 CMake 系列文章

一、语法介绍

详细介绍移步: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...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值