Cmake教程


参考网站:https://subingwen.cn/cmake/CMake-primer/
https://subingwen.cn/cmake/CMake-advanced/
$Cmake -G “MinGW Makefiles” …
$make
$rm -rf *
VScode与Git联合进行代码管理。

cmake_minimum_required(VERSION 3.0)
project(CALC)
add_executable(app add.c div.c main.c mult.c sub.c)
//定义变量SRC——LIST
set(SRC_LIST add.c;div.c;main.c;mult.c;sub.c)
add_executable(app  ${SRC_LIST})
//指定C++的使用标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)

//指定输出路径
set(HOME /D:/test) 
set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)//若目录不存在会自动创建目录。

include_directories(${PROJECT_SOURCE_DIR}/include)//包含的头文件目录地址。
//将src目录下的源文件(.cpp文件)包含在 SRC_LIST变量中。
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src SRC_LIST)
add_executable(app  ${SRC_LIST})

GLOB_RECURSE:递归搜索指定目录,将搜索到的满足条件的文件名生成一个列表,并将其存储到变量中
//搜索当前目录的src目录下所有的.cpp源文件,并存储到变量MAIN_SRC中
file(GLOB MAIN_SRC ${CMAKE_SURRENT_SOURCE_DIR}/src/*.cpp)
fie(GLOB MAIN_HEAD ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h)  */*/
file(GLOB MAIN_SRC "${CMAKE_SURRENT_SOURCE_DIR}/src/*.cpp")

包含头文件目录

$ tree
.
├── build
├── CMakeLists.txt
├── include
│   └── head.h
└── src
    ├── add.cpp
    ├── div.cpp
    ├── main.cpp
    ├── mult.cpp
    └── sub.cpp

3 directories, 7 files

cmake_minimum_required(VERSION 3.0)
project(CALC)
set(CMAKE_CXX_STANDARD 11)
set(HOME /home/robin/Linux/calc)
set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin/)
//包含头文件目录。
include_directories(${PROJECT_SOURCE_DIR}/include)
file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
add_executable(app  ${SRC_LIST})

动态库与静态库

制作静态库

include_directories(${PROJECT_SOURCE_DIR}/include)
file(GLOB SRC_LIST "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
add_library(calc STATIC ${SRC_LIST})
add_library(calc SHARED ${SRC_LIST)

最终生成对应的静态库文件libcalc.a
动态库文件 libcalc.so

设置动态库生成路径

cmake_minimum_required(VERSION 3.0)
project(CALC)
include_directories(${PROJECT_SOURCE_DIR}/include)
file(GLOB SRC_LIST "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
# 设置动态库生成路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
add_library(calc SHARED ${SRC_LIST})

由于在Linux下生成的静态库默认不具有可执行权限,所以在指定静态库生成的路径的时候就不能使用EXECUTABLE_OUTPUT_PATH宏了,而应该使用LIBRARY_OUTPUT_PATH,这个宏对应静态库文件和动态库文件都适用。

链接静态库

link_directories(${PROJECT_SOURCE_DIR}/lib)
link_librarys(calc)
add_executable(app ${SRC_LIST})

链接动态库

# 指定源文件或者动态库对应的头文件路径
include_directories(${PROJECT_SOURCE_DIR}/include)
#指定要链接的动态库的路径
link_directories(${PROJECT_SOURCE_DIR}/lib)
add_executable(app ${SRC_LIST})
#指定要链接的动态库
target_link_library(app calc)

变量操作

变量追加

优势项目的源文件在多个目录中。如果我们通过file命令对各个目录下的源文件进行搜索,最后还需要做一个字符串拼接的操作

file(CLOB SRC_1 "${PROJECT_SOURCE_DIR}/src1/*.cpp")
file(CLOB SRC_2 "${PROJECT_SOURCE_DIR}/src2/*.cpp")
//对变量进行拼接
set(SRC_1 ${SRC_1} ${SRC_2})
//使用list进行拼接
list(APPEND SRC_1 ${SRC_1} ${SRC_2})
message(STATUS "message:${SRC_1")

字符串移除

我们在通过file搜索某个目录就得到了该目录下所有的源文件,但是其中有些源文件并不是我们所需要的

# 移除 main.cpp
list(REMOVE_ITEM SRC_1 ${PROJECT_SOURCE_DIR}/main.cpp)

关于list还有其他功能,但不常用。

宏定义

#include <stdio.h>
#define NUMBER  3

int main()
{
    int a = 10;
#ifdef DEBUG
    printf("我是一个程序猿, 我不会爬树...\n");
#endif
    for(int i=0; i<NUMBER; ++i)
    {
        printf("hello, GCC!!!\n");
    }
    return 0;
}

cmake_minimum_required(VERSION 3.0)
project(TEST)
# 自定义 DEBUG 宏。这时在编译上面的代码时。则在代码中定义了DEBUG
add_definitions(-DDEBUG)
add_executable(app ./test.c)

打印出:是一个程序猿, 我不会爬树。
在这里插入图片描述

1 Cmake 概述

Cmake是一个项目构建工具,还有makefile,但是编写makefile工作量大。Cmake会自动生成makefile文件。

在这里插入图片描述
在这里插入图片描述
g++与gcc的区别:g++编译之后自带C++库文件。而gcc要显示添加。-lstdc++
下图为编译流程:1.预处理。2.编译 3.汇编 4.链接。

g++ -E main.cpp -o main.i  //预处理
g++ -S main.i -o main.s    //编译
g++ -c main.s -o main.o    //汇编
g++ main.o  -o main        //链接

2. Cmake使用

2.1 注释

# 行注释
#[[块注释]]

2.2 执行Cmake命令

通常到当前文件夹新建文件夹build,在此文件夹下执行命令$ cmake …之后然后在执行make命令。这是生成的中间文件就在build文件夹中。

VSCode中使用Cmake

参考资料:
https://subingwen.cn/vscode/cpp-windows/?highlight=cmake
在这里插入图片描述

嵌套的CMake

如果项目很大,或者项目中有很多的源码目录。在通过CMake管理项目的时候如果只使用一个CMakeLists.txt。那么这个文件相对会比较复杂。这时我们可以给每个源码目录都添加一个CMakeLists.txt。这样每个文件都不会太复杂。而且更灵活。更容易维护。

# 添加子目录
add_subdirectory(calc)

目录架构。
在这里插入图片描述

  1. 根节点CMakeLists.txt中的变量全局有效。
  2. 父节点CMakeLists.txt中的变量可以在子节点中使用。
  3. 子节点CMakeLists.txt中的变量只能在当前节点中使用。

根目录的文件

cmake_minimum_required(VERSION 3.0)
project(root)
set(LIB_PATH  ${CMAKE_CURRENT_SOURCE_DIR}/lib)
set(EXEC_PATH ${CMAKE_CURRENT_SOURCE_DIR}/bin)
set(HEAD_PATH ${CMAKE_CURRENT_SOURCE_DIR}/include)
set(CALC_LIB calc)
set(SORT_LIB sort)
set(APP_NAME_1 test1)
set(APP_NAME_2 test2)
#添加子目录中的CMakeLists.txt文件。
add_subdirectory(calc)
add_subdirectory(sort)
add_subdirectory(test1)
add_subdirectory(test2)

子目录的文件

calc中的文件

制作静态库文件

cmake_minimum_required(VERSION 3.0)
project(CALCLIB)
aux_source_directory(./ SRC)
include_directories(${HEAD_PATH})
set(LIBRARY_OUTPUT_PATH ${LIB_PATH})
add_library(${CALC_LIB} STATIC ${SRC})

test1的文件

链接静态库生成可执行文件

cmake_minimum_required(VERSION 3.0)
project(CALCTEST)
aux_source_directory(./ SRC)
include_directories(${HEAD_PATH})
link_directories(${LIB_PATH})
link_libraries(${CALC_LIB})
set(EXECUTABLE_OUTPUT_PATH ${EXEC_PATH})
add_executable(${APP_NAME_1} ${SRC})

现代Cmake

1基础

变量名 CMAKE_GENERATOR
变量值:MinGW Makei
在自己的build文件夹中输入终端命令
cmake -G “MinGW Makefiles” … //…表示上一文件夹。这里是CMakeLists.txt所在文件路径

cmake_minimum_required(VERSION 3.10)
project(Tutorial VERSION 2.11)
set(CMAKE_CXX_STANDARD 26)
set(CMAKE_CXX_STANDARD_REQUIRED True)
#在源文件中包含自己的项目名
configure_file(TutorialConfig.h.in TutorialConfig.h)
a
add_executable(Tutorial tutorial.cxx)

//输出自己先输出的内容
message(STATUS "Hello World form cmake")输出一个字符串
message(STATUS "${Tutorial_VERSION_MAJOR}")//输出项目版本号小数点之前
message(STATUS "${Tutorial_VERSION_MINOR}")//小数点之后

message(STATUS "${PROJECT_BINARY_DIR}")//项目构建目录,这里是自己的build目录

cmakedefine与define的区别

//#cmakedefine 与define的区别
//1.非0值,效果相同。当为0是camkedefien不会定义
//2.对于bool值也是一样的 。为真时,都会定义。为假时cmakedefine不会定义
//3.对于在CmakeLists.txt中为定义的变量define会

config.h.in

#define Tutorial_VERSION_MAJOR ${Tutorial_VERSION_MAJOR}
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
#define STR_TEST "@STR_TEST@" 
#cmakedefine USE_MATH ${USE_MATH}

CMakeLists.txt

cmake_minimum_required(VERSION 3.25)
project(Tutorial VERSION 2.11)
#set的位置需要放在目标位置的前面
set(STR_TEST "Hello world")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
#在源文件中能够读取CmakeLists.txt中的变量。
configure_file(TutorialConfig.h.in TutorialConfig.h)

#option为可选变量  ON/OFF  TRUE/FALSE
option(USE_MATH "use my libmcalcu.a?" ON)
message(STATUS USE_MATH=${USE_MATH})
#添加Cmake子文件夹
if(USE_MATH)
    add_subdirectory(MathFunctions)
    #list里面的变量相当于字符串数组。
    list(APPEND EXTRA_LIBS mycalcu)
    list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
endif()

#生成可执行文件
add_executable(Tutorial mian.cpp)
#给目标链接库文件
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
# 目标的include文件夹  PROJECT_BINARY_DIR表示自己的build文件夹。
#PROJECT_SOURCE_DIR 表示自己的源文件目录,在两端加上双引号的目的是防止路径中空格的出现
target_include_directories(Tutorial PUBLIC "${PROJECT_BINARY_DIR}"
                                            ${EXTRA_INCLUDES}
                          )

message(STATUS out-- "Hello World form cmake")
message(STATUS "${Tutorial_VERSION_MAJOR}")
message(STATUS "${Tutorial_VERSION_MINOR}")

main.cpp

#include<iostream>
#include"TutorialConfig.h"
#ifdef USE_MATH
    #include"mycalcu.h"
#endif
int main(){
    std::cout<<"Tutorial_VERSION_MAJOR:"<<Tutorial_VERSION_MAJOR<<std::endl;
    std::cout<<"Tutorial_VERSION_MINOR:"<<Tutorial_VERSION_MINOR<<std::endl;
    std::cout<<"STR:"<<STR_TEST<<std::endl;
#ifdef USE_MATH
    std::cout<<"5*6="<<Multi(5,6)<<std::endl;
#endif
   // char ch;
    //std::cin>>ch;
    return 0;
}

CMake中使用第三方库流程

在这里插入图片描述

  • 32
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值