CMake(十二):构建类型

2023-05-16

本章和下一章涉及两个密切相关的主题。构建类型(在某些IDE工具中也称为构建配置或构建方案)是一种高级控件,它选择不同的编译器和链接器行为集。构建类型的操作是本章的主题,而下一章将介绍控制编译器和链接器选项的更具体细节。总之,这些章节涵盖了除了最琐碎的项目外,每个CMake开发人员通常都会使用的材料。

12.1 构建基础类型

​ 构建类型有可能以某种方式影响与构建相关的几乎所有内容。虽然它主要对编译器和链接器的行为有直接影响,但它也对项目使用的目录结构有影响。这反过来又会影响开发人员如何设置他们自己的本地开发环境,因此构建类型的影响可能相当深远。

​ 开发人员通常认为构建是两种安排之一:调试或发布。对于调试构建,使用编译器标志来启用调试器可用于将机器指令与源代码关联的信息记录。在这样的构建中,通常会禁用优化,以便在逐步执行程序时,从机器指令到源代码位置的映射是直接的,并且很容易遵循。另一方面,发布版本通常启用了充分的优化,并且没有生成调试信息。

​ 这些是CMake所说的构建类型的例子。虽然项目可以定义他们想要的任何构建类型,但CMake提供的默认构建类型通常对大多数项目来说已经足够了:

  • Debug

    由于没有优化和完整的调试信息,这通常在开发和调试期间使用,因为它通常提供最快的构建时间和最佳的交互式调试体验。

  • Release

    这种构建类型通常快速的提供了充分的优化,并且没有调试信息,尽管一些平台在某些情况下仍然可能生成调试符号。它通常是为最终产品版本构建软件时使用的构建类型。

  • RelWithDebInfo

    这在某种程度上是前两者的折衷。它的目标是使性能接近于发布版本,但仍然允许一定程度的调试。通常应用大多数速度优化,但也启用了大多数调试功能。因此,当调试构建的性能甚至对调试会话来说都是不可接受的时,这种构建类型最有用。请注意,RelWithDebInfo的默认设置将禁用断言。

  • MinSizeRel

    这种构建类型通常只用于受限制的资源环境,如嵌入式设备。代码是针对大小而不是速度进行优化的,并且没有创建调试信息。每种构建类型都会产生一组不同的编译器和链接器标志。它还可能改变其他行为,比如改变编译的源文件或链接到的库。

(1)单一配置生成器

​ 回到“生成项目文件”,介绍了不同类型的项目生成器。有些,比如Makefiles和Ninja,每个构建目录只支持一种构建类型。对于这些生成器,必须通过设置CMAKE_BUILD_TYPE缓存变量来选择构建类型。例如,要用Ninja配置和构建一个项目,可以使用如下命令:

cmake -G Ninja -DCMAKE_BUILD_TYPE:STRING=Debug ../source
cmake --build .

​ CMAKE_BUILD_TYPE缓存变量也可以在CMake GUI应用程序中更改,而不是在命令行中更改,但最终效果是一样的。但是,一种替代策略是为每种构建类型设置单独的构建目录,而不是在不同的构建类型之间切换,所有的构建类型仍然使用相同的源。这样的目录结构可能看起来像这样:

image-20220114114607500

​ 如果频繁地在构建类型之间切换,这种安排可以避免仅仅因为编译器标志改变而不断地重新编译相同的源代码。它还允许单个配置生成器像多个配置生成器一样有效地运行,像Qt Creator这样的IDE环境支持在构建目录之间切换,就像Xcode或Visual Studio支持在构建方案或配置之间切换一样简单。

(2)多个配置生成器

​ 一些生成器,特别是Xcode和Visual Studio,支持在一个构建目录下的多个配置。这些生成器忽略CMAKE_BUILD_TYPE缓存变量,而是要求开发人员在IDE中选择构建类型,或者在构建时使用命令行选项。配置和构建这样的项目看起来像这样:

cmake -G Xcode ../source
cmake --build . --config Debug

​ 当在Xcode IDE中构建时,构建类型由构建方案控制,而在Visual Studio IDE中,当前解决方案配置控制构建类型。这两个环境都为不同的构建类型保留了单独的目录,因此在构建之间进行切换不会导致不断的重新构建。实际上,与上面描述的针对单个配置生成器的多构建目录安排一样,IDE只是代表开发人员处理目录结构。

12.2 常见的错误

​ 请注意,对于单个配置生成器,如何在配置时指定构建类型,而对于多个配置生成器,如何在构建时指定构建类型。这种区别非常重要,因为它意味着当CMake处理项目的CMakeLists.txt文件时,并不总是知道构建类型。考虑下面这段CMake代码,不幸的是,它相当常见,但演示了一个错误的模式:

# WARNING: Do not do this!
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
  # Do something only for debug builds
endif()

​ 上述方法适用于基于Makefile的生成器和Ninja,但不适用于Xcode或Visual Studio。在实践中,项目中几乎任何基于CMAKE_BUILD_TYPE的逻辑都是有问题的,除非它受到检查的保护,以确认正在使用单个配置生成器。对于多个配置生成器,这个变量可能是空的,但即使不是,它的值也应该被认为是不可靠的,因为构建将忽略它。而不是在CMakeLists.txt文件中引用CMAKE_BUILD_TYPE,项目应该使用其他更健壮的替代技术,例如基于 $<CONFIG:…>的生成器表达式。

mkdir build
cd build
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ../source
cmake --build . --config Release

​ 在上面的示例中,开发人员可以简单地更改-G参数所指定的生成器名称,脚本的其余部分将不受更改。

​ 不显式地为单个配置生成器设置CMAKE_BUILD_TYPE也是常见的,但通常不是开发人员想要的。如果没有设置CMAKE_BUILD_TYPE,单个配置生成器特有的行为则构建类型为空。这有时会引起一些开发人员的误解,认为空构建类型等同于Debug,但事实并非如此。空构建类型是它自己唯一的、无名称的构建类型。在这种情况下,不使用特定于配置的编译器或链接器标志,这通常只会导致调用带有最小标志的编译器和链接器,因此行为由编译器和链接器自己的默认行为决定。虽然这通常与Debug构建类型的行为类似,但绝不能保证。

12.3 自定义构建类型

​ 有时,项目可能希望将构建类型集限制为默认值的一个子集,或者希望添加其他具有特殊编译器和链接器标志集的定制构建类型。后者的一个很好的例子是为分析或代码覆盖添加构建类型,这两种类型都需要特定的编译器和链接器设置。

​ 开发人员可以在两个主要的地方看到构建类型集。当使用像Xcode和Visual Studio这样的多配置生成器时,IDE环境提供了一个下拉列表或类似的东西,开发人员可以从中选择他们想要构建的配置。对于像Makefiles或Ninja这样的单个配置生成器,构建类型是直接为CMAKE_BUILD_TYPE缓存变量输入的,但是CMake GUI应用程序可以显示一个有效选择的组合框,而不是简单的文本编辑字段。这两种情况背后的机制是不同的,因此必须分别处理。

​ 多配置生成器已知的构建类型集由CMAKE_CONFIGURATION_TYPES缓存变量控制,或者更准确地说,由该变量在处理顶级CMakeLists.txt文件结束时的值控制。第一个遇到的project()命令用一个默认列表填充缓存变量(如果还没有定义的话),但是项目可以在此之后修改同名的非缓存变量(修改缓存变量是不安全的,因为它可能会放弃开发人员所做的更改)。可以通过将自定义构建类型添加到CMAKE_CONFIGURATION_TYPES中来定义它们,并且可以从该列表中删除不需要的构建类型。

​ 但是,如果CMAKE_CONFIGURATION_TYPES还没有定义,则需要注意避免设置它。在CMake 3.9之前,确定是否使用了多配置生成器的一个非常常见的方法是检查CMAKE_CONFIGURATION_TYPES是否为非空。甚至在3.11之前,CMake的某些部分也这样做了。虽然这种方法通常是准确的,但即使使用单个配置生成器,项目也会单方面设置CMAKE_CONFIGURATION_TYPES。这可能会导致在使用的生成器类型方面做出错误的决定。为了解决这个问题,CMake 3.9添加了一个新的GENERATOR_IS_MULTI_CONFIG全局属性,当使用多配置生成器时,该属性被设置为true,提供了一种确定的方式来获取该信息,而不是依赖于从CMAKE_CONFIGURATION_TYPES推断。即便如此,检查CMAKE_CONFIGURATION_TYPES仍然是一种流行的模式,项目应该只在它存在的时候继续修改它,而不应该自己创建它。还应该注意的是,在CMake 3.11之前,向CMAKE_CONFIGURATION_TYPES添加自定义构建类型在技术上是不安全的。CMake的某些部分只考虑默认的构建类型,但即便如此,项目仍然可以使用早期的CMake版本来定义定制的构建类型,这取决于它们将如何被使用。也就是说,为了更好的健壮性,如果要定义自定义构建类型,仍然建议至少使用CMake 3.11。

​ 这个问题的另一个方面是,开发人员可能会将他们自己的类型添加到CMAKE_CONFIGURATION_TYPES缓存变量中,并且/或删除一些他们不感兴趣的类型。因此,项目不应该对什么配置类型是或没有定义做任何假设。

​ 考虑到以上几点,下面的模式显示了项目添加自己的自定义多配置生成器的构建类型的首选方式:

cmake_minimum_required(3.11)
project(Foo)
if(CMAKE_CONFIGURATION_TYPES)
  if(NOT "Profile" IN_LIST CMAKE_CONFIGURATION_TYPES)
  list(APPEND CMAKE_CONFIGURATION_TYPES Profile)
  endif()
endif()
# Set relevant Profile-specific flag variables if not already set...

​ 对于单个配置生成器,只有一种构建类型,它由CMAKE_BUILD_TYPE缓存变量指定,该变量是一个字符串。在CMake GUI中,这通常是一个文本编辑字段,所以开发人员可以编辑它以包含任何他们想要的任意内容。但是,正如在“缓存变量属性”中所讨论的,缓存变量可以定义它们的string属性来保存一组有效的值。然后,CMake GUI应用程序将该变量显示为一个包含有效值的组合框,而不是一个文本编辑字段。

set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
  STRINGS Debug Release Profile)

​ 属性只能从项目的CMakeLists.txt文件中更改,所以他们可以安全地设置string属性,而不必担心保留任何开发人员的更改。注意,然而,设置一个缓存变量的STRINGS属性并不能保证缓存变量将保存其中一个定义的值,它只是控制变量在CMake GUI应用程序中的呈现方式。开发者仍然可以在cmake命令行中将CMAKE_BUILD_TYPE设置为任意值,或者手动编辑CMakeCache.txt文件。为了严格要求变量具有其中一个定义的值,项目必须显式地执行测试本身。

set(allowableBuildTypes Debug Release Profile)
# WARNING: This logic is not sufficient
if(NOT CMAKE_BUILD_TYPE IN_LIST allowableBuildTypes)
  message(FATAL_ERROR "${CMAKE_BUILD_TYPE} is not a defined build type")
endif()

​ CMAKE_BUILD_TYPE的默认值是一个空字符串,所以上面的设置对于单个和多个配置生成器都会导致致命错误,除非开发人员显式地设置它。这是不希望看到的,特别是对于不使用CMAKE_BUILD_TYPE变量值的多配置生成器。如果CMAKE_BUILD_TYPE没有设置,可以通过让项目提供一个默认值来处理。此外,多组态和单组态生成器的技术可以而且应该结合起来,在所有生成器类型中提供健壮的行为。最终的结果是这样的:

cmake_minimum_required(3.11)
project(Foo)
if(CMAKE_CONFIGURATION_TYPES)
  if(NOT "Profile" IN_LIST CMAKE_CONFIGURATION_TYPES)
  	list(APPEND CMAKE_CONFIGURATION_TYPES Profile)
  endif()
else()
  set(allowableBuildTypes Debug Release Profile)
  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
  STRINGS "${allowableBuildTypes}")
  if(NOT CMAKE_BUILD_TYPE)
  	set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE)
  elseif(NOT CMAKE_BUILD_TYPE IN_LIST allowableBuildTypes)
  	message(FATAL_ERROR "Invalid build type: ${CMAKE_BUILD_TYPE}")
  endif()
endif()
# Set relevant Profile-specific flag variables if not already set...

​ 上面讨论的所有技术只允许选择一个自定义构建类型,它们不定义任何关于该构建类型的东西。基本上,当一个构建类型被选择时,它指定了CMake应该使用哪些特定于配置的变量,它也会影响任何逻辑依赖于当前配置的生成器表达式(例如$<\CONFIG>和$<CONFIG:…>)。这些变量和生成器表达式将在下一章中详细讨论,但现在,我们主要关注以下两类变量:

  • CMAKE_<LANG>_FLAGS_<CONFIG>
  • CMAKE_<TARGETTYPE>_LINKER_FLAGS_<CONFIG>

​ 这些可以用来在没有_后缀的同名变量所提供的默认设置之上添加额外的编译器和链接器标志。例如,自定义概要文件构建类型的标志可以定义如下:

set(CMAKE_C_FLAGS_PROFILE "-p -g -O2" CACHE STRING "")
set(CMAKE_CXX_FLAGS_PROFILE "-p -g -O2" CACHE STRING "")
set(CMAKE_EXE_LINKER_FLAGS_PROFILE "-p -g -O2" CACHE STRING "")
set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "-p -g -O2" CACHE STRING "")
set(CMAKE_STATIC_LINKER_FLAGS_PROFILE "-p -g -O2" CACHE STRING "")
set(CMAKE_MODULE_LINKER_FLAGS_PROFILE "-p -g -O2" CACHE STRING "")

​ 上面假设有一个gcc兼容的编译器,以保持示例的简单性,并打开分析以及启用调试符号和大多数优化。另一种方法是将编译器和链接器标志基于另一种构建类型,并添加所需的额外标志。只要它在project()命令之后就可以完成,因为该命令填充了默认的编译器和链接器标志变量。对于分析,RelWithDebInfo默认的构建类型是一个很好的选择作为基础配置,因为它可以同时启用调试和大多数优化:

set(CMAKE_C_FLAGS_PROFILE
  "${CMAKE_C_FLAGS_RELWITHDEBINFO} -p" CACHE STRING "")
set(CMAKE_CXX_FLAGS_PROFILE
  "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -p" CACHE STRING "")
set(CMAKE_EXE_LINKER_FLAGS_PROFILE
  "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} -p" CACHE STRING "")
set(CMAKE_SHARED_LINKER_FLAGS_PROFILE
  "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} -p" CACHE STRING "")
set(CMAKE_STATIC_LINKER_FLAGS_PROFILE
  "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO} -p" CACHE STRING "")
set(CMAKE_MODULE_LINKER_FLAGS_PROFILE
  "${CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO} -p" CACHE STRING "")

​ 每个自定义配置都应该定义相关的编译器和链接器标志变量。对于一些多配置生成器类型,CMake会检查所需的变量是否存在,如果没有设置,则会出现错误。

​ 另一个有时可以为自定义构建类型定义的变量是CMAKE_<CONFIG>_POSTFIX。它用于初始化每个库目标的<CONFIG>_POSTFIX属性,当为指定的配置构建时,它的值被附加到这些目标的文件名中。这使得来自多个构建类型的库可以放在同一个目录中,而不会相互覆盖。CMAKE_DEBUG_POSTFIX通常被设置为d或_debug这样的值,特别是在Visual Studio构建中,Debug和non-Debug构建必须使用不同的运行时dll,所以包可能需要包含两种构建类型的库。在上面定义的自定义概要文件构建类型的情况下,一个例子可能是:

set(CMAKE_PROFILE_POSTFIX _profile)

​ 如果创建包含多个构建类型的包,强烈建议为每种构建类型设置CMAKE_<CONFIG>_POSTFIX。按照惯例,Release构建的后缀通常是空的。注意,在苹果平台上<CONFIG>_POSTFIX目标属性被忽略了。

​ 由于历史原因,传递给target_link_libraries()命令的项可以用debug或optimized的关键字作为前缀,以指示命名的项只能分别用于调试或非调试构建。如果构建类型在DEBUG_CONFIGURATIONS全局属性中列出,则认为它是调试构建,否则认为它是优化的。对于自定义构建类型,如果在此场景中它们应被视为调试构建,则应将其名称添加到此全局属性中。例如,如果一个项目定义了自己的自定义构建类型StrictChecker,并且该构建类型应该被认为是一个未优化的调试构建类型,那么它可以(也应该)这样明确:

set_property(GLOBAL PROPERTY APPEND DEBUG_CONFIGURATIONS StrictChecker)

​ 新项目通常应该更喜欢使用生成器表达式,而不是使用target_link_libraries()命令debug和optimized的关键字。
相关代码:https://gitee.com/jiangli01/cmake-learning
更多请关注微信公众号【Hope Hut】:
在这里插入图片描述

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

CMake(十二):构建类型 的相关文章

  • 在 C 中使用 pow 时,CMake 可以检测是否需要链接到 libm 吗?

    对于某些编译器 using powC 程序中的某些其他函数需要链接到m library https stackoverflow com q 8671366 1959975 但是 某些编译器不需要这样做 并且在链接到m图书馆 C 也存在几乎相
  • Cmake 错误:无效的转义序列 \U

    使用 CMake 在 VC 10 中运行 OpenCL 代码时 出现以下错误 CMake Error at CMakeLists txt 6 set Syntax error in cmake code at C Users Shreedh
  • 为什么 cmake 在 git commit 后编译所有内容

    假设我有时在 Linux 上使用 cmake 2 8 编译一段代码 我更改了一个文件 my changed file 运行 cmake 并且只构建了这个文件 到目前为止 一切都很好 现在我想提交这个 git add my changed f
  • 将 Doctest 与代码一起使用时将实现放在哪里

    我在用着doctest https github com onqtam doctest用于我的 C 项目中的测试 我想将测试代码与我的实现放在一起 正如库所说是可能的 但我似乎不知道如何处理 doctest 实现代码 我有一个doctest
  • 使用星号更改多个源文件的 CMake 编译器标志

    我正在尝试调试与编译器优化相关的问题 O2 或以下版本没有问题 O3 出现段错误 并且我希望能够切换我的源代码块的编译器标志 以便我可以尝试缩小段错误的来源范围 我可以将全局优化级别设置为 O2 并更改单个文件的属性 如下所示 SET SO
  • 将 dll/lib 链接到 cmake 项目

    我试图将库链接到我的 cmake 项目 但遇到链接器错误 我花了 2 个小时尝试解决这个问题 并创建了一个简单的项目 在其中对所有路径进行了硬编码 CMAKE MINIMUM REQUIRED VERSION 3 0 PROJECT Tes
  • 如何使用cmake查找库?

    要将可执行文件与驻留在标准位置的库链接 可以在 CmakeLists txt 文件中执行以下操作 create executable generate mesh generate mesh cpp target link libraries
  • 了解 CMake 背后的目的[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我试图理解 CMake 背后的目的 为什么它被设计成现在这样 以下是我想回答的一些问题 为什么CMake会生成生成文件 https e
  • 如何在 CMake Makefile 中包含 OpenCV 库

    我希望你可以帮助我 我有一个简单的 CMakeLists txt 以便在 Leopard 10 5 8 上构建我的项目 我正在使用 CMake 2 8 1 目前这是代码 cmake minimum required VERSION 2 8
  • Clion如何将文件添加到项目中

    这看起来真的很基本 如何将文件添加到项目中而无需手动编辑CMakeLists txt 例如另一个目录中的源文件 CLion 解析CMakeLists txt并使用它生成项目视图 但我相信将文件添加到项目的唯一方法是编辑CMakeLists
  • CMake:如何更改单个目标的编译器

    我有使用交叉编译器的嵌入式项目 我想介绍一下Google测试 用原生GCC编译器编译 另外使用 CTC 编译器构建一些单元测试目标 Briefly 我有 3 个不同的目标并用 3 个不同的编译器编译它们 如何表达它CMakeLists tx
  • 如何在 CMake 中运行基本的“add_custom_command”

    我只是想启动并运行一个基本的 CMake 示例 它可以运行一些基本的命令行命令 我已经研究这个有一段时间了 但没有任何运气 我完全用错了吗 任何和所有的意见将不胜感激 cmake minimum required VERSION 3 0 a
  • 编译器标志的 cmake list 附加会产生虚假结果?

    我需要向 CMake 文件 CMake 2 8 10 2 中的 C 和 C 编译行添加各种标志 我看到有些人使用add definitions但据我所知 这是用于预处理器标志的 D 我有一些标志不想传递给预处理器 所以我一直在尝试修改CMA
  • 奇怪的函数参数名称行为

    我问了一个关于cmake和传递变量的问题here https stackoverflow com questions 14375519 cmake how to write a nice function that passes varia
  • 使用 CLion IDE 运行 Opengl 程序 [重复]

    这个问题在这里已经有答案了 我知道这个问题已经被问过 但提供的解决方案确实对我不起作用 我想通过 CLion IDE 运行我的 OpenGL 程序 我可以通过 Ubuntu 中的终端运行相同的程序 gcc progname c lglut
  • CMake GUI:指定 Windows 的库路径

    我正在编译一个基于 CMake 的项目 具体来说是 SOCI 它依赖于 SQLite 这是Windows 没有可供项目研究的标准路径 因此它找不到SQLite 我在配置时得到这个 SQLite3 not found some librari
  • 为什么我会收到此 Android Studio 错误:“使用 -fPIC 重新编译”?

    我正在使用 NDK 18 并使用 x86 64 NDK 独立工具链单独编译静态库 我可以成功链接它 但是当我尝试以一种不平凡的方式访问该库时 我在构建时遇到了许多错误 例如 requires dynamic R X86 64 PC32 re
  • CMake:Fortran 模块和编译顺序

    我有一个大型 Fortran 程序 其中包含许多目录 每个目录都在伪库中单独编译 但仍然存在相互依赖的混乱 因此最终所有伪库都组合在一个可用的库中 我想使用 Fortran 模块 但它非常脆弱 因为我不能依赖自动依赖项检查 并且根据顺序编译
  • CMakeLists.txt:30(项目)处的 CMake 错误:找不到 CMAKE_C_COMPILER

    我正在尝试使用 CMake 制作 Visual Studio 解决方案来编译最新版本的 aseprite 并且 CMake 不断向我提供 No CMAKE C COMPILER could be found No CMAKE CXX COM
  • CMake 链接 glfw3 lib 错误

    我正在使用 CLion 并且正在使用 glfw3 库编写一个程序 http www glfw org docs latest http www glfw org docs latest 我安装并正确执行了库中的所有操作 我有 a 和 h 文

随机推荐

  • Jetson TX2配置Tensorflow、Pytorch等常用库

    之前在PC Ubuntu或者树莓派上都配置过 方法不变 所以此篇博客会简单记录 下过程 详细的一些方法思路可以去参考博主之前的系列博客 虽然硬件平台不一样 但方法大体一致的 硬件平台主流的有树莓派 NVIDIA Jetson Google的
  • Macbook pro外接显卡实现深度学习

    耗时一整天加一晚上终于成功了安装配置外接GPU并运行深度学习案列 故事的缘由 2017年底鬼使神差的买了个macbook xff0c 放在家里吃了一年灰 xff0c 心想还是要用起来啊 目前主要从事数据挖掘机器学习的工作 xff0c 需要搞
  • Gradle技术之一 Groovy语法精讲

    Gradle技术之一 Groovy语法精讲 gradle脚本是基于groovy语言开发的 xff0c 想要学好gradle必须先要对groovy有一个基本的认识 1 Groovy特点 groovy是一种DSL语言 xff0c 所谓的DSL语
  • 字符串子串的查找

    1 考虑用标准函数库中 strstr 函数 包含文件 xff1a string h 函数名 strstr 函数原型 xff1a extern char strstr char str1 char str2 功能 xff1a 从字符串str1
  • 大锤老湿教您如何配置TP-Link路由器组建wifi上网

    TP Link路由器设置教程 大家好 xff0c 今天由大锤老湿教大家如何设置使用最广的TP Link路由器 一般家庭都希望能上wifi 那么首先看看我们如何将新买回的或者由于故障已经恢复成重置出厂状态的路由器 xff0c 如何经过重新设置
  • 【ESP01S】使用串口调试助手,发送AT指令收回的是乱码/重复一遍AT指令发回的问题

    调试帮助 span class token punctuation span 技术交流Q xff1a span class token number 1083091092 span xff08 备注CSDN xff09 一 问题描述 在使用
  • 刷leetcode使用python还是c++?

    我身边80 的程序员朋友在刷题的时候会选择Java xff0c 很少有人用C 43 43 来刷题 这两门语言各有特点 xff1a C 43 43 xff1a 从C语言发展过来的一门语言 xff0c 继承了灵活 xff08 可以潜入任何现代的
  • VINS-Mono代码精简版代码详解-后端非线性优化(三)

    非线性优化部分代码解析 之前已经对VINS Mono的初始化部分进行了介绍 xff0c 下面结合代码和公式介绍其非线性优化部分 本文部分参考 https blog csdn net u012871872 article details 78
  • Ubuntu IO占用过多导致文件读取变慢的原因查找方法

    问题描述 xff1a 多用户服务器 xff0c ubuntu系统 xff0c 突然点开文件夹 xff0c 发现变慢 查看方法 xff1a step1 xff1a 进入管理员用户 step2 xff1a 运行iostat x 1 在显示的结果
  • ROS Docker

    Docker 常用指令 docker pull osrf ros galactic desktop 从网络上下载镜像 docker images 查看已加载镜像列表 window docker界面 xff1a 命令行结果 xff1a doc
  • Win10C盘文件夹内容详解(持续更新,欢迎留言)

    本文参考以下博客 Roaming和Local的区别 C Users 用户名 AppData 1 Local和Roaming之间的区别 xff1a Local 比较大 xff0c 非漫游应用数据 Roaming 一般是漫游应用数据 2 Roa
  • STM32运行FreeRTOS

    使用ARM Keil 的 Keil uVision IDE xff0c 在 STM32上运行 FreeRTOS 内核 物料清单 软件 在创建新项目之前 xff0c 我们必须安装软件包 下面是打印屏幕 xff0c 其中包含如何执行此操作的步骤
  • ESP32实践FreeRTOS

    将部分代码作为应用程序中的任务独立执行可以简化大型复杂问题的设计 当有多个 CPU 时 xff0c 任务支持还允许选定的功能并行运行 本文将调查 Arduino 框架对 ESP32 系列设备的 FreeRTOS 任务支持 除了少数例外 xf
  • 黑马程序员—5—Java基础:多态学习笔记和学习心得体会

    lt ahref 61 34 http www itheima com 34 target 61 34 blank 34 gt android 培训 lt a gt lt ahref 61 34 http www itheima com 3
  • 图像去噪算法简介

    一 xff0c 背景 随着各种数字仪器和数码产品的普及 xff0c 图像和视频已成为人类活动中最常用的信息载体 xff0c 它们包含着物体的大量信息 xff0c 成为人们获取外界原始信息的主要途径 然而在图像的获取 传输和存贮过程中常常会受
  • Android 7 Nougat 源码目录结构

    code style margin 0px auto font family none padding 0px color inherit background color transparent art Android Runtime x
  • 【无人驾驶规划】BOSS无人车规划算法

    无人驾驶规划 BOSS无人车规划算法 1 boss运动规划结构2 轨迹生成2 1 状态约束2 2 车辆模型2 3 控制参数化2 4 初始化轨迹2 5 轨迹优化 3 on road模式规划3 1 路径生成3 2 轨迹生成3 3 轨迹速度配置3
  • 这也太全面了 阿里王牌级“Docker全线笔记”,Github已标星80k+,我太爱

    写在开头 司汤达说过 xff1a 一个人只要强烈地坚持不懈地追求 xff0c 他就能达到目的 Docker的创始人Solomon Hykes就是以这样的精神 xff0c 在docker即将坚持不下去的时候 xff0c 选择的不是放弃 xff
  • 如何在keil5中新建.c和.h文件?

    有两种方法 xff1a 方法1 在keil5内部添加两个文件分别为 c和 h文件 xff0c 可以保存在一个新建的文件夹里 xff08 前提是此文件夹是在keil5内部保存时新建的文件夹 xff0c 而不是在keil5软件外自己新建的文件夹
  • CMake(十二):构建类型

    本章和下一章涉及两个密切相关的主题 构建类型 在某些IDE工具中也称为构建配置或构建方案 是一种高级控件 xff0c 它选择不同的编译器和链接器行为集 构建类型的操作是本章的主题 xff0c 而下一章将介绍控制编译器和链接器选项的更具体细节