Chapter 7: Compiling C++ Sources with CMake_《Modern CMake for C++》_Notes

news2025/4/18 9:31:10

Chapter 7: Compiling C++ Sources with CMake


1. Understanding the Compilation Process

Key Points:

  • Four-stage process: Preprocessing → Compilation → Assembly → Linking
  • CMake abstracts low-level commands but allows granular control
  • Toolchain configuration (compiler flags, optimizations, diagnostics)

Code Example - Basic Compilation Flow:

add_executable(MyApp main.cpp util.cpp)

2. Preprocessor Configuration

a. Include Directories

target_include_directories(MyApp
    PRIVATE 
        src/
        ${PROJECT_BINARY_DIR}/generated
)

b. Preprocessor Definitions

target_compile_definitions(MyApp
    PRIVATE
        DEBUG_MODE=1
        "PLATFORM_NAME=\"Linux\""
)

Key Considerations:

  • Use PRIVATE/PUBLIC/INTERFACE appropriately
  • Avoid manual -D flags; prefer CMake’s abstraction

3. Optimization Configuration

a. General Optimization Levels

target_compile_options(MyApp
    PRIVATE
        $<$<CONFIG:RELEASE>:-O3>
        $<$<CONFIG:DEBUG>:-O0>
)

b. Specific Optimizations

target_compile_options(MyApp
    PRIVATE
        -funroll-loops
        -ftree-vectorize
)

Key Considerations:

  • Use generator expressions for build-type-specific flags
  • Test optimization compatibility with check_cxx_compiler_flag()

4. Compilation Time Reduction

a. Precompiled Headers (PCH)

target_precompile_headers(MyApp
    PRIVATE
        <vector>
        <string>
        common.h
)

b. Unity Builds

set(CMAKE_UNITY_BUILD ON)
set(CMAKE_UNITY_BUILD_BATCH_SIZE 50)
add_executable(MyApp UNITY_GROUP_SOURCES src/*.cpp)

Tradeoffs:

  • PCH: Faster compilation but larger memory usage
  • Unity Builds: Reduced link time but harder debugging

5. Diagnostics Configuration

a. Warnings & Errors

target_compile_options(MyApp
    PRIVATE
        -Wall
        -Werror
        -Wno-deprecated-declarations
)

b. Cross-Compiler Compatibility

include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-Wconversion HAS_WCONVERSION)
if(HAS_WCONVERSION)
    target_compile_options(MyApp PRIVATE -Wconversion)
endif()

Best Practices:

  • Treat warnings as errors in CI builds
  • Use compiler-agnostic warning flags (/W4 vs -Wall)

6. Debug Information
target_compile_options(MyApp
    PRIVATE
        $<$<CONFIG:DEBUG>:-g3>
        $<$<CXX_COMPILER_ID:MSVC>:/Zi>
)

Key Considerations:

  • -g (GCC/Clang) vs /Zi (MSVC)
  • Separate debug symbols (-gsplit-dwarf for GCC)

7. Advanced Features

a. Link Time Optimization (LTO)

include(CheckIPOSupported)
check_ipo_supported(RESULT ipo_supported)
if(ipo_supported)
    set_target_properties(MyApp PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()

b. Platform-Specific Flags

if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm")
    target_compile_options(MyApp PRIVATE -mfpu=neon)
endif()

8. Common Pitfalls & Solutions

Problem: Inconsistent flags across targets
Solution: Use add_compile_options() carefully, prefer target-specific commands

Problem: Debug symbols missing in Release builds
Solution:

set(CMAKE_BUILD_TYPE RelWithDebInfo)

Problem: Compiler-specific flags breaking cross-platform builds
Solution: Use CMake’s abstraction:

target_compile_features(MyApp PRIVATE cxx_std_20)

9. Complete Example
cmake_minimum_required(VERSION 3.20)
project(OptimizedApp)

# Compiler feature check
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-flto HAS_LTO)

# Executable with unified build
add_executable(MyApp 
    [UNITY_GROUP_SOURCES]
    src/main.cpp 
    src/utils.cpp
)

# Precompiled headers
target_precompile_headers(MyApp PRIVATE common.h)

# Includes & definitions
target_include_directories(MyApp
    PRIVATE
        include/
        ${CMAKE_CURRENT_BINARY_DIR}/gen
)

target_compile_definitions(MyApp
    PRIVATE
        APP_VERSION=${PROJECT_VERSION}
)

# Optimization & diagnostics
target_compile_options(MyApp
    PRIVATE
        $<$<CONFIG:Release>:-O3 -flto>
        $<$<CONFIG:Debug>:-O0 -g3>
        -Wall
        -Werror
)

# LTO configuration
if(HAS_LTO)
    set_target_properties(MyApp PROPERTIES 
        INTERPROCEDURAL_OPTIMIZATION TRUE
    )
endif()

Key Takeaways
  1. Target-Specific Commands > Global settings
  2. Generator Expressions enable conditional logic
  3. Compiler Abstraction ensures portability
  4. Diagnostic Rigor prevents runtime errors
  5. Build-Type Awareness (Debug/Release) is crucial

Multiple Choice Questions


Question 1: Compilation Stages
Which of the following are required stages in the C++ compilation process when using CMake?
A) Preprocessing
B) Linking
C) Assembly
D) Code generation
E) Static analysis


Question 2: Preprocessor Configuration
Which CMake commands are valid for configuring the preprocessor?
A) target_include_directories()
B) add_definitions(-DDEBUG)
C) target_compile_definitions()
D) include_directories()
E) target_link_libraries()


Question 3: Header File Management
Which CMake features help manage header files correctly?
A) Using target_include_directories() with the PUBLIC keyword
B) Manually copying headers to the build directory
C) Using configure_file() to generate versioned headers
D) Adding headers to add_executable()/add_library() commands
E) Using file(GLOB) to collect headers


Question 4: Optimizations
Which optimization techniques can be controlled via CMake?
A) Function inlining (-finline-functions)
B) Loop unrolling (-funroll-loops)
C) Link-Time Optimization (-flto)
D) Setting -O3 as the default optimization level
E) Disabling exceptions via -fno-exceptions


Question 5: Reducing Compilation Time
Which CMake mechanisms are valid for reducing compilation time?
A) Enabling precompiled headers with target_precompile_headers()
B) Using UNITY_BUILD to merge source files
C) Disabling RTTI via -fno-rtti
D) Enabling ccache via CMAKE_<LANG>_COMPILER_LAUNCHER
E) Setting CMAKE_BUILD_TYPE=Debug


Question 6: Debugging Configuration
Which CMake settings are essential for generating debuggable binaries?
A) add_compile_options(-g)
B) set(CMAKE_BUILD_TYPE Debug)
C) target_compile_definitions(DEBUG)
D) Enabling -O0 optimization
E) Using -fsanitize=address


Question 7: Precompiled Headers
Which practices ensure correct usage of precompiled headers (PCH) in CMake?
A) Including PCH as the first header in source files
B) Using target_precompile_headers() with PRIVATE scope
C) Adding all headers to the PCH
D) Avoiding PCH for template-heavy code
E) Manually compiling headers with -x c++-header


Question 8: Error/Warning Flags
Which CMake commands enforce strict error handling?
A) add_compile_options(-Werror)
B) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
C) target_compile_options(-Wpedantic)
D) cmake_minimum_required(VERSION 3.10)
E) include(CheckCXXCompilerFlag)


Question 9: Platform-Specific Compilation
Which CMake variables detect platform-specific properties?
A) CMAKE_SYSTEM_NAME
B) CMAKE_CXX_COMPILER_ID
C) CMAKE_HOST_SYSTEM_PROCESSOR
D) CMAKE_SOURCE_DIR
E) CMAKE_ENDIANNESS


Question 10: Compiler Feature Detection
Which CMake modules/commands help check compiler support for C++ features?
A) check_cxx_compiler_flag()
B) include(CheckCXXSourceCompiles)
C) target_compile_features()
D) find_package(CXX17)
E) try_compile()


Answers & Explanations


Question 1: Compilation Stages
Correct Answers: A, C

  • A) Preprocessing and C) Assembly are core stages.
  • B) Linking occurs after compilation (handled separately).
  • D) Code generation is part of the compilation stage.
  • E) Static analysis is optional and not a standard stage.

Question 2: Preprocessor Configuration
Correct Answers: A, C

  • A) target_include_directories() sets include paths.
  • C) target_compile_definitions() adds preprocessor macros.
  • B/D) add_definitions() and include_directories() are legacy (not target-specific).
  • E) target_link_libraries() handles linking, not preprocessing.

Question 3: Header File Management
Correct Answers: A, C

  • A) target_include_directories(PUBLIC) propagates include paths.
  • C) configure_file() generates headers (e.g., version info).
  • B/D/E) Manual copying, add_executable(), or file(GLOB) are error-prone.

Question 4: Optimizations
Correct Answers: A, B, C

  • A/B/C) Explicitly controlled via target_compile_options().
  • D) -O3 is compiler-specific; CMake uses CMAKE_BUILD_TYPE (e.g., Release).
  • E) Disabling exceptions is a language feature, not an optimization.

Question 5: Reducing Compilation Time
Correct Answers: A, B, D

  • A/B) PCH and Unity builds reduce redundant parsing.
  • D) ccache caches object files.
  • C/E) Disabling RTTI/Debug builds do not reduce compilation time directly.

Question 6: Debugging Configuration
Correct Answers: A, B, D

  • A/B/D) -g, Debug build type, and -O0 ensure debuggable binaries.
  • C) DEBUG is a preprocessor macro (not required for symbols).
  • E) Sanitizers aid debugging but are not strictly required.

Question 7: Precompiled Headers
Correct Answers: A, B

  • A) PCH must be included first to avoid recompilation.
  • B) PRIVATE limits PCH to the current target.
  • C/E) Including all headers or manual compilation breaks portability.
  • D) PCH works with templates but may increase build complexity.

Question 8: Error/Warning Flags
Correct Answers: A, B, C

  • A/B/C) Enforce warnings/errors via compiler flags.
  • D/E) cmake_minimum_required() and CheckCXXCompilerFlag are unrelated to error handling.

Question 9: Platform-Specific Compilation
Correct Answers: A, B, C

  • A/B/C) Detect OS, compiler, and architecture.
  • D) CMAKE_SOURCE_DIR is the project root.
  • E) CMAKE_ENDIANNESS is not a standard CMake variable.

Question 10: Compiler Feature Detection

Correct Answers: A, B, E

  • A/B/E) Directly check compiler support for flags/features.
  • C) target_compile_features() specifies required standards.
  • D) CXX17 is not a standard package.

Practice Questions


Question 1: Preprocessor Definitions & Conditional Compilation
Scenario:
You’re working on a cross-platform project where a DEBUG_MODE macro must be defined only in Debug builds, and a PLATFORM_WINDOWS macro should be defined automatically when compiling on Windows. Additionally, in Release builds, the NDEBUG macro must be enforced.

Task:
Write a CMake snippet to configure these preprocessor definitions correctly for a target my_app, using modern CMake practices. Handle platform detection and build type conditions appropriately.


Question 2: Precompiled Headers (PCH)
Scenario:
Your project has a frequently used header common.h that includes heavy template code. To speed up compilation, you want to precompile this header for a target my_lib. However, your team uses both GCC/Clang and MSVC compilers.

Task:
Configure CMake to generate a PCH for common.h and apply it to my_lib, ensuring compatibility across GCC, Clang, and MSVC. Avoid hardcoding compiler-specific flags.


Hard Difficulty Question: Unity Builds & Platform-Specific Optimizations
Scenario:
A large project suffers from long compilation times. You decide to implement Unity Builds (combining multiple .cpp files into a single compilation unit) for a target big_target, while also enabling Link-Time Optimization (LTO) in Release builds. Additionally, on Linux, you want to enforce -march=native, but on Windows, use /arch:AVX2.

Task:

  1. Configure CMake to enable Unity Builds for big_target by grouping all .cpp files in src/ into batches of 10 files.
  2. Enable LTO in Release builds using CMake’s built-in support.
  3. Apply architecture-specific optimizations conditionally based on the platform.
  4. Ensure the solution avoids file(GLOB) anti-patterns and uses generator expressions where appropriate.

Answers & Explanations


Answer to Medium Question 1

target_compile_definitions(my_app
  PRIVATE
    $<$<CONFIG:Debug>:DEBUG_MODE>
    $<$<PLATFORM_ID:Windows>:PLATFORM_WINDOWS>
  PUBLIC
    $<$<CONFIG:Release>:NDEBUG>
)

Explanation:

  • Conditional Definitions:
    • Use generator expressions ($<...>) to conditionally define macros based on build type (CONFIG) and platform (PLATFORM_ID).
    • $<$<CONFIG:Debug>:DEBUG_MODE> adds -DDEBUG_MODE only in Debug builds.
    • $<$<PLATFORM_ID:Windows>:PLATFORM_WINDOWS> automatically defines PLATFORM_WINDOWS on Windows.
  • Public vs Private:
    • NDEBUG is marked PUBLIC to propagate to dependent targets (e.g., if my_app is a library).
    • Platform-specific and build-type-specific flags are PRIVATE to avoid leaking to dependents.

Answer to Medium Question 2

# Enable precompiled headers for the target
target_precompile_headers(my_lib
  PRIVATE
    # For GCC/Clang: Use the header directly
    $<$<CXX_COMPILER_ID:GNU,Clang>:common.h>
    # For MSVC: Use forced include
    $<$<CXX_COMPILER_ID:MSVC>:/FIcommon.h>
)

# MSVC requires the header to be part of the source tree
if(MSVC)
  target_sources(my_lib PRIVATE common.h)
endif()

Explanation:

  • Compiler-Agnostic PCH:
    • target_precompile_headers is the modern CMake way to handle PCH.
    • For GCC/Clang, specifying common.h directly tells CMake to precompile it.
    • MSVC requires /FI (Force Include) to use the PCH, hence the generator expression.
  • MSVC Workaround:
    • MSVC needs the header in the source list to avoid “header not found” errors.
  • No Hardcoded Flags:
    • Avoids manual -Winvalid-pch or /Yc//Yu flags by relying on CMake abstractions.

Answer to Hard Question

# 1. Unity Build Configuration
file(GLOB_RECURSE SRC_FILES CONFIGURE_DEPENDS src/*.cpp)
set(BATCH_SIZE 10)
set(UNITY_SOURCES "")
math(EXPR N_BATCHES "${SRC_FILES} / ${BATCH_SIZE} + 1")

foreach(BATCH RANGE 1 ${N_BATCHES})
  list(SUBLIST SRC_FILES ${BATCH_SIZE}*(BATCH-1) ${BATCH_SIZE} BATCH_FILES)
  if(BATCH_FILES)
    set(UNITY_FILE "unity_${BATCH}.cpp")
    file(WRITE ${UNITY_FILE} "")
    foreach(SRC ${BATCH_FILES})
      file(APPEND ${UNITY_FILE} "#include \"${SRC}\"\n")
    endforeach()
    list(APPEND UNITY_SOURCES ${UNITY_FILE})
  endif()
endforeach()

add_library(big_target ${UNITY_SOURCES})

# 2. LTO in Release
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON)

# 3. Platform-Specific Optimizations
target_compile_options(big_target
  PRIVATE
    $<$<AND:$<PLATFORM_ID:Linux>,$<CONFIG:Release>>:-march=native>
    $<$<AND:$<PLATFORM_ID:Windows>,$<CONFIG:Release>>:/arch:AVX2>
)

Explanation:

  1. Unity Builds:
    • file(GLOB_RECURSE ... CONFIGURE_DEPENDS) avoids the “stale file list” anti-pattern by re-globbing on build system regeneration.
    • Batches .cpp files into unity_X.cpp files, each including 10 source files.
    • Note: Unity builds trade compilation speed for incremental build efficiency. Use judiciously.
  2. LTO:
    • CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE enables LTO portably across compilers.
  3. Platform-Specific Flags:
    • Uses nested generator expressions to apply -march=native on Linux and /arch:AVX2 on Windows only in Release builds.
  4. Best Practices:
    • Avoids file(GLOB) for source lists in most cases but uses CONFIGURE_DEPENDS to mitigate its drawbacks here.
    • Generator expressions ensure flags are applied conditionally without polluting other configurations/platforms.

Key Concepts from Chapter 7 Reinforced:

  1. Generator Expressions: Used extensively for conditional logic based on build type, platform, and compiler.
  2. Precompiled Headers: Leveraged via target_precompile_headers with compiler-specific logic abstracted by CMake.
  3. Build Optimization: Unity builds and LTO demonstrate advanced techniques to reduce compilation time.
  4. Platform/Compiler Portability: Solutions avoid hardcoding flags, using CMake variables (PLATFORM_ID, CXX_COMPILER_ID) instead.
  5. Modern CMake Practices: Use of target_* commands ensures properties propagate correctly to dependents.

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

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

相关文章

怎么检查网站CDN缓存是否生效

为什么要使用CDN缓存&#xff1f; 网站使用缓存可显著提升加载速度&#xff0c;减少服务器负载和带宽消耗&#xff0c;优化用户体验&#xff0c;增强架构稳定性&#xff0c;助力SEO优化&#xff0c;实现资源高效利用与性能平衡。 通过合理配置 CDN 缓存策略&#xff0c;可降低…

【自然语言处理】深度学习中文本分类实现

文本分类是NLP中最基础也是应用最广泛的任务之一&#xff0c;从无用的邮件过滤到情感分析&#xff0c;从新闻分类到智能客服&#xff0c;都离不开高效准确的文本分类技术。本文将带您全面了解文本分类的技术演进&#xff0c;从传统机器学习到深度学习&#xff0c;手把手实现一套…

vba讲excel转换为word

VBA将excel转换为word Sub ExportToWordFormatted() 声明变量Dim ws As Worksheet 用于存储当前活动的工作表Dim rng As Range 用于存储工作表的使用范围&#xff08;即所有有数据的单元格&#xff09;Dim rowCount As Long, colCount As Long 用于存储数据范围的行数和列数…

ubuntu安装openWebUI和Dify【自用详细版】

系统版本&#xff1a;ubuntu24.04LTS 显卡&#xff1a;4090 48G 前期准备 先安装好docker和docker-compose&#xff0c;可以参考我之前文章安装&#xff1a; ubuntu安装docker和docker-compose【简单详细版】 安装openWebUI 先docker下载ollama docker pull ghcr.nju.edu.c…

基于Flask的勒索病毒应急响应平台架构设计与实践

基于Flask的勒索病毒应急响应平台架构设计与实践 序言&#xff1a;安全工程师的防御视角 作为从业十年的网络安全工程师&#xff0c;我深刻理解勒索病毒防御的黄金时间法则——应急响应速度每提升1分钟&#xff0c;数据恢复成功率将提高17%。本文介绍的应急响应平台&#xff…

spark数据清洗案例:流量统计

一、项目背景 在互联网时代&#xff0c;流量数据是反映用户行为和业务状况的重要指标。通过对流量数据进行准确统计和分析&#xff0c;企业可以了解用户的访问习惯、业务的热门程度等&#xff0c;从而为决策提供有力支持。然而&#xff0c;原始的流量数据往往存在格式不规范、…

list的使用以及模拟实现

本章目标 1.list的使用 2.list的模拟实现 1.list的使用 在stl中list是一个链表,并且是一个双向带头循环链表,这种结构的链表是最优结构. 因为它的实现上也是一块线性空间,它的使用上是与string和vector类似的.但相对的因为底层物理结构上它并不像vector是线性连续的,它并没有…

【今日三题】小乐乐改数字 (模拟) / 十字爆破 (预处理+模拟) / 比那名居的桃子 (滑窗 / 前缀和)

⭐️个人主页&#xff1a;小羊 ⭐️所属专栏&#xff1a;每日两三题 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 小乐乐改数字 (模拟)十字爆破 (预处理模拟&#xff09;比那名居的桃子 (滑窗 / 前缀和) 小乐乐改数字 (模拟) 小乐乐改数字…

基于 Qt 的图片处理工具开发(一):拖拽加载与基础图像处理功能实现

一、引言 在桌面应用开发中&#xff0c;图片处理工具的核心挑战在于用户交互的流畅性和异常处理的健壮性。本文以 Qt为框架&#xff0c;深度解析如何实现一个支持拖拽加载、亮度调节、角度旋转的图片处理工具。通过严谨的文件格式校验、分层的架构设计和用户友好的交互逻辑&am…

44、Spring Boot 详细讲义(一)

Spring Boot 详细讲义 目录 Spring Boot 简介Spring Boot 快速入门Spring Boot 核心功能Spring Boot 技术栈与集成Spring Boot 高级主题Spring Boot 项目实战Spring Boot 最佳实践总结 一、Spring Boot 简介 1. Spring Boot 概念和核心特点 1.1、什么是 Spring Boot&#…

虽然理解git命令,但是我选择vscode插件!

文章目录 2025/3/11 补充一个项目一个窗口基本操作注意 tag合并冲突已有远程&#xff0c;新加远程仓库切换分支stash 只要了解 git 的小伙伴&#xff0c;应该都很熟悉这些指令&#xff1a; git init – 初始化git仓库git add – 把文件添加到仓库git commit – 把文件提交到仓库…

idea 打不开terminal

IDEA更新到2024.3后Terminal终端打不开的问题_idea terminal打不开-CSDN博客

【JVM】JVM调优实战

&#x1f600;大家好&#xff0c;我是白晨&#xff0c;一个不是很能熬夜&#x1f62b;&#xff0c;但是也想日更的人✈。如果喜欢这篇文章&#xff0c;点个赞&#x1f44d;&#xff0c;关注一下&#x1f440;白晨吧&#xff01;你的支持就是我最大的动力&#xff01;&#x1f4…

FPGA_DDR(二)

在下板的时候遇到问题 1&#xff1a;在写一包数据后再读&#xff0c;再写再读 这时候读无法读出 查看时axi_arready没有拉高 原因 &#xff1a; 由于读地址后没有拉高rready,导致数据没有读出卡死现象。 解决结果

【吾爱出品】[Windows] 鼠标或键盘可自定义可同时多按键连点工具

[Windows] 鼠标或键盘连点工具 链接&#xff1a;https://pan.xunlei.com/s/VONSFKLNpyVDeYEmOCBY3WZJA1?pwduik5# [Windows] 鼠标或键盘可自定义可同时多按键连点工具 就是个连点工具&#xff0c;功能如图所示&#xff0c;本人系统win11其他系统未做测试&#xff0c;自己玩…

vue3实战一、管理系统之实战立项

目录 管理系统之实战立项对应相关文章链接入口&#xff1a;实战效果登录页&#xff1a;动态菜单&#xff1a;动态按钮权限白天黑夜模式&#xff1a;全屏退出全屏退出登录&#xff1a;菜单收缩&#xff1a; 管理系统之实战立项 vue3实战一、管理系统之实战立项&#xff1a;这个项…

设计模式 Day 6:深入讲透观察者模式(真实场景 + 回调机制 + 高级理解)

观察者模式&#xff08;Observer Pattern&#xff09;是一种设计结构中最实用、最常见的行为模式之一。它的魅力不仅在于简洁的“一对多”事件推送能力&#xff0c;更在于它的解耦能力、模块协作设计、实时响应能力。 本篇作为 Day 6&#xff0c;将带你从理论、底层机制到真实…

汽车软件开发常用的需求管理工具汇总

目录 往期推荐 DOORS&#xff08;IBM &#xff09; 行业应用企业&#xff1a; 应用背景&#xff1a; 主要特点&#xff1a; Polarion ALM&#xff08;Siemens&#xff09; 行业应用企业&#xff1a; 应用背景&#xff1a; 主要特点&#xff1a; Codebeamer ALM&#x…

AI 越狱技术剖析:原理、影响与防范

一、AI 越狱技术概述 AI 越狱是指通过特定技术手段&#xff0c;绕过人工智能模型&#xff08;尤其是大型语言模型&#xff09;的安全防护机制&#xff0c;使其生成通常被禁止的内容。这种行为类似于传统计算机系统中的“越狱”&#xff0c;旨在突破模型的限制&#xff0c;以实…

推荐一款Nginx图形化管理工具: NginxWebUI

Nginx Web UI是一款专为Nginx设计的图形化管理工具&#xff0c;旨在简化Nginx的配置与管理过程&#xff0c;提高开发者和系统管理的工作效率。项目地址&#xff1a;https://github.com/cym1102/nginxWebUI 。 一、Nginx WebUI的主要特点 简化配置&#xff1a;通过图形化的界…