CMake&CMakeList.txt

2023-05-16

1、各种关系

 

在各种开源项目中,经常会发现项目中除了代码源文件,还包含了 CMakeList.txtMakefile 文件,在项目的编译时候需要用到的命令有 cmakemake。我们本次想搞清楚他们之前的关系以及CMakeList的语法规则。

正常情况下,我们编写程序的大体流程为:

1)用编辑器(vim、emacs等)编写源代码文件(.h、.cpp等);

2)用编译器编译代码生成目标文件(.o等);

3)用链接器连接目标文件生成可执行文件(.exe等)。

一个程序在编写时,可能需要编写很多的代码文件,以及依赖很多第三方的库。在这种情况下,手动依次编译每个文件会变的非常麻烦,效率低下。

make 是一个自动化的批量编译工具,可以实现用一个命令构建整个工程的目的。但是其执行需要依赖一个规则文件,这个文件就是 Makefile。 Makefile 文件里详细描述了构建的细节(文件的依赖关系,编译的先后顺序等)。

对于一个大工程来说,编写 Makefile 文件也是一项非常复杂的事情。

cmake(Cross-platform Make)是一个可以自动生成 Makefile 文件的工具,当然它不只能生成 Makefile ,还能跨平台生成主流IDE(VS, xcode…)构建工程所需的 project 文件。 cmake 的执行同样需要依赖规则文件,这个文件就是 CMakeLists.txt 。

所以,为了能够把一堆c,cc,cpp,h,hpp代码变成可运行的库或者程序,核心还是Makefile,CMakefiles.txt纯粹是为了降低不懂Unix体系的人去编译C/C++代码做的一个自动系统和环境检测和设置工具,同时帮你生成Makefile。

综上所述,大致可以总结 cmake, make, CMakeList.txt, Makefile 之间的关系,如下图所示:

2、CMakeList.txt规则

鉴于目前在开发中,主要遇到的是使用CMake和CMakeList.txt使用的问题,重点介绍下CMakeList.txt的编写规则。

CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。

CMake的所有的语句都写在一个叫:CMakeLists.txt的文件中。当CMakeLists.txt文件确定后,可以用ccmake命令对相关 的变量值进行配置。这个命令必须指向CMakeLists.txt所在的目录。配置完成之后,应用cmake命令生成相应的makefile(在Unix like系统下)或者 project文件(指定用window下的相应编程工具编译时)

2.1 常用命令

2.11 指定 cmake 的最小版本

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

cmake_minimum_required(VERSION 3.4.1)

2.12 设置项目名称

这个命令不是强制性的,但最好都加上。它会引入两个变量 demo_BINARY_DIR 和 demo_SOURCE_DIR,同时,cmake 自动定义了两个等价的变量 PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR。

project(demo)

2.13 设置编译类型

add_executable(demo test.cpp) # 生成可执行文件

add_library(common STATIC test.cpp) # 生成静态库

add_library(common SHARED test.cpp) # 生成动态库或共享库

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

在 Linux /Mac下是:

  • demo

  • libcommon.a

  • libcommon.so

在 Windows 下是:

  • demo.exe

  • common.lib

  • common.dll

2.14 执行编译包含的源文件

2.14.1 明确指定包含哪些源文件

源文件少时可以这么做

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

2.14.2 搜索所有的 cpp 文件

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

aux_source_directory(. SRC_LIST) # 搜索当前目录下的所有.cpp文件,存储在变量SRC_LIST中

add_library(demo ${SRC_LIST})

2.14.3 自定义搜索规则

file(GLOB SRC_LIST "*.cpp" "protocol/*.cpp") #查找当前目录下、及protocol目录下所有cpp文件,保存在变量SEC_LIST中

add_library(demo ${SRC_LIST})

# 或者

file(GLOB SRC_LIST "*.cpp") #查找当前目录下所有cpp文件,保存在变量SRC_LIST中

file(GLOB SRC_PROTOCOL_LIST "protocol/*.cpp")

add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})

# 或者

file(GLOB_RECURSE SRC_LIST "*.cpp") #递归搜索

FILE(GLOB SRC_PROTOCOL RELATIVE "protocol" "*.cpp") # 相对protocol目录下搜索

add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})

# 或者

aux_source_directory(. SRC_LIST)

aux_source_directory(protocol SRC_PROTOCOL_LIST)

add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})

2.15 查找指定的库文件

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

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

find_library( # Sets the name of the path variable.

                log-lib

              # Specifies the name of the NDK library that

              # you want CMake to locate.

                log )

2.16 设置包含的目录

include_directories(

${CMAKE_CURRENT_SOURCE_DIR}

${CMAKE_CURRENT_BINARY_DIR}

${CMAKE_CURRENT_SOURCE_DIR}/include

)

Linux和Mac下还可以通过如下方式设置包含的目录

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_CURRENT_SOURCE_DIR}")

2.17 设置链接库搜索目录

link_directories(

${CMAKE_CURRENT_SOURCE_DIR}/libs

)

Linux和Mac下还可以通过如下方式设置链接库搜索目录

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_CURRENT_SOURCE_DIR}/libs")

2.18 设置 target 需要链接的库

target_link_libraries( # 目标库

demo

# 目标库需要链接的库

# log-lib 是上面 find_library 指定的变量名

${log-lib} )

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

2.18.1 指定链接静态库或动态库

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

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

2.18.2 指定全路径

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

2.18.3 指定链接多个库

target_link_libraries(demo

${CMAKE_CURRENT_SOURCE_DIR}/libs/libface.a

boost_system.a

boost_thread

pthread)

2.19 设置变量

2.19.1 set直接设置变量的值

set(SRC_LIST main.cpp test.cpp) # 两个cpp文件,存储在变量SRC_LIST中

add_executable(demo ${SRC_LIST})

2.19.2 set追加设置变量的值

set(SRC_LIST main.cpp)

set(SRC_LIST ${SRC_LIST} test.cpp)

add_executable(demo ${SRC_LIST})

2.19.3 list追加或删除变量的值

set(SRC_LIST main.cpp)

list(APPEND SRC_LIST test.cpp)

list(REMOVE_ITEM SRC_LIST main.cpp)

add_executable(demo ${SRC_LIST})

2.110 条件控制

2.110.1 if…elseif…else…endif

逻辑判断和比较:

if (expression):expression 不为空(0,N,NO,OFF,FALSE,NOTFOUND)时为真

if (not exp):与上面相反

if (var1 AND var2)

if (var1 OR var2)

if (COMMAND cmd):如果 cmd 确实是命令并可调用为真

if (EXISTS dir) if (EXISTS file):如果目录或文件存在为真

if (file1 IS_NEWER_THAN file2):当 file1 比 file2 新,或 file1/file2 中有一个不存在时为真,文件名需使用全路径

if (IS_DIRECTORY dir):当 dir 是目录时为真

if (DEFINED var):如果变量被定义为真

if (var MATCHES regex):给定的变量或者字符串能够匹配正则表达式 regex 时为真,此处 var 可以用 var 名,也可以用 ${var}

if (string MATCHES regex)

数字比较:

if (variable LESS number):LESS 小于

if (string LESS number)

if (variable GREATER number):GREATER 大于

if (string GREATER number)

if (variable EQUAL number):EQUAL 等于

if (string EQUAL number)

字母表顺序比较:

if (variable STRLESS string)

if (string STRLESS string)

if (variable STRGREATER string)

if (string STRGREATER string)

if (variable STREQUAL string)

if (string STREQUAL string)

2.1100.2 while .. endwhile

while(condition)

...

endwhile()

2.110.3 foreach…endforeach

foreach(loop_var RANGE start stop [step])

...

endforeach(loop_var)

foreach(i RANGE 1 9 2) # 从1到9,步长为2

message(${i})

endforeach(i)

# 输出:13579

2.111 打印信息

message(${PROJECT_SOURCE_DIR})

message("build with debug mode")

message(WARNING "this is warnning message")

message(FATAL_ERROR "this build has many error") # FATAL_ERROR 会导致编译失败

2.112 包含其他cmake文件

include(./common.cmake) # 指定包含文件的全路径

include(def) # 在搜索路径中搜索def.cmake文件

set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # 设置include的搜索路径

2.2 常用变量

2.21 预定义变量

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 的完整路径

CMAKE_CURRENT_LIST_LINE:当前所在的行

CMAKE_MODULE_PATH:定义自己的 cmake 模块所在的路径,SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake),然后可以用INCLUDE命令来调用自己的模块

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

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

2.22 环境变量

使用环境变量

$ENV{Name}

写入环境变量

set(ENV{Name} value) # 这里没有“$”符号

2.23 系统变量

CMAKE_MAJOR_VERSION:cmake 主版本号,比如 3.4.1 中的 3

­CMAKE_MINOR_VERSION:cmake 次版本号,比如 3.4.1 中的 4

­CMAKE_PATCH_VERSION:cmake 补丁等级,比如 3.4.1 中的 1

­CMAKE_SYSTEM:系统名称,比如 Linux-­2.6.22

­CMAKE_SYSTEM_NAME:不包含版本的系统名,比如 Linux

­CMAKE_SYSTEM_VERSION:系统版本,比如 2.6.22

­CMAKE_SYSTEM_PROCESSOR:处理器名称,比如 i686

­UNIX:在所有的类 UNIX 平台下该值为 TRUE,包括 OS X 和 cygwin

­WIN32:在所有的 win32 平台下该值为 TRUE,包括 cygwin

2.24 主要开关选项

BUILD_SHARED_LIBS:这个开关用来控制默认的库编译方式,如果不进行设置,使用 add_library 又没有指定库类型的情况下,默认编译生成的库都是静态库。如果 set(BUILD_SHARED_LIBS ON) 后,默认生成的为动态库

CMAKE_C_FLAGS:设置 C 编译选项,也可以通过指令 add_definitions() 添加

CMAKE_CXX_FLAGS:设置 C++ 编译选项,也可以通过指令 add_definitions() 添加

add_definitions(-DENABLE_DEBUG -DABC) # 参数之间用空格分隔

3 实例搞起

3.1 单个源文件

cmaketest1.zip

以一段简单C程序为例

#include <stdio.h>

int main() {

printf("某程序员退休后决定练习书法,于是重金购买文房四宝。一日,饭后突生雅兴,一番研墨拟纸,并点上上好檀香。定神片刻,泼墨挥毫,郑重地写下一行字:\n");

printf("Hello World!\n");

return 0;

}

新建文件 CMakeLists.txt(命名必须是 CMakeLists.txt,注意大小写和不要漏字母)

编译可执行文件

project(HELLO)

add_executable(hello test.c) # 生成可执行文件

#add_library(common STATIC test.c) # 生成静态库

#add_library(common SHARED test.c) # 生成动态库或共享库

直接在当前文件夹执行cmake ..

弹出提示

 原来这个命令会去上级目录找CMakeLists.txt

一般会新建一个build目录,cd到build目录

先执行cmake ..

再执行make

 可以看到在build目录中产出了可执行文件,并且能执行成功

编译静态库

project(HELLO)

#add_executable(hello test.c) # 生成可执行文件

add_library(common STATIC test.c) # 生成静态库

#add_library(common SHARED test.c) # 生成动态库或共享库

编译动态库

project(HELLO)

#add_executable(hello test.c) # 生成可执行文件

#add_library(common STATIC test.c) # 生成静态库

add_library(common SHARED test.c) # 生成动态库或共享库

但是发现编译出来的是Mac下的动态库文件格式,dylib

如何才能编译出来so格式的动态库呢,需要把CMAKE_SYSTEM_NAME设置为Android

set(CMAKE_SYSTEM_NAME Android)

set(CMAKE_ANDROID_NDK "/Users/guozhenqian/Develop/android-ndk-r22b")

set(CMAKE_TOOLCHAIN_FILE "/Users/guozhenqian/Develop/android-ndk-r22b/build/cmake/android.toolchain.cmake")

set(ANDROID_TOOLCHAIN clang)

set(ANDROID_NATIVE_API_LEVEL 14)

set(ANDROID_ABI "armeabi-v7a")

set(CMAKE_BUILD_TYPE Release)

set(CMAKE_CROSSCOMPILING "TRUE")

set(CMAKE_CXX_STANDARD 11) #c++标准

project(HELLO)

#add_executable(hello test.c) # 生成可执行文件

#add_library(common STATIC test.c) # 生成静态库

add_library(common SHARED test.c) # 生成动态库或共享库

3.2 复杂项目(多个目录,多个源文件,多个项目)

关于多目录+自定义编译选项的,参考这篇文章足够了

CMake入门-04-自定义编译选项_binglingziyu的博客-CSDN博客_cmake 自定义选项

但是这篇文章有个错误的地方,导致自定义编译选项不生效

option一定要在configure_file之前定义

cmaketest_3.zip

cmake_minimum_required(VERSION 3.15.0)

# 项目名

project(hello)

# 查找当前目录下的所有源文件,并将名称保存到 SRC_LIST 变量

aux_source_directory(. SRC_LIST)

# 是否使用自己的 MathFunctions 库

# 这里设置的变量 USE_MYMATH、中间的提示文字、默认值,在 ccmake 命令中会展示

# 这个option一定要在configure_file之前,不然生成的config.h文件默认是没有define的

option (USE_MYMATH

"Use provided math implementation"

ON

)

# 加入一个配置头文件,用于处理 CMake 对源码的设置

configure_file (

"${PROJECT_SOURCE_DIR}/config.h.in"

"${PROJECT_SOURCE_DIR}/config.h"

)

# 是否加入 MathFunctions 库

if (USE_MYMATH)

# 添加头文件路径

include_directories ("${PROJECT_SOURCE_DIR}/math")

# 添加 math 子目录 (math 目录里必须有 CMakeLists.txt)

add_subdirectory (math)

set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)

endif (USE_MYMATH)

# 指定生成目标

add_executable(hello ${SRC_LIST} ${MATH_SRC_LIST})

# 添加链接库

target_link_libraries(hello ${EXTRA_LIBS})

3.3 复杂项目编译动态库

在cmaketest_3的基础上升级,编译出来动态库

cmaketest_4.zip

cmake_minimum_required(VERSION 3.15.0)

# 设置Android环境

set(CMAKE_SYSTEM_NAME Android)

set(CMAKE_ANDROID_NDK "/Users/guozhenqian/Develop/android-ndk-r22b")

set(CMAKE_TOOLCHAIN_FILE "/Users/guozhenqian/Develop/android-ndk-r22b/build/cmake/android.toolchain.cmake")

set(ANDROID_TOOLCHAIN clang)

set(ANDROID_NATIVE_API_LEVEL 14)

set(ANDROID_ABI "armeabi-v7a")

set(CMAKE_BUILD_TYPE Release)

set(CMAKE_CROSSCOMPILING "TRUE")

set(CMAKE_CXX_STANDARD 11) #c++标准

# 项目名

project(hello)

# 查找当前目录下的所有源文件,并将名称保存到 SRC_LIST 变量

aux_source_directory(. SRC_LIST)

# 打印一下SRC_LIST的值看看

MESSAGE( STATUS "SRC_LIST contains = ${SRC_LIST}")

# 查找 math 目录下的所有源文件,并将名称保存到 MATH_SRC_LIST 变量

# aux_source_directory(${PROJECT_SOURCE_DIR}/math MATH_SRC_LIST)

# 是否使用自己的 MathFunctions 库

# 这里设置的变量 USE_MYMATH、中间的提示文字、默认值,在 ccmake 命令中会展示

# 这个option一定要在configure_file之前,不然生成的config.h文件默认是没有define的

option (

USE_MYMATH "Use provided math implementation" ON

)

# 加入一个配置头文件,用于处理 CMake 对源码的设置

configure_file (

"${PROJECT_SOURCE_DIR}/config.h.in"

"${PROJECT_SOURCE_DIR}/config.h"

)

# 是否加入 MathFunctions 库

if (USE_MYMATH)

# 添加头文件路径

include_directories ("${PROJECT_SOURCE_DIR}/math")

# 添加 math 子目录 (math 目录里必须有 CMakeLists.txt)

add_subdirectory (math)

# 把MathFunctions追加设置到EXTRA_LIBS变量中

set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)

MESSAGE( STATUS "EXTRA_LIBS contains = ${EXTRA_LIBS}")

endif (USE_MYMATH)

# 生成动态库

add_library(hello SHARED ${SRC_LIST})

# 添加链接库

target_link_libraries(hello ${EXTRA_LIBS})

码字不易,如果对您有帮助,还请赏个赞哇!

参考文章:

1、cmake, make, CMakeLists.txt, Makefile简介 cmake, make, CMakeLists.txt, Makefile简介_Northan的博客-CSDN博客_cmakelists.txt makefile

2、Makefile和CMakefiles.txt的那些事儿 https://www.jianshu.com/p/f51adf8430f0

3、CMakeLists.txt 语法介绍与实例演练(最后一个例子有问题) CMakeLists.txt 语法介绍与实例演练_阿飞__的博客-CSDN博客_cmakelist

4、cmake学习4--自定义编译选项 cmake学习4--自定义编译选项_小珊瑚的爸爸的博客-CSDN博客

5、CMake入门实战(这篇才正宗,别的都是抄的吧)CMake&CMakeList.txt

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CMake&CMakeList.txt 的相关文章

随机推荐

  • 粒子滤波方法入门

    例子滤波方法入门 xff1a 分析典型非线性系统数学模型 主要内容 xff1a 1 非线性数学模型 2 用粒子滤波的MATLAB程序简介 1 非线性数学模型 2 用粒子滤波的MATLAB程序简介 function output args 6
  • 关于VIO中IMU预积分的讲解

    Why VIO 转自 xff1a https zhehangt github io 2019 03 23 SLAM Basic VIOInit 首先我们先简单回顾一下为什么要做VIO xff0c 以及为什么要做VIO初始化 我们知道单目相机
  • 线程互斥量死锁,与sleep没有关联

    文章目录 死锁问题死锁原因产生死锁的几个常见场景死锁产生的四个必要条件 61 61 仅供参考互斥条件占有和等待条件不可抢占条件环路等待条件 pthread mutex lock 线程互斥量死锁 与sleep没有关联 项目上 定位死锁原因 无
  • linux下,应用程序中的全局变量与so库中的全局变量名冲突,怎么办?

    文章目录 Wl Bsymbolic 动态库与应用 如果存在同名全局变量 会如何 实现了一个动态库 xff0c 封装了一些方法 然后基于这个动态库 xff0c 实现了一个应用程序 应用程序中含有全局变量A xff0c 动态库中也含有全局变量A
  • 内存管理:分页,分段,段页结合

    内存管理 xff1a 分页 xff0c 分段 xff0c 段页结合
  • STM32 SPI 收发数据 ---规则 + 问题解析

    规则 xff1a 1 xff09 高速同步串行口 3 xff5e 4线接口 xff08 CS xff0c CLK xff0c MOSI xff0c MISO xff09 xff0c 收发独立 可同步进行 2 xff09 SPI分为主从模式
  • gazebo: ROS Control的仿真教程

    gazebo 43 ROS control 1 预备知识2 数据流3 实现动态避障的环境构建 本文主要介绍如何为仿真机器人做控制器的仿真 通过仿真控制器 xff0c 控制机器人的对应关节 1 预备知识 关于gazebo中机器人的仿真 xff
  • NuttX实时操作系统

    NuttX 是一个实时操作系统 RTOS xff0c 其重点遵从特定的标准并且尽量小型化 可伸缩良好且可适应从8位到32位单片机环境 xff0c Nuttx主要遵循的标准是 Posix和ANSI标准 其他的一些来自于Unix或者其他常规的实
  • STM32 CAN 配置、收发结构定义 留存...

    分布式系统项目需要 xff0c 这次弄个CAN总线来布局 xff0c 仅见CAN的冰山一角 本次使用扩展帧模式 STM32 对CAN的定义 库 CAN结构体定义 说明 xff1a 寄存器映射 xff1a typedef span class
  • cortex-M3 的SVC、PendSV异常,与操作系统(ucos实时系统)

    文章目录 SVC和PendSVSVC xff1a PendSV xff1a 操作系统 xff0c 上下文切换 实例 xff1a ucos 关于 PendSV 异常的应用 上下文切换时机 怎样满足实时性 xff1a 中断 异常处理通用模板 x
  • STM32+IAP方案 实现网络升级应用固件

    关注了这个概念有些日子了 xff0c 这段时间总算有机会实战 61 61 网络升级应用固件 xff0c 这里记录下遇到的问题 xff0c 及解决方案 原理与网上流传的串口作为传输手段 一致 xff1b 不同之处 xff0c 无非我这里使用了
  • IAR版本不兼容导致无法正常打开工程文件--解决方法

    嵌入式开发 学习过程中 xff0c 难免需要借鉴别人的工程 xff0c 但是开发环境的匹配始终是个问题 61 61 版本不匹配 无法正常的打开工程文件 一般官方标配的开发环境包括 xff1a MDKIAR 这里描述IAR环境下 xff0c
  • STM32中GPIO的8种工作模式

    概念解释 xff1a 复用功能 xff1a 即片内外设 xff0c 包括UART SPI CAN I2C等等 xff0c 开启这些外设的功能 xff0c 就是使用了系统的复用功能 复用功能有两种 xff1a 没有重映像 重映像 xff08
  • 再读 ucosII源码(邵贝贝):任务之间的通讯与同步--邮箱

    邮箱简介 xff1a 邮箱是 C OS II中另一种通讯机制 xff0c 它可以使一个任务或者中断服务子程序向另一个任务发送一个指针型的变量 该指针指向一个包含了特定 消息 的数据结构 为了在 C OS II中使用邮箱 xff0c 必须将O
  • 阿里云ubuntu 16.04安装图形界面

    1 VNC的安装与配置 安装之前先输入 span class pln apt span span class pun span span class kwd span class hljs keyword get span span spa
  • cmake/makefile 获取git版本信息并传入源码输出

    CMake获取git commitId CMakeLists txt cmake minimum required VERSION 2 8 project test set SRCS main cpp 执行git命令 xff0c 并把结果重
  • 为什么使用static的类方法不需要new

    文章目录 JAVA加载过程static静态成员从static学习java编译过程JVM加载顺序摘要 xff1a 稍稍延申一下 xff1a 对于此java给出了两个解决方案 xff1a 总结static下面说说静态的特点 xff1a 实例变量
  • CMake引入三方库

    做移动端的NDK开发经常需要引入三方库 xff0c 本文以常见的JSON库为例进行说明 jsoncpp源码下载地址https github com open source parsers jsoncpp 下载1 9 5的tag 1 纯源码依
  • C++中泛型算法详解5:面向泛型算法的迭代器类别

    前言 任何算法最基本的特性是要求迭代器提供那些操作 根据算法要求的迭代器操作 xff0c 可以分为如下迭代器类别 xff1a 1 input iterator 2 output iterator 3 forward iterator 4 b
  • CMake&CMakeList.txt

    1 各种关系 在各种开源项目中 xff0c 经常会发现项目中除了代码源文件 xff0c 还包含了 CMakeList txt Makefile 文件 xff0c 在项目的编译时候需要用到的命令有 cmake make 我们本次想搞清楚他们之