从入门到精通:CMakeLists.txt 完全指南

从入门到精通:CMakeLists.txt 完全指南

CMake 是一个跨平台的自动化构建系统,它使用名为 CMakeLists.txt 的配置文件来控制软件的编译过程。无论你是刚接触 CMake 的新手,还是希望提升 CMake 技能的中级开发者,这篇指南都将带你从基础到高级全面掌握 CMakeLists.txt 的编写技巧。

一、CMake 基础入门

1.1 什么是 CMake?

CMake 是一个跨平台的开源构建系统,它通过读取 CMakeLists.txt 文件中的指令来生成标准的构建文件(如 Unix 的 Makefile 或 Windows 的 Visual Studio 项目文件)。CMake 的主要优势在于:

  • 跨平台性:可以生成适用于不同操作系统和编译器的构建文件
  • 简化构建过程:自动处理依赖关系和编译顺序
  • 模块化设计:支持大型项目的模块化管理
  • 可扩展性:可以通过自定义命令和函数扩展功能

1.2 最简单的 CMakeLists.txt

让我们从一个最简单的 “Hello World” 项目开始:

# 指定 CMake 的最低版本要求
cmake_minimum_required(VERSION 3.10)# 设置项目名称
project(HelloWorld)# 添加可执行文件
add_executable(HelloWorld main.cpp)

这个简单的 CMakeLists.txt 文件包含三个基本指令:

  1. cmake_minimum_required:指定构建此项目所需的最低 CMake 版本
  2. project:定义项目名称和相关信息
  3. add_executable:指定要生成的可执行文件和源文件

1.3 构建过程

使用这个 CMakeLists.txt 文件的典型构建流程是:

mkdir build  # 创建构建目录(推荐外部构建)
cd build     # 进入构建目录
cmake ..     # 生成构建系统
make         # 编译项目

这种"外部构建"的方式(在单独的 build 目录中构建)是推荐的做法,因为它不会污染源代码目录。

二、CMakeLists.txt 核心语法详解

2.1 基本指令深入

2.1.1 project() 指令

project() 指令不仅可以指定项目名称,还可以设置版本、描述和使用的编程语言:

project(MyProject VERSION 1.0.0 DESCRIPTION "A sample CMake project"LANGUAGES CXX)
  • VERSION:设置项目版本号
  • DESCRIPTION:项目描述信息
  • LANGUAGES:指定项目使用的编程语言(C 表示 C 语言,CXX 表示 C++)
2.1.2 添加可执行文件

add_executable() 指令用于生成可执行文件:

add_executable(TargetName source1.cpp source2.cpp header1.h)

CMake 会自动识别 .cpp 文件为源文件,.h 文件为头文件。虽然头文件可以列出,但通常不需要,除非它们包含需要被 moc 或其他预处理器处理的代码。

2.1.3 添加库文件

使用 add_library() 可以创建库文件:

add_library(LibraryName STATIC source1.cpp source2.cpp)

库的类型可以是:

  • STATIC:静态库(.a 或 .lib)
  • SHARED:动态库(.so 或 .dll)
  • MODULE:模块库(不被链接,但可能被运行时加载)

2.2 变量与属性

2.2.1 变量设置与使用

CMake 使用 set() 命令定义变量:

set(MY_VARIABLE "Hello World")
set(SOURCE_FILES main.cpp utils.cpp)

使用 ${} 语法引用变量:

message(STATUS "The value is: ${MY_VARIABLE}")
add_executable(MyApp ${SOURCE_FILES})
2.2.2 缓存变量

缓存变量会保存在 CMakeCache.txt 中,可以在后续构建中使用:

set(MY_CACHE_VAR "DefaultValue" CACHE STRING "A description of this variable")

缓存变量可以在命令行通过 -D 选项设置:

cmake -DMY_CACHE_VAR="CustomValue" ..
2.2.3 环境变量

读取和使用环境变量:

set(ENV{PATH} "$ENV{PATH}:/opt/local/bin")
message(STATUS "Current PATH: $ENV{PATH}")

2.3 控制流

2.3.1 条件语句
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")message(STATUS "Running on Linux")
elseif(WIN32)message(STATUS "Running on Windows")
else()message(STATUS "Running on unknown system")
endif()

常用条件表达式:

  • DEFINED var:检查变量是否定义
  • EXISTS path:检查路径是否存在
  • file1 IS_NEWER_THAN file2:检查文件时间戳
  • version1 VERSION_LESS version2:版本比较
2.3.2 循环语句
# foreach 循环
foreach(i RANGE 1 10)message(STATUS "Counter: ${i}")
endforeach()# while 循环
set(i 0)
while(i LESS 10)message(STATUS "Counter: ${i}")math(EXPR i "${i} + 1")
endwhile()

2.4 文件操作

2.4.1 包含目录
include_directories(${PROJECT_SOURCE_DIR}/include)

现代 CMake 更推荐使用 target_include_directories()

target_include_directories(MyTarget PUBLIC include)
2.4.2 链接库
target_link_libraries(MyTarget PUBLIC MyLibrary)

PUBLICPRIVATEINTERFACE 关键字控制依赖的传递性:

  • PRIVATE:仅当前目标使用
  • INTERFACE:仅依赖此目标的其他目标使用
  • PUBLIC:当前目标和其他依赖目标都使用
2.4.3 文件操作命令
# 查找所有 .cpp 文件
file(GLOB SOURCES "src/*.cpp")# 复制文件
file(COPY data DESTINATION ${CMAKE_BINARY_DIR})# 读写文件
file(READ "${PROJECT_SOURCE_DIR}/VERSION" PROJECT_VERSION)
file(WRITE "${CMAKE_BINARY_DIR}/generated.h" "#define VERSION \"${PROJECT_VERSION}\"")

三、项目结构组织

3.1 基本项目结构

一个典型的 CMake 项目结构如下:

MyProject/
├── CMakeLists.txt        # 顶层 CMake 配置
├── build/                # 构建目录(外部构建)
├── include/              # 公共头文件
│   └── MyLib/
│       └── header.h
├── src/                  # 源文件
│   ├── CMakeLists.txt    # 子目录 CMake 配置
│   ├── main.cpp
│   └── utils.cpp
└── tests/                # 测试代码└── CMakeLists.txt

3.2 子目录管理

使用 add_subdirectory() 将项目分解为多个子目录:

# 顶层 CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(MyProject)add_subdirectory(src)    # 包含 src 子目录
add_subdirectory(tests)  # 包含 tests 子目录

每个子目录有自己的 CMakeLists.txt 文件。

3.3 源文件收集

有多种方式指定源文件:

  1. 显式列出所有源文件:
add_executable(MyApp src/main.cpp src/utils.cpp)
  1. 使用 aux_source_directory 自动收集:
aux_source_directory(. SRC_FILES)
add_executable(MyApp ${SRC_FILES})
  1. 使用 file(GLOB) 更灵活地匹配文件:
file(GLOB SRC_FILES "src/*.cpp" "src/*.c")
add_executable(MyApp ${SRC_FILES})

注意:GLOB 不会自动检测新增文件,需要重新运行 CMake。

四、依赖管理与查找

4.1 查找系统库

使用 find_package 查找系统安装的库:

find_package(Boost 1.70 REQUIRED COMPONENTS filesystem system)
target_link_libraries(MyTarget PUBLIC Boost::filesystem Boost::system)

REQUIRED 表示必须找到该包,否则报错。

4.2 自定义查找模块

如果 CMake 没有提供某个库的查找模块,可以自己编写 FindXXX.cmake

# FindMyLib.cmake
find_path(MYLIB_INCLUDE_DIR mylib.h HINTS /usr/local/include)
find_library(MYLIB_LIBRARY NAMES mylib HINTS /usr/local/lib)include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MyLib DEFAULT_MSG MYLIB_LIBRARY MYLIB_INCLUDE_DIR)if(MyLib_FOUND)set(MyLib_LIBRARIES ${MYLIB_LIBRARY})set(MyLib_INCLUDE_DIRS ${MYLIB_INCLUDE_DIR})
endif()

然后在 CMakeLists.txt 中使用:

list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
find_package(MyLib REQUIRED)
target_include_directories(MyTarget PUBLIC ${MyLib_INCLUDE_DIRS})
target_link_libraries(MyTarget PUBLIC ${MyLib_LIBRARIES})

4.3 第三方依赖管理

现代 CMake 项目常用这些方法管理第三方依赖:

  1. Git 子模块
git submodule add https://github.com/xxx/yyy.git extern/yyy

然后在 CMakeLists.txt 中:

add_subdirectory(extern/yyy)
target_link_libraries(MyTarget PUBLIC yyy)
  1. FetchContent(CMake 3.11+):
include(FetchContent)
FetchContent_Declare(googletestGIT_REPOSITORY https://github.com/google/googletest.gitGIT_TAG release-1.11.0
)
FetchContent_MakeAvailable(googletest)
target_link_libraries(MyTarget PRIVATE gtest_main)
  1. ExternalProject(更复杂但更灵活):
include(ExternalProject)
ExternalProject_Add(MyExternalLibURL "http://example.com/mylib.tar.gz"CONFIGURE_COMMAND ""BUILD_COMMAND ""INSTALL_COMMAND ""
)

五、高级特性与技巧

5.1 生成器表达式

生成器表达式允许在生成构建系统时进行条件判断,常用于平台特定设置:

target_compile_definitions(MyTargetPUBLIC $<$<CONFIG:Debug>:DEBUG_MODE=1>$<$<CXX_COMPILER_ID:GNU>:EXTRA_FEATURE=1>
)

常用生成器表达式:

  • $<CONFIG:cfg>:如果配置是 cfg 则为 1
  • $<PLATFORM_ID:platform>:平台匹配检查
  • $<COMPILE_LANGUAGE:lang>:编译语言检查

5.2 自定义命令与目标

# 自定义命令
add_custom_command(OUTPUT generated.cppCOMMAND generator.py ${CMAKE_CURRENT_SOURCE_DIR}/input.txt > generated.cppDEPENDS generator.py input.txt
)# 自定义目标
add_custom_target(GenerateDocs ALLCOMMAND doxygen DoxyfileWORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}COMMENT "Generating documentation"
)

5.3 交叉编译

设置交叉编译工具链:

# toolchain.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)set(CMAKE_FIND_ROOT_PATH /path/to/sysroot)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

然后使用:

cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake ..

5.4 测试与打包

5.4.1 添加测试
enable_testing()add_test(NAME MyTest1COMMAND MyTestExe --test1WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})add_test(NAME MyTest2COMMAND MyTestExe --test2)

可以使用 CTest 运行测试:

ctest -V  # 运行所有测试并显示详细输出
5.4.2 安装规则
install(TARGETS MyTargetRUNTIME DESTINATION binLIBRARY DESTINATION libARCHIVE DESTINATION lib/static)install(DIRECTORY include/ DESTINATION include)
install(FILES README.md DESTINATION doc)
5.4.3 打包
include(InstallRequiredSystemLibraries)
set(CPACK_PACKAGE_VENDOR "My Company")
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
set(CPACK_SOURCE_GENERATOR "TGZ")
include(CPack)

生成包:

make package      # 生成二进制包
make package_source  # 生成源码包

六、现代 CMake 最佳实践

6.1 目标为中心的设计

现代 CMake 强调以目标(target)为中心的构建方式,每个库或可执行文件都是一个目标,明确指定其属性:

add_library(MyLibrary STATIC src/lib.cpp)
target_include_directories(MyLibrary PUBLIC include)
target_compile_features(MyLibrary PUBLIC cxx_std_17)
target_link_libraries(MyLibrary PUBLIC SomeOtherLib)

6.2 作用域控制

正确使用 PRIVATEPUBLICINTERFACE 控制依赖传递:

# MyLibrary 的 CMakeLists.txt
target_include_directories(MyLibraryPUBLIC include      # 使用者和被使用者都需要PRIVATE src        # 仅实现需要INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/interface  # 仅使用者需要
)

6.3 避免全局设置

避免使用全局设置如 include_directories()link_directories(),而是使用目标特定的命令。

6.4 模块化设计

将大型项目分解为多个逻辑组件,每个组件有自己的 CMakeLists.txt:

components/
├── core/
│   ├── CMakeLists.txt
│   ├── include/
│   └── src/
└── gui/├── CMakeLists.txt├── include/└── src/

6.5 工具链兼容性

编写可移植的 CMake 脚本:

if(MSVC)target_compile_options(MyTarget PRIVATE /W4 /WX)
else()target_compile_options(MyTarget PRIVATE -Wall -Wextra -pedantic)
endif()

七、常见问题与解决方案

7.1 头文件找不到

问题:编译时报告头文件找不到。

解决方案

  1. 使用 target_include_directories() 明确指定包含路径
  2. 确保路径正确,使用绝对路径或相对于 CMAKE_CURRENT_SOURCE_DIR 的路径
  3. 检查拼写错误

7.2 库链接失败

问题:链接时报告未定义的引用。

解决方案

  1. 确保 target_link_libraries() 指定了所有需要的库
  2. 检查库文件路径是否正确
  3. 确保库的顺序正确(被依赖的库放在后面)

7.3 跨平台问题

问题:在 Windows 上工作正常,但在 Linux 上失败。

解决方案

  1. 使用 if(WIN32)if(UNIX) 等条件语句处理平台差异
  2. 避免使用平台特定的路径分隔符(总是使用 /
  3. 使用 CMAKE_CXX_COMPILER_ID 检查编译器

7.4 构建速度慢

问题:大型项目构建时间过长。

解决方案

  1. 使用 ccache 缓存编译结果
  2. 启用并行构建:make -j8cmake --build . --parallel 8
  3. 减少不必要的依赖和包含

7.5 调试 CMake

技巧

  1. 使用 message() 打印变量值
  2. 添加 --trace--trace-expand 选项查看详细执行过程
  3. 使用 cmake --graphviz=graph.dot 生成依赖图

八、实战项目示例

8.1 基础项目结构

让我们看一个完整的基础项目结构:

MyApp/
├── CMakeLists.txt
├── build/
├── include/
│   └── MyApp/
│       ├── utils.h
│       └── config.h
├── src/
│   ├── CMakeLists.txt
│   ├── main.cpp
│   └── utils.cpp
└── tests/├── CMakeLists.txt└── test_utils.cpp

顶层 CMakeLists.txt:

cmake_minimum_required(VERSION 3.10)
project(MyApp VERSION 1.0.0 LANGUAGES CXX)# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)# 添加子目录
add_subdirectory(src)
add_subdirectory(tests)

src/CMakeLists.txt:

# 添加库
add_library(MyLib STATIC utils.cpp)
target_include_directories(MyLib PUBLIC ../include)# 添加可执行文件
add_executable(MyApp main.cpp)
target_link_libraries(MyApp PRIVATE MyLib)

tests/CMakeLists.txt:

# 启用测试
enable_testing()# 添加测试可执行文件
add_executable(TestUtils test_utils.cpp)
target_link_libraries(TestUtils PRIVATE MyLib)# 添加测试用例
add_test(NAME TestUtils COMMAND TestUtils)

8.2 使用外部依赖的项目

更复杂的项目可能依赖第三方库:

cmake_minimum_required(VERSION 3.12)
project(AdvancedApp)# 查找依赖
find_package(Boost 1.70 REQUIRED COMPONENTS system filesystem)
find_package(OpenCV REQUIRED)
find_package(Threads REQUIRED)# 添加项目目标
add_executable(AdvancedApp main.cpp)
target_link_libraries(AdvancedApp PRIVATE Boost::system Boost::filesystem OpenCV::OpenCV Threads::Threads
)# 安装规则
install(TARGETS AdvancedApp DESTINATION bin)
install(FILES config.xml DESTINATION etc/AdvancedApp)

九、总结与进阶学习资源

9.1 CMake 学习路径

  1. 初学者

    • 掌握基本命令:project(), add_executable(), target_link_libraries()
    • 理解变量和作用域
    • 学习简单的项目组织
  2. 中级开发者

    • 掌握现代 CMake 目标为中心的方法
    • 学习依赖管理和查找
    • 理解生成器表达式
  3. 高级开发者

    • 掌握交叉编译和工具链文件
    • 学习编写复杂的自定义命令和目标
    • 理解 CMake 内部机制和模块开发

9.2 推荐资源

  1. 官方文档

    • CMake 官方文档
    • CMake Tutorial
  2. 书籍

    • 《Professional CMake: A Practical Guide》
    • 《CMake Cookbook》
  3. 在线教程

    • Modern CMake
    • CMake 菜鸟教程
  4. 开源项目参考

    • 学习知名开源项目(如 KDE、VTK)的 CMake 配置
    • 参考 GitHub 上的现代 CMake 模板项目

9.3 结语

CMake 是一个功能强大但学习曲线较陡的工具。掌握 CMake 不仅能提高你的构建系统技能,还能让你更好地理解软件项目的组织和管理。从简单的单文件项目开始,逐步尝试更复杂的场景,最终你将能够驾驭任何规模的 CMake 项目。

记住,好的 CMake 脚本应该是:

  • 模块化:易于维护和扩展
  • 可移植:能在不同平台和编译器上工作
  • 高效:最小化不必要的重新构建
  • 明确:清晰地表达项目的结构和依赖关系

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/78191.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CPT204 Advanced Obejct-Oriented Programming 高级面向对象编程 Pt.8 排序算法

文章目录 1. 排序算法1.1 冒泡排序&#xff08;Bubble sort&#xff09;1.2 归并排序&#xff08;Merge Sort&#xff09;1.3 快速排序&#xff08;Quick Sort&#xff09;1.4 堆排序&#xff08;Heap Sort&#xff09; 2. 在面向对象编程中终身学习2.1 记录和反思学习过程2.2 …

【element plus】解决报错error:ResizeObserver loop limit exceeded的问题

当我们在使用element plus框架时&#xff0c;有时会遇到屏幕突然变暗&#xff0c;然后来一句莫名其妙的报错ResizeObserver loop limit exceeded&#xff0c;其实这是因为改变屏幕大小时el-table导致的报错 网上给出了几种解决方案&#xff0c;我试了其中两种可以实现 方案一&…

LeetCode算法题(Go语言实现)_60

题目 给你一个整数数组 cost &#xff0c;其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用&#xff0c;即可选择向上爬一个或者两个台阶。 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。 请你计算并返回达到楼梯顶部的最低花费。 一、代码实现…

马架构的Netty、MQTT、CoAP面试之旅

标题&#xff1a;马架构的Netty、MQTT、CoAP面试之旅 在互联网大厂的Java求职者面试中&#xff0c;一位名叫马架构的资深Java架构师正接受着严格的考验。他拥有十年的Java研发经验和架构设计经验&#xff0c;尤其对疑难问题和线索问题等有着丰富的经历。 第一轮提问&#xff…

焦化烧结行业无功补偿解决方案—精准分组补偿 稳定电能质量沃伦森

在焦化、烧结等冶金行业&#xff0c;负荷运行呈现长时阶梯状变化&#xff0c;功率波动相对平缓&#xff0c;但对无功补偿的分组精度要求较高。传统固定电容器组补偿方式无法动态跟随负荷变化&#xff0c;导致功率因数不稳定&#xff0c;甚至可能因谐波放大影响电网安全。 行业…

使用String path = FileUtilTest.class.getResource(“/1.txt“).getPath(); 报找不到路径

在windows环境运行&#xff0c;下面的springboot中path怎么找不到文件呢&#xff1f; path输出后的结果是&#xff1a;路径是多少&#xff1a;/D:/bjpowernode/msb/%e4%b9%90%e4%b9%8b%e8%80%85/apache%20commons/SpringBootBase6/target/test-classes/1.txt 怎么解决一下呢&am…

【C++】二叉树进阶面试题

根据二叉树创建字符串 重点是要注意括号省略问题&#xff0c;分为以下情况&#xff1a; 1.左字树为空&#xff0c;右子树不为空&#xff0c;左边括号保留 2.左右子树都为空&#xff0c;括号都不保留 3。左子树不为空&#xff0c;右子树为空&#xff0c;右边括号不保留 如果根节…

RSUniVLM论文精读

一些收获&#xff1a; 1. 发现这篇文章的table1中&#xff0c;有CDChat ChangeChat Change-Agent等模型&#xff0c;也许用得上。等会看看有没有源代码。 摘要&#xff1a;RSVLMs在遥感图像理解任务中取得了很大的进展。尽管在多模态推理和多轮对话中表现良好&#xff0c;现有模…

低空AI系统的合规化与标准化演进路径

随着AI无人机集群逐步参与城市空域治理、物流服务与公共安全作业&#xff0c;其系统行为不再是“技术封闭域”&#xff0c;而需接受法规监管、责任评估与接口协同的多方审查。如何将AI集群系统推向标准化、可接入、可审计的合规体系&#xff0c;成为未来空中交通演进的关键。本…

【金仓数据库征文】从云计算到区块链:金仓数据库的颠覆性创新之路

目录 一、引言 二、金仓数据库概述 2.1 金仓数据库的背景 2.2 核心技术特点 2.3 行业应用案例 三、金仓数据库的产品优化提案 3.1 性能优化 3.1.1 查询优化 3.1.2 索引优化 3.1.3 缓存优化 3.2 可扩展性优化 3.2.1 水平扩展与分区设计 3.2.2 负载均衡与读写分离 …

致远oa部署

文章目录 环境搭建项目构建 仅供学习使用 环境搭建 准备项目&#xff1a; https://pan.quark.cn/s/04a166575e94 https://pan.xunlei.com/s/VOOc1c9dBdLIuU8KKiqDa68NA1?pwdmybd# 官方文档: https://open.seeyoncloud.com/v5devCTP/ 安装时 mysql 数据库可能出现字符集设置…

移远通信智能模组助力东成“无边界智能割草机器人“闪耀欧美市场

2025年4月21日&#xff0c;移远通信宣布&#xff0c;旗下SC206E-EM智能模组已成功应用于江苏东成电动工具有限公司旗下的DCK TERRAINA无边界智能割草机器人。 这款智能模组高度集成计算、通信、定位等多元能力&#xff0c;以小型化、低功耗、实时性强和低成本等综合优势&#…

100.HTB-Meow

学习成果 在第一层&#xff0c;您将获得网络安全渗透测试领域的基本技能。您将首先学习如何匿名连接到各种服务&#xff0c;例如 FTP、SMB、Telnet、Rsync 和 RDP。接下来&#xff0c;您将发现 Nmap 的强大功能&#xff0c;Nmap 是一个有价值的工具&#xff0c;用于识别目标系统…

大厂面试-redis

前言 本章内容来自B站黑马程序员java大厂面试题和小林coding 博主学习笔记&#xff0c;如果有不对的地方&#xff0c;海涵。 如果这篇文章对你有帮助&#xff0c;可以点点关注&#xff0c;点点赞&#xff0c;谢谢你&#xff01; 1.redis的使用场景 1.1 缓存 缓存穿透 在布…

【含文档+PPT+源码】基于SpringBoot+vue的疫苗接种系统的设计与实现

项目介绍 本课程演示的是一款 基于SpringBootvue的疫苗接种系统的设计与实现&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系…

【Pandas】pandas DataFrame dot

Pandas2.2 DataFrame Binary operator functions 方法描述DataFrame.add(other)用于执行 DataFrame 与另一个对象&#xff08;如 DataFrame、Series 或标量&#xff09;的逐元素加法操作DataFrame.add(other[, axis, level, fill_value])用于执行 DataFrame 与另一个对象&…

Windows上Tomcat 11手动启动startup.bat关闭shutdown.bat

发现tomcat11无法手动双击startup.bat和shutdown.bat进行开启和关闭。双击startup.bat命令窗口一闪而过就是启动失败了&#xff0c;正常启动成功是cmd命令窗口有全副的执行输出且不关闭窗口。 解决方法如下&#xff1a;主要更改一个tomcat安装目录下的/conf/server.xml配置 1.…

7.9 Python+Click实战:5步打造高效的GitHub监控CLI工具

Python+Click实战:5步打造高效的GitHub监控CLI工具 GitHub Sentinel Agent 命令行界面开发实战 关键词:CLI 开发实践、Click 框架、API 集成、命令行参数解析、错误处理机制 1. 命令行界面技术选型与架构设计 GitHub Sentinel 采用 Click + Requests 技术栈构建 CLI 工具,…

安全框架概述

Java中的安全框架通常是指解决Web应用安全问题的框架&#xff0c;如果开发Web应用时没有使用安全框架&#xff0c;开发者需要自行编写代码增加Web应用安全性。自行实现Web应用的安全性并不容易&#xff0c;需要考虑不同的认证和授权机制、网络关键数据传输加密等多方面的问题&a…

配置 C/C++ 语言智能感知(IntelliSense)的 c_cpp_properties.json 文件内容

配置 C/C 语言智能感知&#xff08;IntelliSense&#xff09;的 c_cpp_properties.json 文件内容 {"configurations": [{"name": "Linux","includePath": ["${workspaceFolder}/**","/opt/ros/humble/include/**&quo…