3.编写CMakeLists文件

2023-05-16

本章将介绍为您的软件编写有效的 CMakeLists 文件的基础知识。它将涵盖处理大多数项目所需的基本命令和问题。虽然 CMake 可以处理极其复杂的项目,但对于大多数项目,你会发现本章的内容会告诉你所有你需要知道的。CMake 由为软件项目编写的 CMakeLists.txt 文件驱动。CMakeLists 文件确定从向用户呈现哪些选项到要编译哪些源文件的所有内容。除了讨论如何编写 CMakeLists 文件之外,本章还将介绍如何使它们变得健壮和可维护。

编写CMakeLists文件

CMakeLists 文件几乎可以在任何文本编辑器中进行编辑。一些编辑器,例如 Notepad++,内置了 CMake 语法高亮和缩进支持。对于 Emacs 或 Vim 等编辑器,CMake 包括缩进和语法高亮模式。这些可以在Auxiliary源代码分发的目录中找到,或者从 CMake下载页面下载。
在任何受支持的生成器(Makefile、Visual Studio 等)中,如果您编辑 CMakeLists 文件并重新构建,则有一些规则会根据需要自动调用 CMake 来更新生成的文件(例如 Makefile 或项目文件)。这有助于确保您生成的文件始终与您的 CMakeLists 文件同步。

CMake语言

CMake 语言由注释、命令和变量组成。

注释

注释从#开始并一直运行到行尾。见 cmake-language手册了解更多详情。

变量

CMakeLists 文件使用变量很像任何编程语言。CMake 变量名称区分大小写,并且只能包含字母数字字符和下划线。
许多有用的变量由 CMake 自动定义,并在 cmake-variables手动的。这些变量以CMAKE_. 对于特定于您的项目的变量,请避免使用这种命名约定(理想情况下,建立您自己的命名约定)
尽管有时可能将它们解释为其他类型,但所有 CMake 变量都在内部存储为字符串。
使用set命令来设置变量值。以最简单的形式,第一个参数set是变量的名称,其余参数是值。多个值参数被打包到分号分隔的列表中,并作为字符串存储在变量中。例如:

set(Foo "")      # 1 quoted arg -> value is ""
set(Foo a)       # 1 unquoted arg -> value is "a"
set(Foo "a b c") # 1 quoted arg -> value is "a b c"
set(Foo a b c)   # 3 unquoted args -> value is "a;b;c"

可以使用语法 ${VAR}在命令中引用变量,其中VAR是变量名。如果未定义命名变量,则将引用替换为空字符串;否则它被变量的值替换。替换是在扩展未引用的参数之前执行的,因此包含分号的变量值被拆分为零个或多个参数来代替原始的未引用参数。例如:

set(Foo a b c)    # 3 unquoted args -> value is "a;b;c"
command(${Foo})   # unquoted arg replaced by a;b;c
                  # and expands to three arguments
command("${Foo}") # quoted arg value is "a;b;c"
set(Foo "")       # 1 quoted arg -> value is empty string
command(${Foo})   # unquoted arg replaced by empty string
                  # and expands to zero arguments
command("${Foo}") # quoted arg value is empty string

系统环境变量和 Windows 注册表值可以直接在 CMake 中访问。要访问系统环境变量,请使用语法$ENV{VAR}. CMake 还可以使用表单语法在许多命令中引用注册表项 [HKEY_CURRENT_USER\Software\path1\path2;key],其中路径是从注册表树和键构建的。

变量范围

CMake 中的变量的作用域与大多数语言略有不同。设置变量时,当前 CMakeLists 文件或函数以及任何子目录的 CMakeLists 文件、调用的任何函数或宏以及使用include命令。当处理一个新的子目录(或调用一个函数)时,会创建一个新的变量范围,并使用调用范围内所有变量的当前值进行初始化。在子作用域中创建的任何新变量或对现有变量所做的更改都不会影响父作用域。考虑以下示例

function(foo)
  message(${test}) # test is 1 here
  set(test 2)
  message(${test}) # test is 2 here, but only in this scope
endfunction()

set(test 1)
foo()
message(${test}) # test will still be 1 here

在某些情况下,您可能希望函数或子目录在其父范围内设置变量。CMake 有一种方法可以从函数返回值,可以通过使用 PARENT_SCOPE带有set命令。我们可以修改前面的示例,以便该函数foo在其父范围内更改 test 的值,如下所示:

function(foo)
  message(${test}) # test is 1 here
  set(test 2 PARENT_SCOPE)
  message(${test}) # test still 1 in this scope
endfunction()

set(test 1)
foo()
message(${test}) # test will now be 2 here

CMake中的变量是按照执行顺序定义的 set命令。
考虑以下示例:

# FOO is undefined

set(FOO 1)
# FOO is now set to 1

set(FOO 0)
# FOO is now set to 0

要了解变量的范围,请考虑以下示例:

set(foo 1)

# process the dir1 subdirectory
add_subdirectory(dir1)

# include and process the commands in file1.cmake
include(file1.cmake)

set(bar 2)
# process the dir2 subdirectory
add_subdirectory(dir2)

# include and process the commands in file2.cmake
include(file2.cmake)

在这个例子中,因为变量foo是在开头定义的,所以在处理 dir1 和 dir2 时都会定义它。相反,bar只会在处理dir2时定义。同样, foo将在处理 file1.cmake 和 file2.cmake 时定义,而bar仅在处理 file2.cmake 时定义。这个例子有点神奇呀,可以细细的考虑一下

命令

命令由命令名称、左括号、空格分隔的参数和右括号组成。每个命令都按照它在 CMakeLists 文件中出现的顺序进行评估。见 cmake-commands手册以获取 CMake 命令的完整列表。
CMake 不再对命令名称区分大小写,因此在您看到command的地方,您可以使用COMMAND或是Command代替。使用小写命令被认为是最佳实践。除了分隔参数外,所有空格(空格、换行符、制表符)都将被忽略。因此,只要命令名称和左括号在同一行,命令就可以跨越多行。
CMake 命令参数以空格分隔且区分大小写。命令参数可以被引用或不被引用。带引号的参数以双引号 (") 开始和结束,并且始终只表示一个参数。值中包含的任何双引号都必须使用反斜杠进行转义。考虑对需要转义的参数使用方括号参数,请参阅 cmake-language手动的。不带引号的参数以双引号以外的任何字符开头(后来的双引号是文字),并通过在值中用分号分隔来自动扩展为零个或多个参数。例如:

command("")          # 1 quoted argument
command("a b c")     # 1 quoted argument
command("a;b;c")     # 1 quoted argument
command("a" "b" "c") # 3 quoted arguments
command(a b c)       # 3 unquoted arguments
command(a;b;c)       # 1 unquoted argument expands to 3

基本命令

正如我们在前面看到的,set和unset命令显式设置或取消设置变量。string,list和 separate_arguments命令提供对字符串和列表的基本操作。
add_executable和add_library命令是用于定义要构建的可执行文件和库的主要命令,以及包含它们的源文件。对于 Visual Studio 项目,源文件将照常显示在 IDE 中,但项目使用的任何头文件都不会显示。要显示头文件,只需将它们添加到可执行文件或库的源文件列表中即可;这可以为所有发电机完成。任何不直接使用头文件的生成器(例如基于 Makefile 的生成器)将简单地忽略它们。

流的控制

CMake 语言提供了三种流控制结构来帮助组织您的 CMakeLists 文件并保持它们的可维护性。

  • 条件语句(例如if)
  • 循环结构(例如foreach和while)
  • 程序定义(例如macro和function)

条件语句

首先,我们将考虑if命令。在许多方面, if在CMake 中的命令就像if任何其他语言的命令。它评估其表达式并使用它来执行其主体中的代码或可选地执行else条款。例如:

if(FOO)
  # do something here
else()
  # do something else
endif()

CMake 还支持elseif帮助顺序测试多个条件。例如

if(MSVC80)
  # do something here
elseif(MSVC90)
  # do something else
elseif(APPLE)
  # do something else
endif()

if命令记录了它可以测试的许多条件,在documentation中找到。

循环语句

foreach和while命令允许您处理按顺序发生的重复性任务。break命令从一个foreach或者while在它正常结束之前循环。
foreach命令使您能够对列表的成员重复执行一组 CMake 命令。考虑以下改编自 VTK 的示例

foreach(tfile
        TestAnisotropicDiffusion2D
        TestButterworthLowPass
        TestButterworthHighPass
        TestCityBlockDistance
        TestConvolve
        )
  add_test(${tfile}-image ${VTK_EXECUTABLE}
    ${VTK_SOURCE_DIR}/Tests/rtImageTest.tcl
    ${VTK_SOURCE_DIR}/Tests/${tfile}.tcl
    -D ${VTK_DATA_ROOT}
    -V Baseline/Imaging/${tfile}.png
    -A ${VTK_SOURCE_DIR}/Wrapping/Tcl
    )
endforeach()

foreach命令的第一个参数是循环变量的名称,它将在循环的每次迭代中采用不同的值;其余参数是循环的值列表。在本个示例当中,foreach命令的循环主体为一个add_test的命令。在foreach主体中,每次tfile引用循环变量(在此示例中)时,都将替换为列表中的当前值。在第一次迭代中,出现的 t f i l e 将替换为 T e s t A n i s o t r o p i c D i f f u s i o n 2 D 。在下一次迭代中, {tfile}将替换为 TestAnisotropicDiffusion2D。在下一次迭代中, tfile将替换为TestAnisotropicDiffusion2D。在下一次迭代中,{tfile} 将替换为TestButterworthLowPass.这foreach循环将继续循环,直到处理完所有参数。
值得一提的是foreach循环可以嵌套,并且循环变量在任何其他变量扩展之前被替换。这意味着在foreach循环一个主体中,您可以使用循环变量构造变量名称。在下面的代码中,循环变量tfile被展开,然后与 _TEST_RESULT串联. 然后扩展新变量名并测试它是否匹配FAILED

if(${${tfile}}_TEST_RESULT} MATCHES FAILED)
  message("Test ${tfile} failed.")
endif()

while命令提供基于测试条件的循环。测试表达式的格式while命令是一样的if命令,如前所述。考虑以下 CTest 使用的示例。请注意,CTest 会在 CTEST_ELAPSED_TIME内部更新值

#####################################################
# run paraview and ctest test dashboards for 6 hours
#
while(${CTEST_ELAPSED_TIME} LESS 36000)
  set(START_TIME ${CTEST_ELAPSED_TIME})
  ctest_run_script("dash1_ParaView_vs71continuous.cmake")
  ctest_run_script("dash1_cmake_vs71continuous.cmake")
endwhile()

程序(函数)定义

这macro和function命令支持可能分散在 CMakeLists 文件中的重复性任务。一旦定义了宏或函数,它就可以被定义后处理的任何 CMakeLists 文件使用。
CMake 中的函数非常类似于 C 或 C++ 中的函数。您可以将参数传递给它,它们将成为函数中的变量。同样,定义了一些标准变量,如ARGC、 ARGV、ARGN和ARGV0、ARGV1等。函数调用具有动态范围。在一个函数中,您处于一个新的变量范围内;这就像你如何使用add_subdirectory命令并且在一个新的变量范围内。调用函数时定义的所有变量都保持定义,但对变量或新变量的任何更改仅存在于函数内。当函数返回时,这些变量将消失。更简单地说:当您调用一个函数时,会推送一个新的变量范围;当它返回时,该变量范围被弹出。
function命令 定义了一个新函数。第一个参数是要定义的函数的名称;所有附加参数都是函数的形式参数。

function(DetermineTime _time)
  # pass the result up to whatever invoked this
  set(${_time} "1:23:45" PARENT_SCOPE)
endfunction()

# now use the function we just defined
DetermineTime(current_time)

if(DEFINED current_time)
  message(STATUS "The time is now: ${current_time}")
endif()

注意在本例中,_time用于传递返回变量的名称。这set使用 的值调用命令 _time,这将是current_time。最后,set 命令使用该PARENT_SCOPE选项在调用者的范围内而不是本地范围内设置变量。
宏的定义和调用方式与函数相同。主要区别在于宏不会推送和弹出新的变量范围,并且宏的参数不被视为变量,而是在执行之前被替换为字符串。这非常类似于 C 或 C++ 中宏和函数之间的区别。第一个参数是要创建的宏的名称;所有附加参数都是宏的形式参数。

# define a simple macro
macro(assert TEST COMMENT)
  if(NOT ${TEST})
    message("Assertion failed: ${COMMENT}")
  endif()
endmacro()

# use the macro
find_library(FOO_LIB foo /usr/local/lib)
assert(${FOO_LIB} "Unable to find library foo")

上面的简单示例创建了一个名为assert. 宏定义为两个参数;第一个是要测试的值,第二个是测试失败时要打印的注释。宏的主体很简单if命令与message里面的命令。宏主体结束时endmacro找到命令。可以简单地通过使用它的名称来调用宏,就好像它是一个命令一样。在上面的示例中,如果FOO_LIB未找到,则会显示一条消息,指示错误情况。
这macro命令还支持定义采用可变参数列表的宏。如果您要定义具有可选参数或多个签名的宏,这可能很有用。ARGC可以使用and ARGV0,等来引用变量参数ARGV1,而不是形式参数。ARGV0表示宏的第一个参数;ARGV1代表下一个,依此类推。您还可以混合使用形式参数和可变参数,如下例所示。

# define a macro that takes at least two arguments
# (the formal arguments) plus an optional third argument
macro(assert TEST COMMENT)
  if(NOT ${TEST})
    message("Assertion failed: ${COMMENT}")

    # if called with three arguments then also write the
    # message to a file specified as the third argument
    if(${ARGC} MATCHES 3)
      file(APPEND ${ARGV2} "Assertion failed: ${COMMENT}")
    endif()

  endif()
endmacro()

# use the macro
find_library(FOO_LIB foo /usr/local/lib)
assert(${FOO_LIB} "Unable to find library foo")

在此示例中,两个必需的参数是TEST和 COMMENT。这些必需的参数可以通过名称来引用,就像在本例中一样,也可以通过引用ARGV0and 来引用ARGV1。如果要将参数作为列表处理,请使用 ARGV和ARGN变量。ARGV(与 , 等相反ARGV0) ARGV1是宏 ARGN的所有参数的列表,而是形式参数之后的所有参数的列表。在您的宏中,您可以使用foreach命令迭代ARGV或ARGN根据需要。
return命令从函数、目录或文件返回。请注意,与函数不同,宏是在原地展开的,因此无法处理return.

正则的表达

一些 CMake 命令,例如if和string, 使用正则表达式或可以将正则表达式作为参数。在最简单的形式中,正则表达式是用于搜索精确字符匹配的字符序列。但是,很多时候要找到的确切序列是未知的,或者只需要在字符串的开头或结尾进行匹配。由于指定正则表达式有几种不同的约定,因此 CMake 的标准在string命令文档。该描述基于 Texas Instruments 的开源正则表达式类,CMake 使用该类来解析正则表达式。

高级命令

有一些命令可能非常有用,但通常不用于编写 CMakeLists 文件。本节将讨论其中一些命令以及它们何时有用。
首先,考虑add_dependencies在两个目标之间创建依赖关系的命令。当 CMake 可以确定目标时,它会自动创建目标之间的依赖关系。例如,CMake 将自动为依赖于库目标的可执行目标创建依赖关系。add_dependencies命令通常用于指定目标之间的目标间依赖关系,其中至少一个目标是自定义目标(请参阅添加自定义命令部分)
include_regular_expression命令也与依赖关系有关。此命令控制用于跟踪源代码依赖关系的正则表达式。默认情况下,CMake 将跟踪源文件的所有依赖项,包括系统文件,例如stdio.h. 如果您使用 include_regular_expression命令,该正则表达式将用于限制处理哪些包含文件。例如; 如果您的软件项目的包含文件都以前缀 foo 开头(例如,等),您可以指定正则表达式 of以将依赖项检查限制为仅对项目的文件进行检查。

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

3.编写CMakeLists文件 的相关文章

  • CMakeLists中目录含空格导致报警【Invalid character escape】的解决方案

    如题所述 xff0c CMakeLists中目录含空格导致报警Invalid character escape x CMakeLists的问题写法 xff1a 解决方案 xff1a 只需将路径使用双引号引起来即可解决问题 参考链接 xff1
  • PX4 CMakeLists.txt 文件剖析

    PX4 CMakeLists txt 文件剖析 前面对于 PX4 的 Makefile 已经做了比较详细的分析 见这里 这里进一步对 PX4 的 CMakeLists txt 文件结构进行进一步的分析 1 CMake 简述 CMake 是一
  • CMake中CMakeLists文件的编写以及变量打印

    最近在学习PCL xff0c 在Win10下使用VS编写PCL程序 xff0c 配置环境时经常出错 xff0c 踩坑记录详见 xff1a Win10 43 VS2017 43 PCL 1 8 1软件安装 踩坑记录 看到 点云库PCL从入门到
  • ROS CmakeLists.txt解读

    CMakeLists txt原本是Cmake编译系统的规则文件 xff0c 而Catkin编译系统基本沿用了CMake的编译风格 xff0c 只是针对ROS工程添加了一些宏定义 所以在写法上 xff0c catkin的CMakeLists
  • CMakeLists.txt书写规则记录

    编写自己的CMakeLists txt 1 一个CMakeLists txt的基本内容2 项目包含多个文件或文件夹时添加方式3 添加链接库 1 一个CMakeLists txt的基本内容 span class token comment 编
  • CMakeLists

    1 指定 cmake 的最小版本 cmake minimum required VERSION 3 4 1 2 设置项目名称 xff0c 它会引入两个变量 demo BINARY DIR 和 demo SOURCE DIR xff0c 同时
  • 2022-12-18 CMakelists指定CMAKE_BUILD_TYPE为Debug或者Release

    今天编译代码的时候遇到古怪的事情 xff0c 在Cmakelists txt中指定了编译版本 xff0c build的时候输出一句 xff1a cpptools The build configurations generated do n
  • PX4 CMakeLists.txt分析

    简单的概述 make 和 cmake 是linux UNIX系统下广泛使用的构建编译规则工具 xff0c 面对复杂庞大的工程 xff0c 各种源文件和工具文件分布在工程目录下 xff0c 如何组织和有序地编译和使用这些文件 xff0c 显然
  • 一步一步学CMake 之 VSCode+CMakeLists 调试 C++ 工程

    目录 1 插件推荐 2 文件准备 3 开始调试 一步一步学 CMake 系列文章 1 插件推荐 CMake CMake tools 2 文件准备 新建文件夹 xff1a TEST 新建文件 xff1a CMakeLists txt 内容如下
  • px4的CMakelists.txt阅读

    1 2 3 Copyright c 2017 PX4 Development Team All rights reserved 4 5 Redistribution and use in source and binary forms wi
  • [ROS](03)CMakeLists.txt详解

    文章只是个人学习过程中学习笔记 xff0c 主要参考ROS教程1 目录 1 概述2 CMakeLists txt文件2 1 遵循的格式和顺序2 2 文件解析2 3 find package 2 4 catkin package 1 概述 C
  • ROS CMakeLists.txt中catkin_package和INCLUDE_DIRS的区别

    CMakeLists txt中 catkin package INCLUDE DIRS include 这里代表的是catkin的构建选项 xff0c INCLUDE DIRS表示将使用INCLUDE DIRS后面的内部目录include
  • cmake & CMakeLists.txt

    文章目录 前言先从体验开始1 一个最简单的例子 xff1a 2 例子升级 xff0c 将hello c生成为一个库 xff1a 3 例子升级 xff0c 将源代码和库分开放 xff1a 4 让可执行文件在 bin 目录 xff0c 库文件在
  • ORB_SLAM2 CMakeLIsts文件注释

    最近在学习ORB SLAM 发现基本找不到CMakeLists的代码注释 就决定自己注释一份 如果发现有问题的地方 欢迎和我交流 span class token function cmake minimum required span s
  • QT中CMakeLists添加第三方库

    1 新建项目 xff0c 打开CMakeLists txt文件 cmake minimum required VERSION 2 8 project fp test cm 括号内fp test cm为项目名称 add executable
  • Cmakelists配置多级目录的gtest项目(项目代码和测试代码分离)

    cmake一些语法定义 之前的博客主要写了怎么配置gtest项目 xff0c 但是一般项目代码和测试代码并不在一起 xff0c 所以尝试将代码分离 主要分成三个部分 xff0c 下面给出demo的分级目录 gtest demo CMakel
  • gcc、make、makefile、cmake、cmakelists区别

    转自 xff1a http www zhihu com question 36609459 辉常哥 1 gcc是GNU Compiler Collection xff08 就是GNU编译器套件 xff09 xff0c 也可以简单认为是编译器
  • CMakeLists.txt中FIND_PACKAGE()是如何工作的?

    官方文档 xff1a https cmake org cmake help latest command find package html FIND PACKAGE lt PackageName gt 如何查找头文件和库文件路径 xff1
  • 学习cmake的使用和CMakeLists.txt

    1 学习cmake的使用和CMakeLists txt 文章目录 1 学习cmake的使用和CMakeLists txt1 1 cmake外部构建基础1 2 让每个源文件目录都包含一个CMakeLists txt1 3 安装 1 4 构建静
  • CMake与CMakeLists是干什么的?

    写在最前面 xff1a 所有的博文都是为了若干年月以后当我再次翻看可以快速回想起之前的零星知识 学海无涯 xff0c 在看这篇文章的未来的你 xff0c 加油吧 xff01 因为之前看到有些软件中使用了CMake xff0c 不太理解为什么

随机推荐

  • Apollo 算法阅读之Public Road轨迹规划算法--路径规划(含源代码)

    本次博文主要介绍apollo 5 0版本内使用的轨迹规划算法 public road xff0c 该算法的核心思想是PV解耦 xff0c 即Path Velocity的解耦 xff0c 其主要包含两个过程 xff1a 1 路径规划 xff0
  • 交互式多模型 IMM的原理

    交互式多模型简单原理 交互式多模型 IMM xff08 Interacting Multiple Model xff09 控制算法的主体思想是基于贝叶斯理论而提出的模型间的自动识别与切换 xff1a 在任意跟踪时刻 xff0c 通过设置对应
  • Apollo算法阅读之基于Sqp的Referenceline全局参考路线优化(含源码)

    算法来源于Apollo代码 代码源地址 xff0c 通过序列优化思想 xff0c 建立无人驾驶车辆参考路径的平滑 xff0c 利用泰勒展开将曲率约束线性化表达 xff0c 目标函数中利用弹性带思想 xff0c 并尽可能缩短参考路径长度且保持
  • 离散点间曲率计算

    本文转自知乎计算离散点的曲率 xff08 附Python MATLAB代码 xff09 在很多学科中的很多计算任务中都需要用到曲线的曲率 xff08 或者曲率半径 xff09 xff0c numpy库里和matlab build in里都没
  • 关于Frenet坐标系内曲率约束

    本文摘自于apollo直播公开课 xff0c 因为车辆存在最小的转弯半径 xff0c 所以我们要对车辆运动学进行限制 由于转弯半径是基于笛卡尔坐标系的 xff0c 需要基于Frenet坐标系进行转换 假设 xff1a xff0c 车辆朝向与
  • caffe内CHECK_EQ等函数意义解释

    个人在学习caffe源码文件时遇到了CHECK EQ函数 xff0c 不理解什么含义 xff0c 经过上下文理解 xff0c 明白了其中含义 CHECK EQ x y lt lt 34 x 61 y 34 xff0c EQ即equation
  • 电路交换方式与分组交换方式计算题

    已知网络速率为1Mb S xff0c 对于每个用户来说 xff0c 有10 的时间是活跃的 xff0c 活跃时网速为100kb s 对于电路交换方式来说 xff0c 最多只能支持10位用户接入网络 由于1Mb 61 1000kb xff0c
  • Carla编译make launch过程中出现UE4_ROOT is not defined

    在编译carla过程中出现如下情况 xff1a BuildCarlaUE4 sh ERROR UE4 ROOT is not defined or points to a non existant directory please set
  • request 模块可以帮助我们发起http请求

    request 模块可以帮助我们发起http请求 步骤 xff1a 1 首先import 下 request 模块 2 然后看请求的方式 xff0c 选择对应的请求方法 3 接受返回的报文信息 有requests get requests
  • 自动提取论文公式方法

    需要的软件 MathType 7 Mathpix Snipping Tool 软件获取链接 xff1a 链接 xff1a https pan baidu com s 1Fz VGkgZJbZhlocL4y1AoA 提取码 xff1a ci0
  • 现代 CMake 简明教程--CMake 基础

    前言 用 CMake 来构建 C C 43 43 项目是业内的主流做法 最近 xff0c 我们的项目代码做了一些拆分和合并 xff1a 引入其他仓库代码 xff0c 并且将公共部分拆分以供多个仓库同时使用 为此 xff0c 就得修改项目中的
  • USB接线定义和链接摄像头

    原文链接 xff1a https www cnblogs com chinalantian articles 2131361 html 写本文的意义在于了解USB的接线定义和实现使用手机数据线读取摄像头图像 USB接口定义 颜色 一般的排列
  • C++小结 析构函数、函数后面接冒号 等等

    讲在前面 本小结有析构函数 C 43 43 函数后面接 xff1a 的含义 C 43 43 中public protected及private用法 条件运算符 fabs 和abs 区别 C 43 43 中的结构体内的函数 类中成员函数声明后
  • C++学习笔记:子类构造函数中冒号的使用 — 同时创建父类和子类对象

    C 43 43 中 xff0c 子类对象创建需要预先创建父类对象 xff0c 对象销毁顺序与此相反 假如父类构造函数只存在有参构造 xff0c 在子类对象实例化之前 xff0c 便需要创建一个父类对象 xff0c 在不存在默认无参构造情况下
  • C语言头文件详解

    1 include的作用 简单一句话 xff1a 在include的地方 xff0c 把头文件里的内容原封不动的复制到引用该头文件的地方 2 头文件的引用 头文件引用有两种形式 xff1a include lt stdio h gt 和 i
  • 字符数组进行复制需要加结束符‘\0’

    如想将str1数组内容复制到str2中 xff08 不用strcpy xff0c 如果按照以下格式复制 xff09 xff0c 需要加字符结束符 0 xff1b span class token macro property span cl
  • 学习Kafka

    1 Kafka是什么 xff1f 学习Kafka的目的 xff0c 为了解决高吞吐量项目的需求 xff0c Kafka号称大数据的杀手锏 xff0c 这款为大数据而生的消息中间件 xff0c 以其百亿级tps的吞吐量名声大噪 xff0c 迅
  • cmake命令之option使用案例

    option的命令形式如下 option lt variable gt 34 lt help text gt 34 value option简介 cmake中option起到编译开关的作用 xff0c CMakeLists txt中opti
  • docker学习

    现代软件开发的一大目的就是隔离 xff0c 应用程序在运行时相互独立互不干扰 xff0c 这种隔离实现起来是很不容易的 xff0c 其中一种解决方案就是上面提到的虚拟机技术 xff0c 通过将应用程序部署在不同的虚拟机中从而实现隔离 但是虚
  • 3.编写CMakeLists文件

    本章将介绍为您的软件编写有效的 CMakeLists 文件的基础知识 它将涵盖处理大多数项目所需的基本命令和问题 虽然 CMake 可以处理极其复杂的项目 xff0c 但对于大多数项目 xff0c 你会发现本章的内容会告诉你所有你需要知道的