https://alenstar.github.io/post/cmake_template/

首先我们来看看我们的工程目录结构

$ tree myprojectmyproject  # 工程目录
├── CMakeLists.txt # 入口CMakeLists.txt文件
├── example.c
├── include  # 头文件目录
│   ├── arch.h
│   ├── base.h
│   ├── common.h
│   └── data.h
├── LICENSE
├── README.md
└── src  # 源代码目录├── arch.c├── base.c├── CMakeLists.txt  # 子CMakeLists.txt文件├── common.c└── data.c

入口CMakeLists.txt文件分析

# 设置最低cmake版本要求
cmake_minimum_required(VERSION 2.8.7 FATAL_ERROR) #支持 pkg-config
include(FindPkgConfig)
#检查 libcurl cairo 等模块, 并获取它们的LIBS和INCLUDE, 结果保存到变量 LB_LIBS_XXX 中
# LB_LIBS_INCLUDE_DIRS # 保存包含路径
# LB_LIBS_LIBRARIES # 保存连接库
pkg_check_modules(LB_LIBS REQUIRED libcurl cairo)# 设置项目名称
project(myproject) # 检查编译目录和源码是否为同一目录, 如果是则提示错误
if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")message(FATAL_ERROR "Do not build in-source.\nPlease remove CMakeCache.txt and the CMakeFiles/ directory.\nThen: mkdir build ; cd build ; cmake .. ; make")
endif()if( CMAKE_BUILD_TYPE STREQUAL "Release" )add_definitions(-DNODEBUG)
else()add_definitions(-DDEBUG)#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -O0 -ggdb")#set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -ggdb")#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -O0 -ggdb")#set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -ggdb")
endif()set(CMAKE_CXX_STANDARD 11)# 设置变量 PROJECT_NAME 并初始化, 使用 ${XXX} 引用, 如: ${PROJECT_NAME}
set(PROJECT_NAME "xxx")add_definitions(-DDEBUG) # 添加宏定义# 设置CMAKE_C_FLAGS, `${CMAKE_C_FLAGS}` 可取出CMAKE_C_FLAGS的值
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -ggdb") # 添加include目录(-l)
include_directories(src)
include_directories(include) # 设置 XXX_TESTS 为 OFF
set(XXX_TESTS OFF CACHE BOOL "")
# 添加子目录, 子目录要包含CMakeLists.txt文件
add_subdirectory(src) # 添加可执行文件 example 的生成规则, 后面接依赖文件或者文件列表
add_executable(example example.c)
# 设置可执行文件 example 的链接库, 后面接的可以是系统库, 也可以是 子目录下的自定义库
target_link_libraries(example lib) # 检测是否配置了编译类型[Release|Debug], 如果没有配置则配置为Release
if(NOT CMAKE_BUILD_TYPE)set(CMAKE_BUILD_TYPE "Release" CACHE STRING"Choose the type of build, options are: Debug Profile Release Asan Ubsan." FORCE)
endif(NOT CMAKE_BUILD_TYPE)

子CMakeLists.txt文件

cmake_minimum_required(VERSION 2.6) # cmake 版本要求
project(lib) # 项目名称# 设置option
# 可以在 add_subdirectory(xxx) 时用 set(XXX OFF|ON CACHE BOOL "") 来设置值
#        名称 描述        默认值[ON | OFF]
# option(XXX "描述 ... " ON)
option(XXX_TESTS "Build xxx tests and enable testing" ON)
option(XXX_STATIC "Build static library" ON)
option(XXX_SHARED "Build shared library" ON)# 根据 option 条件编译
# if 语句 支持逻辑运算 [AND | OR | NOT] ; #支持else分支: if() else() endif()
if(XXX_TESTS) # TODO# enable_testing()# add_subdirectory(test testdir)
endif()# 设置包含目录( `./` 当前目录)
include_directories(./) # 设置文件列表SRC_FILES (自定义名称) 的文件内容( 包含的文件 )
set(SRC_FILES arch.c base.c common.c data.c) # 添加静态库 lib 的生成规则, 依赖 SRC_FILES
add_library(lib STATIC ${SRC_FILES})
# 添加动态态库 lib 的生成规则, 依赖 SRC_FILES
add_library(lib_shared SHARED ${SRC_FILES})

构建项目

为了保持项目目录的干净, 我们一般会在build目录下进行构建

$ mkdir build # 创建构建目录
$ cd build # 进入构建目录
$ cmake .. # 从上级目录构建, 构建产生的临时文件和目标文件将在当前目录生成
$ make # 生成目标

添加 c++11 支持

添加一个编译器选项 add_compile_options(-std=c++11) # CMake 2.8.12 or newer不过这种方式不够灵活

使用set来设置cmake内置变量

set(CMAKE_CXX_STANDARD 11) # C++11...
set(CMAKE_CXX_STANDARD_REQUIRED ON) #...is required...
set(CMAKE_CXX_EXTENSIONS OFF) #...without compiler extensions like gnu++11

为特定目标进行设置, set_target_properties 可以为要生成的目标设置属性 PROPERTIES 以实现不同目标的差异处理

set_target_properties(myTarget PROPERTIESCXX_STANDARD 11CXX_STANDARD_REQUIRED ONCXX_EXTENSIONS OFF
)

设置运行时库搜索路径 (gcc -Wl,-rpath=./)

set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_INSTALL_RPATH "./")

设置链接时库搜索路径 (gcc -L./)

LINK_DIRECTORIES("./lib")

其他-使用自定义动态/静态库

# copy local file 拷贝文件
configure_file(${CMAKE_SOURCE_DIR}/libsqlite3.so ${CMAKE_BINARY_DIR}/libsqlite3.so COPYONLY)# add local library 添加库文件
add_library(sqlite3 SHARED IMPORTED) # or STATIC instead of SHARED# 设置库文件属性(文件路径,头文件目录)
set_target_properties(sqlite3 PROPERTIESIMPORTED_LOCATION "${CMAKE_BINARY_DIR}/libsqlite3.so"INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}/include")# 添加到链接目标
target_link_libraries(<TARGET> sqlite3)

使用自定义命令

# 添加命令, OUTPUT 输出, COMMAND 命令
add_custom_command(OUTPUT  ${CMAKE_BINARY_DIR}/message.proto3.pb.ccCOMMAND ${PROTOC} --cpp_out=${CMAKE_BINARY_DIR} --proto_path=${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/message.proto3
)
# 添加到 OUTPUT 到 SRCS 变量中 (OUTPUT必须被依赖,否则不会执行命令)
List (APPEND SRCS  ${CMAKE_BINARY_DIR}/message.proto3.pb.cc)

包含cmake格式的配置文件

include(xxxx.cmake)

包含子工程

# 添加子目录, 子目录要包含CMakeLists.txt文件
add_subdirectory(subdir)

OS define

if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")set(WINDOWS TRUE)message(WARNING "only for Windows")
else()set(LINUX TRUE)message(WARNING "only for linux")
endif()

cross build

if(BUILD_FOR_ARM)SET(CROSS_TOOLS_PATH /opt/crosstools/arm-2009q3/bin/arm-none-linux-gnueabi)SET(CROSS_ROOT_PATH /opt/crosstools/sys-root)# this one is importantSET(CMAKE_SYSTEM_NAME Linux)#this one not so muchSET(CMAKE_SYSTEM_VERSION 1)# specify the cross compilerSET(CMAKE_C_COMPILER   ${CROSS_TOOLS_PATH}-gcc)SET(CMAKE_CXX_COMPILER ${CROSS_TOOLS_PATH}-g++)# where is the target environmentSET(CMAKE_FIND_ROOT_PATH  ${CROSS_ROOT_PATH})# search for programs in the build host directoriesSET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)# for libraries and headers in the target directoriesSET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
endif()

使用文件配置交叉编译工具链

# 文件 arm-none-linux-gnueabi-gcc.cmake
SET(CROSS_TOOLS_PATH /opt/crosstools/arm-2009q3/bin/arm-none-linux-gnueabi)
SET(CROSS_ROOT_PATH /opt/crosstools/sys-root)# this one is important
SET(CMAKE_SYSTEM_NAME Linux)
#this one not so much
SET(CMAKE_SYSTEM_VERSION 1)# specify the cross compiler
SET(CMAKE_C_COMPILER   ${CROSS_TOOLS_PATH}-gcc)
SET(CMAKE_CXX_COMPILER ${CROSS_TOOLS_PATH}-g++)# where is the target environment
SET(CMAKE_FIND_ROOT_PATH  ${CROSS_ROOT_PATH})# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# 使用交叉工具链编译工程
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../arm-none-linux-gnueabi-gcc.cmake ..

cmake 入门学习相关推荐

  1. [转] CMake入门

    转载说明: 文章转自网络,版权归原作者所有, 原文链接: https://www.hahack.com/codes/cmake/ 特别感谢发哥(写代码的篮球痴 )分享 文章目录 ▌什么是 CMake? ...

  2. 【ceph】cmake管理Ceph编译+Ceph工程目录+cmake 实战学习

    前言 Ceph cmake 工程 cmake生成的目录 cmake工程添加新模块(CMakeLists.txt) 添加动态库依赖 cmake导入外部链接库 *.cmake文件 cmake生成编译DEB ...

  3. ESP32入门学习笔记

    概述 ESP32-DevKitC V4 是 乐鑫 一款基于 ESP32 的小型开发板,板上模组的绝大部分管脚均已引出,开发人员可根据实际需求,轻松通过跳线连接多种外围器件,或将开发板插在面包板上使用. ...

  4. python速成要多久2019-8-28_2019最全Python入门学习路线,不是我吹,绝对是最全

    近几年Python的受欢迎程度可谓是扶摇直上,当然了学习的人也是愈来愈多.一些学习Python的小白在学习初期,总希望能够得到一份Python学习路线图,小编经过多方汇总为大家汇总了一份Python学 ...

  5. MAYA 2022基础入门学习教程

    流派:电子学习| MP4 |视频:h264,1280×720 |音频:AAC,48.0 KHz 语言:英语+中英文字幕(根据原英文字幕机译更准确)|大小解压后:3.41 GB |时长:4.5小时 包含 ...

  6. 3dmax Vray建筑可视化入门学习教程

    面向初学者的3Ds Max Vray最佳Archviz可视化课程 从安装到最终图像的一切都将从头开始教授,不需要任何经验 大小解压后:3.25G 时长4h 6m 1280X720 MP4 语言:英语+ ...

  7. Blender 3.0基础入门学习教程 Introduction to Blender 3.0

    成为Blender通才,通过这个基于项目的循序渐进课程学习所有主题的基础知识. 你会学到什么 教程获取:Blender 3.0基础入门学习教程 Introduction to Blender 3.0- ...

  8. Maya游戏角色绑定入门学习教程 Game Character Rigging for Beginners in Maya

    准备好开始为游戏制作自己的角色动画了吗? 你会学到什么 了解Maya的界面 优化并准备好你的模型,为游戏做准备 了解关节以及如何使用它们来构建健壮的角色骨骼,以便在任何游戏引擎中制作动画 了解IK和F ...

  9. 三维地形制作软件 World Machine 基础入门学习教程

    <World Machine课程>涵盖了你需要的一切,让你有一个坚实的基础来构建自己的高质量的电影或视频游戏地形. 你会学到什么 为渲染或游戏开发创建高分辨率.高细节的地形. 基于Worl ...

最新文章

  1. 32位dll注入到64位程序_你用的32位还是64位?有什么区别呢?
  2. 机器学习中常见的过拟合解决方法
  3. 【Android 插件化】VAHunt 检测插件化引擎的具体细节
  4. Oracle优化01-引起数据库性能问题的因素
  5. 转载一篇关于curl的文章
  6. 超级强大的socket工具ss,替代netstat
  7. oa系统源码 python_区块链技术基于springboot的办公oa系统实现源代码
  8. 剖析《Linux 平均负载:解开谜团》
  9. 【数据结构】树(六)—— 二叉平衡树(C语言版)
  10. 互联网舆情数据监测预警分析系统软件不收费的有哪些详解
  11. Exchange 日常管理六之:创建邮箱数据库
  12. unity将指定UI图片置为灰色
  13. 以太坊的单位wei是什么?
  14. 孩子总是偷偷玩游戏,家长该怎么办?
  15. 给Ubuntu安装驱动(nvidia)保姆级教程(方法一)
  16. html超链接的锚点链接的使用
  17. 求asinx+bcosx的不定积分
  18. 2022年泰迪杯数据分析_B题:银行客户忠诚度分析赛题数据_任务五
  19. python编码转换在线_在线UTF-8编码汉字互转 | utf8编码转换器
  20. fabric链码安装失败

热门文章

  1. HTML5实战 学习笔记
  2. (转)Silverlight显示本地图片、Stream转Byte数组
  3. vtk读取文件并显示的几种方法
  4. AlexNet代码解读
  5. 凸优化问题工具包cvxpy安装
  6. MMSE法用于MIMO系统
  7. 【Windows10下OpenCV 3.4.0 + Visual Studio 2015开发环境的配】
  8. 斯坦福CS231n项目实战(一):k最近邻(kNN)分类算法
  9. 关于h5py的使用及数据封装实例
  10. 无监督学习:异常检测与剔除(局部异常因子法 SVM异常检测器)