当前位置: 首页 > news >正文

02 Cmake(全)

CMake 系统学习指南

第一部分:CMake 基础概念

1.1 什么是 CMake?

CMake 是一个跨平台的构建系统生成器。它不直接构建项目,而是生成平台特定的构建文件:

  • Linux/Unix: 生成 Makefile
  • Windows: 生成 Visual Studio 项目文件
  • macOS: 生成 Xcode 项目文件

1.2 为什么使用 CMake?

  1. 跨平台: 一份 CMakeLists.txt 可以在不同平台生成构建文件
  2. 依赖管理: 自动查找库、头文件路径
  3. 现代 C++ 支持: 支持 C++11/14/17/20 标准
  4. CUDA 支持: 原生支持 CUDA 项目构建
  5. IDE 集成: CLion、VSCode、Visual Studio 都支持

1.3 CMake 构建流程

CMakeLists.txt → CMake 配置 → 生成构建文件 → 编译链接 → 可执行文件(源文件)      (cmake)      (Makefile)      (make)      (./app)

两个阶段

  1. 配置阶段: cmake .. - 读取 CMakeLists.txt,生成构建文件
  2. 构建阶段: make - 编译链接生成目标

第二部分:CMake 基础语法

2.1 最简单的 CMakeLists.txt

# 指定 CMake 最低版本
cmake_minimum_required(VERSION 3.10)# 项目名称
project(MyProject)# 生成可执行文件
add_executable(myapp main.cpp)

2.2 常用命令详解

2.2.1 cmake_minimum_required

cmake_minimum_required(VERSION 3.10)
cmake_minimum_required(VERSION 3.10...3.20)  # 支持 3.10 到 3.20

作用: 指定运行此 CMakeLists.txt 所需的最低 CMake 版本。

2.2.2 project

project(MyProject)                    # 最简形式
project(MyProject VERSION 1.0.0)      # 指定版本
project(MyProject LANGUAGES CXX)      # 指定语言
project(MyProject VERSION 1.0.0 LANGUAGES CXX CUDA                # 支持 C++ 和 CUDADESCRIPTION "A CUDA learning project"
)

project() 会设置以下变量

  • PROJECT_NAME: 项目名称
  • PROJECT_VERSION: 项目版本
  • PROJECT_SOURCE_DIR: 项目源码目录
  • PROJECT_BINARY_DIR: 项目构建目录

2.2.3 add_executable

# 基本用法
add_executable(myapp main.cpp)# 多个源文件
add_executable(myapp main.cpp utils.cpp helper.cpp
)# 使用变量
set(SOURCES main.cpp utils.cpp helper.cpp)
add_executable(myapp ${SOURCES})

2.2.4 add_library

# 静态库 (libmylib.a 或 mylib.lib)
add_library(mylib STATIC lib.cpp)# 动态库 (libmylib.so 或 mylib.dll)
add_library(mylib SHARED lib.cpp)# 默认 (通常为静态库)
add_library(mylib lib.cpp)
# 链接库到可执行文件
add_executable(myapp main.cpp)
add_library(mylib lib.cpp)
target_link_libraries(myapp mylib)# 链接系统库
target_link_libraries(myapp pthread)
target_link_libraries(myapp cuda)

第三部分:CMake 变量

3.1 变量定义和使用

# 定义变量
set(MY_VAR "Hello")
set(SOURCES main.cpp utils.cpp)# 使用变量
message(STATUS "MY_VAR = ${MY_VAR}")
add_executable(myapp ${SOURCES})# 追加变量
set(SOURCES ${SOURCES} helper.cpp)
list(APPEND SOURCES extra.cpp)  # 推荐

3.2 CMake 内置变量

# 项目相关
PROJECT_NAME          # 项目名称
PROJECT_SOURCE_DIR    # 项目源码目录
PROJECT_BINARY_DIR    # 项目构建目录# 构建类型
CMAKE_BUILD_TYPE      # Debug, Release, RelWithDebInfo, MinSizeRel# 编译器相关
CMAKE_CXX_COMPILER    # C++ 编译器路径
CMAKE_CUDA_COMPILER   # CUDA 编译器路径# 标准相关
CMAKE_CXX_STANDARD    # C++ 标准版本 (11, 14, 17, 20)
CMAKE_CXX_STANDARD_REQUIRED  # 强制使用指定标准 (ON/OFF)
CMAKE_CXX_EXTENSIONS # 启用编译器扩展 (ON/OFF)# 安装路径
CMAKE_INSTALL_PREFIX  # 安装前缀 (/usr/local)

3.3 设置 C++ 标准

# 方法 1: 使用变量
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)# 方法 2: 使用 target (推荐)
add_executable(myapp main.cpp)
set_target_properties(myapp PROPERTIESCXX_STANDARD 17CXX_STANDARD_REQUIRED ONCXX_EXTENSIONS OFF
)

第四部分:构建目标详解

4.1 可执行文件

add_executable(myapp main.cpp)# 设置输出目录
set_target_properties(myapp PROPERTIESRUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin
)# 设置输出名称
set_target_properties(myapp PROPERTIESOUTPUT_NAME "my_application"
)

4.2 库文件

# 创建库
add_library(mylib STATIC lib.cpp)# 设置库输出目录
set_target_properties(mylib PROPERTIESLIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/libARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib
)# 创建头文件库 (header-only library)
add_library(mylib INTERFACE)
target_include_directories(mylib INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include)

4.3 链接库

# 创建库
add_library(mathlib STATIC math.cpp)# 创建可执行文件并链接库
add_executable(calculator main.cpp)
target_link_libraries(calculator mathlib)# 链接可见性
target_link_libraries(calculatorPUBLIC mathlib       # 传递给依赖此目标的其他目标PRIVATE threadlib    # 仅用于此目标INTERFACE apilib     # 仅用于依赖此目标的其他目标
)

第五部分:条件判断和循环

5.1 条件判断

# if-else-endif
if(CMAKE_BUILD_TYPE STREQUAL "Debug")message(STATUS "Debug 模式")add_definitions(-DDEBUG)
else()message(STATUS "Release 模式")
endif()# 检查变量
if(ENABLE_CUDA)enable_language(CUDA)
endif()# 检查操作系统
if(WIN32)message(STATUS "Windows 平台")
elseif(UNIX)message(STATUS "Unix/Linux 平台")
elseif(APPLE)message(STATUS "macOS 平台")
endif()# 逻辑运算
if(ENABLE_CUDA AND CUDA_FOUND)message(STATUS "CUDA 已启用且找到")
endif()if(USE_OPENMP OR USE_TBB)message(STATUS "并行库已启用")
endif()

5.2 循环

# foreach 循环
set(SOURCES a.cpp b.cpp c.cpp)
foreach(SRC ${SOURCES})message(STATUS "源文件: ${SRC}")
endforeach()# 数字循环
foreach(i RANGE 1 5)message(STATUS "数字: ${i}")
endforeach()# while 循环
set(COUNT 0)
while(COUNT LESS 5)message(STATUS "计数: ${COUNT}")math(EXPR COUNT "${COUNT} + 1")
endwhile()

第六部分:函数和宏

6.1 函数

# 定义函数
function(add_my_executable NAME)message(STATUS "创建可执行文件: ${NAME}")add_executable(${NAME} ${ARGN})  # ARGN 包含额外参数
endfunction()# 使用函数
add_my_executable(myapp main.cpp utils.cpp)

6.2 宏

# 定义宏
macro(print_var VAR_NAME)message(STATUS "${VAR_NAME} = ${${VAR_NAME}}")
endmacro()# 使用宏
set(MY_VALUE 42)
print_var(MY_VALUE)  # 输出: MY_VALUE = 42

6.3 函数 vs 宏

区别

  • 函数: 有自己的作用域,内部变量不影响外部
  • : 在调用者的作用域中展开,内部变量会影响外部
function(test_func)set(VAR "function")  # 不影响外部
endfunction()macro(test_macro)set(VAR "macro")     # 会影响外部
endmacro()set(VAR "original")
test_func()
message(STATUS "After function: ${VAR}")  # originaltest_macro()
message(STATUS "After macro: ${VAR}")     # macro

第七部分:查找包和依赖管理

7.1 find_package

# 查找包
find_package(CUDA REQUIRED)
find_package(OpenCV REQUIRED)
find_package(Boost 1.70 REQUIRED COMPONENTS filesystem system)# 检查是否找到
if(CUDA_FOUND)message(STATUS "CUDA 版本: ${CUDA_VERSION}")message(STATUS "CUDA 编译器: ${CUDA_COMPILER}")
endif()# 使用找到的包
target_link_libraries(myapp ${CUDA_LIBRARIES})
target_include_directories(myapp ${CUDA_INCLUDE_DIRS})

7.2 find_library 和 find_path

# 查找库文件
find_library(MATH_LIB m)  # 查找 libm.so 或 libm.a
if(MATH_LIB)target_link_libraries(myapp ${MATH_LIB})
endif()# 查找头文件路径
find_path(MATH_INCLUDE_DIR math.h)
if(MATH_INCLUDE_DIR)target_include_directories(myapp ${MATH_INCLUDE_DIR})
endif()

7.3 包配置模式

# 使用 Config 模式(推荐)
find_package(CUDA REQUIRED)# 创建导入目标
add_executable(myapp main.cpp)
target_link_libraries(myapp CUDA::cudart)  # 现代 CMake 方式

第八部分:CMake 与 CUDA 集成

8.1 启用 CUDA 支持

cmake_minimum_required(VERSION 3.10)
project(MyCUDAProject LANGUAGES CXX CUDA)# 或者动态启用
project(MyProject LANGUAGES CXX)
enable_language(CUDA)

8.2 CUDA 源文件编译

# 方法 1: 直接添加 .cu 文件
add_executable(myapp main.cpp kernel.cu)# 方法 2: 使用变量分离
set(CPP_SOURCES main.cpp utils.cpp)
set(CUDA_SOURCES kernel.cu helper.cu)
add_executable(myapp ${CPP_SOURCES} ${CUDA_SOURCES})

8.3 CUDA 编译选项

# 设置 CUDA 架构
set(CMAKE_CUDA_ARCHITECTURES 75 86)  # SM 75 (Turing), SM 86 (Ampere)# 或者针对特定目标设置
set_target_properties(myapp PROPERTIESCUDA_ARCHITECTURES "75;86"
)# 设置 CUDA 标准
set(CMAKE_CUDA_STANDARD 17)
set(CMAKE_CUDA_STANDARD_REQUIRED ON)# CUDA 编译器标志
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -O3")
set(CMAKE_CUDA_FLAGS_DEBUG "-G -g")  # Debug 模式
set(CMAKE_CUDA_FLAGS_RELEASE "-O3")  # Release 模式

8.4 CUDA 库链接

# 链接 CUDA 运行时库
target_link_libraries(myapp CUDA::cudart)# 链接 CUDA 库
target_link_libraries(myapp CUDA::cublas CUDA::cufft)# 链接 cuDNN(需要先找到)
find_package(CUDNN REQUIRED)
target_link_libraries(myapp CUDA::cudnn)

8.5 分离 CUDA 和 C++ 代码

# 创建 CUDA 库
add_library(cudakernel STATIC kernel.cu)
target_include_directories(cudakernel PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(cudakernel CUDA::cudart)# 创建 C++ 可执行文件
add_executable(myapp main.cpp)
target_link_libraries(myapp cudakernel)

第九部分:现代 CMake 最佳实践

9.1 使用 target_* 命令

传统方式(不推荐)

include_directories(/usr/include)
link_directories(/usr/lib)
add_definitions(-DDEBUG)

现代方式(推荐)

target_include_directories(myapp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_link_directories(myapp PRIVATE /usr/lib)
target_compile_definitions(myapp PRIVATE DEBUG)

9.2 可见性修饰符

target_include_directories(myappPUBLIC     # 对当前目标和依赖者都可见${CMAKE_CURRENT_SOURCE_DIR}/includePRIVATE    # 仅对当前目标可见${CMAKE_CURRENT_SOURCE_DIR}/srcINTERFACE  # 仅对依赖者可见${CMAKE_CURRENT_SOURCE_DIR}/api
)

9.3 Generator Expressions

# 根据构建类型设置不同选项
target_compile_options(myapp PRIVATE$<$<CONFIG:Debug>:-g -O0>$<$<CONFIG:Release>:-O3>
)# 根据编译器设置选项
target_compile_options(myapp PRIVATE$<$<CXX_COMPILER_ID:GNU>:-Wall>$<$<CXX_COMPILER_ID:Clang>:-Weverything>
)# 平台特定设置
target_compile_definitions(myapp PRIVATE$<$<PLATFORM_ID:Windows>:WINDOWS_BUILD>$<$<PLATFORM_ID:Linux>:LINUX_BUILD>
)

9.4 属性设置

# 设置目标属性
set_target_properties(myapp PROPERTIESCXX_STANDARD 17CXX_STANDARD_REQUIRED ONCUDA_STANDARD 17CUDA_STANDARD_REQUIRED ONCUDA_ARCHITECTURES "75;86"OUTPUT_NAME "my_application"RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin
)# 获取属性
get_target_property(OUTPUT_NAME myapp OUTPUT_NAME)
message(STATUS "输出名称: ${OUTPUT_NAME}")

第十部分:实际项目示例

10.1 你的 CUDA 项目改进版

cmake_minimum_required(VERSION 3.18)
project(HelloWorld VERSION 1.0.0LANGUAGES CXX CUDADESCRIPTION "CUDA Hello World 示例"
)# 设置 C++ 和 CUDA 标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CUDA_STANDARD 17)
set(CMAKE_CUDA_STANDARD_REQUIRED ON)# 设置 CUDA 架构(根据你的 GPU 选择)
# SM 75: Turing (RTX 20xx, GTX 16xx)
# SM 80: Ampere (RTX 30xx, A100)
# SM 86: Ampere (RTX 30xx mobile)
# SM 89: Ada Lovelace (RTX 40xx)
set(CMAKE_CUDA_ARCHITECTURES 75 86)# 编译选项
if(MSVC)add_compile_options(/W4)
else()add_compile_options(-Wall -Wextra -Wpedantic)
endif()# 创建可执行文件
add_executable(hello_world hello_world.cu)# 链接 CUDA 运行时
target_link_libraries(hello_world CUDA::cudart)# 设置输出目录
set_target_properties(hello_world PROPERTIESRUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin
)# 打印配置信息
message(STATUS "项目名称: ${PROJECT_NAME}")
message(STATUS "项目版本: ${PROJECT_VERSION}")
message(STATUS "C++ 标准: ${CMAKE_CXX_STANDARD}")
message(STATUS "CUDA 标准: ${CMAKE_CUDA_STANDARD}")
message(STATUS "CUDA 架构: ${CMAKE_CUDA_ARCHITECTURES}")

10.2 多文件 CUDA 项目

cmake_minimum_required(VERSION 3.18)
project(MyCUDAApp LANGUAGES CXX CUDA)# 标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CUDA_STANDARD 17)
set(CMAKE_CUDA_ARCHITECTURES 75 86)# 源文件
set(CPP_SOURCESmain.cpputils.cpp
)set(CUDA_SOURCESkernel.cuhelper.cu
)# 创建 CUDA 库
add_library(cudakernel STATIC ${CUDA_SOURCES})
target_include_directories(cudakernel PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_link_libraries(cudakernel PUBLIC CUDA::cudart)# 创建可执行文件
add_executable(myapp ${CPP_SOURCES})
target_link_libraries(myapp PRIVATE cudakernel)# 输出目录
set_target_properties(myapp PROPERTIESRUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin
)

第十一部分:常用命令速查

11.1 文件操作

# 读取文件
file(READ "config.txt" CONFIG_CONTENT)# 写入文件
file(WRITE "output.txt" "Hello, CMake!")# 查找文件
file(GLOB SOURCES "src/*.cpp")
file(GLOB_RECURSE SOURCES "src/**/*.cpp")  # 递归查找# 创建目录
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/output)# 复制文件
file(COPY ${PROJECT_SOURCE_DIR}/data DESTINATION ${PROJECT_BINARY_DIR})

11.2 字符串操作

# 字符串拼接
set(FULL_NAME "${FIRST_NAME} ${LAST_NAME}")# 字符串替换
string(REPLACE "old" "new" NEW_STRING ${OLD_STRING})# 字符串长度
string(LENGTH ${MY_STRING} STRING_LENGTH)# 子字符串
string(SUBSTRING ${MY_STRING} 0 5 SUB_STR)# 转换为大写/小写
string(TOUPPER ${MY_STRING} UPPER_STRING)
string(TOLOWER ${MY_STRING} LOWER_STRING)

11.3 列表操作

# 创建列表
set(MY_LIST a b c d)# 追加元素
list(APPEND MY_LIST e f)# 插入元素
list(INSERT MY_LIST 2 x)  # 在索引 2 处插入 x# 删除元素
list(REMOVE_ITEM MY_LIST b)
list(REMOVE_AT MY_LIST 0)  # 删除索引 0 的元素# 列表长度
list(LENGTH MY_LIST LIST_LENGTH)# 获取元素
list(GET MY_LIST 0 FIRST_ITEM)# 连接列表
string(JOIN " " JOINED_STRING ${MY_LIST})

11.4 消息输出

# 不同级别的消息
message(STATUS "普通信息")
message(WARNING "警告信息")
message(SEND_ERROR "错误信息,继续处理")
message(FATAL_ERROR "致命错误,停止处理")# 调试输出
message(STATUS "变量值: ${MY_VAR}")
message(STATUS "列表: ${MY_LIST}")

第十二部分:构建和安装

12.1 构建类型

# 设置默认构建类型
if(NOT CMAKE_BUILD_TYPE)set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
endif()# 不同构建类型的编译选项
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DNDEBUG")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")

12.2 安装规则

# 安装可执行文件
install(TARGETS myappRUNTIME DESTINATION bin
)# 安装库文件
install(TARGETS mylibLIBRARY DESTINATION libARCHIVE DESTINATION lib
)# 安装头文件
install(FILES ${PROJECT_SOURCE_DIR}/include/mylib.hDESTINATION include
)# 安装整个目录
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/DESTINATION include
)

12.3 自定义目标

# 添加自定义命令
add_custom_command(OUTPUT generated.hCOMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/generate.pyDEPENDS generate.pyCOMMENT "生成头文件"
)# 添加自定义目标
add_custom_target(generateCOMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/generate.pyCOMMENT "运行生成脚本"
)# 添加依赖
add_dependencies(myapp generate)

第十三部分:调试和故障排除

13.1 查看变量

# 打印所有缓存变量
get_cmake_property(_variableNames VARIABLES)
foreach(_variableName ${_variableNames})message(STATUS "${_variableName}=${${_variableName}}")
endforeach()# 打印特定变量
message(STATUS "CMAKE_CXX_COMPILER = ${CMAKE_CXX_COMPILER}")
message(STATUS "CMAKE_CUDA_COMPILER = ${CMAKE_CUDA_COMPILER}")

13.2 查看目标属性

# 获取目标属性
get_target_property(INCLUDE_DIRS myapp INCLUDE_DIRECTORIES)
message(STATUS "包含目录: ${INCLUDE_DIRS}")get_target_property(LINK_LIBS myapp LINK_LIBRARIES)
message(STATUS "链接库: ${LINK_LIBS}")

13.3 调试构建过程

# 详细输出
cmake .. -DCMAKE_VERBOSE_MAKEFILE=ON# 或者使用 make
make VERBOSE=1# 查看编译命令
ninja -v  # 如果使用 Ninja

第十四部分:进阶主题

14.1 CMake 模块

# 包含模块
include(CheckCXXCompilerFlag)# 检查编译器标志
check_cxx_compiler_flag("-std=c++17" COMPILER_SUPPORTS_CXX17)
if(COMPILER_SUPPORTS_CXX17)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
endif()# 自定义模块
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
include(MyCustomModule)

14.2 测试支持

enable_testing()add_executable(test_myapp test.cpp)
target_link_libraries(test_myapp mylib)add_test(NAME MyTest COMMAND test_myapp)# 设置测试属性
set_tests_properties(MyTest PROPERTIESTIMEOUT 10LABELS "unit"
)

14.3 打包

# 设置 CPack
set(CPACK_PACKAGE_NAME "MyApp")
set(CPACK_PACKAGE_VERSION "1.0.0")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "My Application")# 包含 CPack
include(CPack)

第十五部分:学习路径建议

15.1 初级阶段

  1. ✅ 理解 CMake 基本概念和构建流程
  2. ✅ 学会编写简单的 CMakeLists.txt
  3. ✅ 掌握 add_executable、add_library、target_link_libraries
  4. ✅ 理解变量和基本语法

15.2 中级阶段

  1. ⬜ 学习 find_package 和依赖管理
  2. ⬜ 掌握条件判断和循环
  3. ⬜ 理解现代 CMake 的 target_* 命令
  4. ⬜ 学会使用 Generator Expressions

15.3 高级阶段

  1. ⬜ 编写自定义 CMake 模块
  2. ⬜ 理解 CMake 内部机制
  3. ⬜ 掌握跨平台构建技巧
  4. ⬜ 学习 CMake 测试和打包

附录:常用资源

官方文档

  • CMake 官方文档: https://cmake.org/documentation/
  • CMake 教程: https://cmake.org/cmake/help/latest/guide/tutorial/

学习资源

  • Modern CMake: https://cliutils.gitlab.io/modern-cmake/
  • CMake 最佳实践: https://github.com/cpp-best-practices/cppbestpractices

CUDA 相关

  • CMake CUDA 支持: https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#cuda
  • NVIDIA CMake 示例: https://github.com/NVIDIA/cuda-samples

练习建议

  1. 从简单开始: 先创建一个最简单的 CMake 项目
  2. 逐步增加复杂度: 添加库、多文件、CUDA 支持
  3. 实践你的项目: 改进现有的 CUDA 项目 CMake 配置
  4. 阅读优秀项目: 查看开源项目的 CMakeLists.txt
http://www.jsqmd.com/news/770004/

相关文章:

  • EAGLE框架:多模态大模型的可解释性生成技术解析
  • 为什么83%的组织在AISMM L2评估中卡在“治理成熟度”?SITS2026首席评估师亲授4个可验证证据构建模板
  • 3大突破性AI能力重塑Unreal Engine 5游戏开发工作流
  • 别再傻傻分不清!PCB设计中的‘爬’与‘飞’:手把手教你搞定安规间距
  • Flutter GPT Box:构建原生跨平台AI助手,打造高效对话工作流
  • 不止是显示图片:用MicroPython玩转ESP32上的ST7735S屏幕,还能做这些事
  • Android Studio布局避坑指南:TableLayout的列宽控制和FrameLayout的层级覆盖问题
  • Cell|化学结构基因表达谱预测
  • 2026 南京墙面刷新|旧房改造・局部装修 5 家正规企业排行 + 避坑攻略 - 速递信息
  • AI学习路线图:从零基础到工程实践的系统指南
  • LxRunOffline:Windows WSL离线安装与高效管理的完整解决方案
  • 前端安全必修课:你的Next.js/Vue项目Referrer Policy配对了吗?
  • 为AI助手集成BigDataCloud MCP Server:实现IP定位与数据验证
  • 开源协作团队构建指南:从理念到实践的高效运作
  • 如何突破平台限制:一站式免费获取Steam创意工坊模组终极指南
  • YoloMouse终极指南:如何让游戏鼠标指针在Windows中变得清晰可见
  • 炉石传说脚本完整指南:如何快速配置智能自动化对战工具
  • 【OpenClaw从入门到精通】第74篇:30天OpenClaw实战挑战——从零搭建个人数字助理(Day 22-30)(2026万字超详细实战版)
  • 终极TigerVNC远程桌面完整指南:15分钟实现跨平台高效连接
  • BilibiliDown高效下载指南:一站式B站视频离线解决方案
  • 三步骤革新:用LocalVocal打造零成本、零隐私泄露的实时字幕革命
  • #2026全国国内液位计企业实力排行榜:技术领先性能可靠,基于工业测量需求的十大权威推荐榜单 - 十大品牌榜
  • 3分钟搞定!APK-Installer:Windows上最轻量的安卓应用安装神器
  • 2026年新疆办公用纸与热敏收银纸采购完全指南:五大品牌对标与成本优化方案 - 企业名录优选推荐
  • Python 的 Excel/Word 库
  • BilibiliDown:终极免费B站视频下载器,快速打造你的离线视频库
  • 2026 珠三角设备租赁王者榜:高空 / 防撞车出租前三强,大牌设备、严保严训 - 广州搬家老班长
  • XGBoost分类任务避坑指南:处理时序数据标签不平衡与评估陷阱(附Python代码)
  • #2026全国变送器企业实力排行榜:技术领先性能可靠,基于工业测控能力的十大权威推荐榜单 - 十大品牌榜
  • 3步快速上手:中兴光猫配置解密工具完整使用指南