• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
MKT-porter
博客园    首页    新随笔    联系   管理    订阅  订阅
CMake 学习(0)基本指令和例子

Cmake 语法与实战入门

  1. 官方主页
  2. 官方文档
  3. 官方教程

语法

1指定cmake最小版本

cmake_minimum_required(VERSION 3.4.1)

    

在有些情况下,如果 CMakeLists.txt 文件中使用了一些高版本 cmake 特有的一些命令的时候,就需要加上这样一行,提醒用户升级到该版本之后再执行 cmake。 

2设置项目名称 

project(demo)

它会引入两个变量 demo_BINARY_DIR 和 demo_SOURCE_DIR,

同时,cmake 自动定义了两个等价的变量 PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR。

3设置编译类型

add_executable(demo demo.cpp) # 生成可执行文件
add_library(common STATIC util.cpp) # 生成静态库
add_library(common SHARED util.cpp) # 生成动态库或共享库

  

add_library 默认生成是静态库,通过以上命令生成文件名字,

在 Linux 下是:demo libcommon.a libcommon.so

在 Windows 下是:demo.exe common.lib common.dll

4指定编译包含的源文件

4- 1明确指出包含哪些源文件

add_library(demo demo.cpp test.cpp util.cpp)

4-2搜索所有的cpp文件 

aux_source_directory(dir VAR) 发现一个目录(dir)下所有的源代码文件并将列表存储在一个变量(VAR)中。

aux_source_directory(. SRC_LIST) # 搜索当前目录下的所有.cpp文件
add_library(demo ${SRC_LIST})

4-3自定义搜索规则

#1file模式 搜索同目录+protocol目录所有的cpp文件
file(GLOB SRC_LIST "*.cpp" "protocol/*.cpp")
add_library(demo ${SRC_LIST})

# 2file模式 分开目录搜索添加
file(GLOB SRC_LIST "*.cpp")#单独搜索本目录所有cpp 存放变量SRC_LIST
file(GLOB SRC_PROTOCOL_LIST "protocol/*.cpp")#单独搜索protocol目录所有cpp 存放变量SRC_PROTOCOL_LIST
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})

# 3 aux模式  
aux_source_directory(. SRC_LIST)##单独搜索本目录所有cpp 存放变量SRC_LIST
aux_source_directory(protocol SRC_PROTOCOL_LIST)#单独搜索protocol目录所有cpp 存放变量SRC_PROTOCOL_LIST
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})

5-1设置包含的目录

 如果src/math.cpp和include/math.h不在同一个文件夹,math.cpp中引用math.h头文件

模式1 使用相对路径 include/math.h

模式2 使用直接路径math.h 但是camke要指定包含include文件夹

 

include_directories(
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_BINARY_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}/include
)

  

5-2添加一个子目录并构建该子目录

add_subdirectory (source_dir [binary_dir] [EXCLUDE_FROM_ALL])

  

  • source_dir
    必选参数。该参数指定一个子目录,子目录下应该包含CMakeLists.txt文件和代码文件。子目录可以是相对路径也可以是绝对路径,如果是相对路径,则是相对当前目录的一个相对路径。
  • binary_dir
    可选参数。该参数指定一个目录,用于存放输出文件。可以是相对路径也可以是绝对路径,如果是相对路径,则是相对当前输出目录的一个相对路径。如果该参数没有指定,则默认的输出目录使用source_dir。
  • EXCLUDE_FROM_ALL
    可选参数。当指定了该参数,则子目录下的目标不会被父目录下的目标文件包含进去,父目录的CMakeLists.txt不会构建子目录的目标文件,必须在子目录下显式去构建。例外情况:当父目录的目标依赖于子目录的目标,则子目录的目标仍然会被构建出来以满足依赖关系(例如使用了target_link_libraries)。
  • 例子
 


6-1查找指定的库文件

 find_library(VAR name path)查找到指定的预编译库,并将它的路径存储在变量中。
默认的搜索路径为 cmake 包含的系统库,因此如果是 NDK 的公共库只需要指定库的name 即可(不需path)。

find_library(log-lib,log)

类似的命令还有 find_file()、find_path()、find_program()、find_package()。  

 

6-2设置target需要链接的库 

target_link_libraries( # 目标库 demo # 目标库需要链接的库 ${log-lib} )

在 Windows 下,系统会根据链接库目录,搜索xxx.lib 文件,Linux 下会搜索 xxx.so 或者 xxx.a 文件,如果都存在会优先链接动态库(so 后缀)。

 6-2-1指定链接动态库或静态库

target_link_libraries(demo libface.a) # 链接libface.a
target_link_libraries(demo libface.so) # 链接libface.so

2. 指定全路径

target_link_libraries(demo ${CMAKE_CURRENT_SOURCE_DIR}/libs/libface.a)
target_link_libraries(demo ${CMAKE_CURRENT_SOURCE_DIR}/libs/libface.so)

3. 指定链接多个库

target_link_libraries(demo
    ${CMAKE_CURRENT_SOURCE_DIR}/libs/libface.a
    boost_system.a
    boost_thread
    pthread)

  

7设置变量

set 直接设置变量的值 

set(SRC_LIST main.cpp test.cpp)
add_executable(demo ${SRC_LIST})

 set 追加设置变量的值 

 
set(SRC_LIST main.cpp)
set(SRC_LIST ${SRC_LIST} test.cpp)
add_executable(demo ${SRC_LIST})

  

常用变量

PROJECT_SOURCE_DIR:工程的根目录

PROJECT_BINARY_DIR:运行cmake命令的目录,通常为${PROJECT_SOURCE_DIR}/build

PROJECT_NAME:返回通过 project 命令定义的项目名称

CMAKE_CURRENT_SOURCE_DIR:当前处理的 CMakeLists.txt 所在的路径

CMAKE_CURRENT_BINARY_DIR:target 编译目录

CMAKE_CURRENT_LIST_DIR:CMakeLists.txt 的完整路径

EXECUTABLE_OUTPUT_PATH:重新定义目标二进制可执行文件的存放位置

LIBRARY_OUTPUT_PATH:重新定义目标链接库文件的存放位置

 

 

测试例程

例子1 文件包含模式-非库引用

 

 CMakeLists.txt

# 父目录下的CMakeLists.txt
cmake_minimum_required(VERSION 3.10.2)
project(test)

#1手动设置指定文件
set(Current_LIST main.cpp )
set(SRC_LIST src/API_Cout.cpp) #不需要指定头文件

#2自动搜所文件目录
#aux_source_directory(. Current_LIST) # 搜索当前.目录下的所有.cpp文件
#aux_source_directory(./src SRC_LIST) # 搜索src目录下的所有.cpp文件

add_executable(demo ${Current_LIST} ${SRC_LIST})

  

 main.cpp

#ifndef MAIN_CPP
#define MAIN_CPP

#include "src/API_Cout.h"
#include <iostream>

int main(int argc, char** argv)
{
    std::cout << "In main..." << std::endl;
    test("hello, world!");
    return 0;
}

#endif MAIN_CPP

  

  API_Cout.h

#ifndef COUT_H
#define COUT_H


#include <string>

void test(std::string str);

#endif

  

  API_Cout.cpp

#ifndef COUT_CPP
#define COUT_CPP

#include "API_Cout.h"
#include <iostream>

void test(std::string str)
{
    std::cout << str << std::endl;
}

#endif

  

 

编译运行结果  

直接命令行

cd build
camke ..
make

  

vscode-View-terminal

 

 

 

 

例子2 文件包含模式-打包库引用

同例子1样的代码

打包成库参与引用

src多了一个cmakelist.txt

 

 注意事项

1所有的cmaklist中涉及到的变量不能同名

2 代码用的是相对路径引用

 

 

#include "src/API_Cout.h"

  

 

例子3 文件包含模式-打包库引用

 

正常模式1 使用了相对路径引用,不需要include_directories包含引用文件路径

 

 正常模式2 不使用了相对路径引用,需要include_directories包含引用文件路径

 

 主函数采用非相对引用

#include "API_Cout.h"  //关键地方 不是相对引用 src/API_Cout.h

cmake需要包含文件路劲

include_directories(src)#关键 不是相对引用 需要单独制定包含

  

include_directories命令使得不使用相对路径也可以包含引用文件。

缺点,但是不建议这么干,代码逻辑混乱

优点,可能一些复杂的工程借助于此,编辑样例的时候省去了一堆相对路径查找和包含。

 

例子4 -1多项目,各自工程独立文件夹编译

 

 

 CMakeLists.txt

# 父目录下的CMakeLists.txt
cmake_minimum_required(VERSION 3.10.2)
project(test)

add_subdirectory("v1_Test")
add_subdirectory("v2_Test")
add_subdirectory("v3_Test")

  

 

  CMakeLists.txt

#1手动设置指定文件
set(Current_LIST main.cpp )
set(SRC_LIST src/API_Cout.cpp) #不需要指定头文件

#2自动搜所文件目录
#aux_source_directory(. Current_LIST) # 搜索当前.目录下的所有.cpp文件
#aux_source_directory(./src SRC_LIST) # 搜索src目录下的所有.cpp文件

add_executable(demo1 ${Current_LIST} ${SRC_LIST})

  

 

 

#1手动设置指定文件
set(Current_LIST main.cpp )
set(SRC_LIST src/API_Cout.cpp) #不需要指定头文件

#2自动搜所文件目录
#aux_source_directory(. Current_LIST) # 搜索当前.目录下的所有.cpp文件
#aux_source_directory(./src SRC_LIST) # 搜索src目录下的所有.cpp文件

add_executable(demo2 ${Current_LIST} ${SRC_LIST})

  

 

 

 

 

 

#1手动设置指定文件
set(Current_LIST main.cpp )
set(SRC_LIST src/API_Cout.cpp) #不需要指定头文件

#2自动搜所文件目录
#aux_source_directory(. Current_LIST) # 搜索当前.目录下的所有.cpp文件
#aux_source_directory(./src SRC_LIST) # 搜索src目录下的所有.cpp文件

add_executable(demo3 ${Current_LIST} ${SRC_LIST})

  

编译

cd build
camke ..
make

  

 

 

 

例子4 -2多项目,各自工程使用共同文件夹编译

 

 

CMakeLists.txt

 

cmake_minimum_required(VERSION 2.6)
project(tcp)
 
#自动连接模式
 
#1将文件夹下全部文件链接到 src
#aux_source_directory(. src)
#将src里面的所有文件链接用于生成可执行文件
#add_executable(project1 ${src})     
 
#手动添加模式
#1测试-生成可执行文件main
add_executable(main src/main.cpp)
 
add_executable(client src/client.cpp)
 
add_executable(Server src/Server.cpp)
 
add_executable(http_client src/http_client.cpp)
 
 #设置可执行文件的输出目录
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)     

src源码地址

可执行文件夹

posted on 2022-01-06 22:20  MKT-porter  阅读(275)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3