CMake几个命令顺序

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

      • 关键顺序规则:
      • 示例说明
      • 顺序解释:
      • 错误顺序的后果:

在 CMake 中,target_include_directoriestarget_link_directoriesadd_librarytarget_link_libraries的使用存在明确的先后顺序,核心原则是:先创建目标(add_library),再配置目标的属性(target_include_directoriestarget_link_directories),最后链接依赖(target_link_libraries。同时,被链接的目标(如库)必须在链接命令之前创建。

关键顺序规则:

  1. add_library必须最先执行:因为target_*系列命令(包括target_include_directoriestarget_link_directoriestarget_link_libraries)的操作对象是“目标”(如库或可执行文件),必须先通过add_library(或add_executable用于可执行文件)创建目标,否则 CMake 会报错“目标不存在”。
  2. target_include_directoriestarget_link_directories需在目标创建后、链接前执行:这两个命令是给目标设置“编译时头文件路径”和“链接时库路径”,需要在目标被链接(target_link_libraries)前完成配置,否则可能导致编译或链接时找不到路径。
  3. target_link_libraries需在被链接的目标创建后执行:如果要链接的是通过add_library创建的自定义库,必须先通过add_library生成该库目标,再用target_link_libraries链接,否则会找不到依赖库。

示例说明

假设一个工程结构如下(多模块项目,包含一个自定义库mylib和一个依赖它的可执行文件myapp):

project/ ├── CMakeLists.txt ├── include/ # 公共头文件目录 │ └── mylib.h ├── src/ │ ├── mylib.cpp # 库的源文件 │ └── main.cpp # 可执行文件的源文件

对应的CMakeLists.txt正确顺序如下:

# 1. 最低版本要求(必须在 project 前) cmake_minimum_required(VERSION 3.10) # 2. 定义项目 project(MyProject LANGUAGES CXX) # -------------------------- # 步骤1:创建库目标(add_library 必须先执行) # -------------------------- add_library(mylib STATIC src/mylib.cpp # 库的源文件 ) # -------------------------- # 步骤2:配置库的头文件路径(target_include_directories 在目标创建后) # -------------------------- # 为 mylib 设置头文件目录,PUBLIC 表示依赖 mylib 的目标(如 myapp)会自动继承该路径 target_include_directories(mylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include # 公共头文件目录 ) # -------------------------- # 步骤3:创建可执行目标(依赖 mylib,需在链接前创建) # -------------------------- add_executable(myapp src/main.cpp # 可执行文件的源文件 ) # -------------------------- # 步骤4:(可选)配置可执行文件的链接路径(如果有额外库路径) # -------------------------- # 假设 myapp 还需要链接第三方库,其路径在 ./third_party/lib target_link_directories(myapp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/lib ) # -------------------------- # 步骤5:链接依赖库(target_link_libraries 在被链接目标创建后) # -------------------------- # 让 myapp 链接自定义库 mylib(mylib 已通过 add_library 创建) # 同时链接第三方库(如 pthread 或其他) target_link_libraries(myapp PRIVATE mylib # 自定义库(必须先通过 add_library 创建) pthread # 系统库(无需提前创建) )

顺序解释:

  1. add_library(mylib ...)先执行:创建库目标mylib,后续的target_include_directories(mylib ...)才能操作这个目标。
  2. target_include_directories(mylib ...)紧随其后:为mylib设置头文件路径,由于用了PUBLIC,后续依赖mylibmyapp会自动继承这个路径(无需再给myapp重复设置include目录)。
  3. add_executable(myapp ...)创建可执行目标myapp是最终要生成的程序,必须先创建才能对其配置链接路径和依赖。
  4. target_link_directories(myapp ...)配置链接路径:如果myapp需要链接额外的第三方库,需在链接前指定其路径(否则链接器可能找不到库文件)。
  5. target_link_libraries(myapp ...)最后链接:此时mylib已存在,myapp的链接路径也已配置,链接操作才能正常执行。

错误顺序的后果:

  • 如果在add_library(mylib)之前调用target_include_directories(mylib ...),CMake 会报错:Cannot specify include directories for target "mylib" which is not built by this project(目标不存在)。
  • 如果在add_library(mylib)之前调用target_link_libraries(myapp mylib),CMake 会报错:Target "myapp" links to target "mylib" which is not built by this project(被链接的目标不存在)。

因此,严格遵循“先创建目标 → 再配置属性 → 最后链接依赖”的顺序是保证 CMake 脚本正确执行的基础。。

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

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

相关文章

佳能主流打印机型号万能清零工具:原理与使用详解【P07/5B00解决方案指南】

佳能打印机万能清零工具:原理与使用详解【P07/5B00解决方案指南】 引言 在日常使用打印机的过程中,我们经常会遇到各种报错问题,如"P07/5B00"等。这些错误通常是由于打印机内部计数器达到预设值导致的,而非硬件故障。…

vTaskDelay在工业控制中的延时机制深度剖析

vTaskDelay在工业控制中的延时机制深度剖析:不只是“等一会儿”那么简单你有没有遇到过这样的情况?在一个电机控制任务里,明明写了vTaskDelay(10)想每10ms采样一次电流,结果发现实际周期越来越长,甚至偶尔跳变成30ms&a…

CMake工程是否引用三方库的头文件

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言具体规则:示例说明特殊情况:通过 find_package 引入的第三方库总结前言 myapp工程需要链接额外的第三方库的情况下,连接前需…

边沿触发D触发器电路图通俗解释:建立与保持时间分析

边沿触发D触发器:从电路图到建立与保持时间的实战解析你有没有遇到过这样的情况?明明逻辑写得没错,仿真也通过了,可烧进FPGA后系统却时不时“抽风”——数据错乱、状态跳变,甚至直接死机。排查半天,最后发现…

PCAN驱动开发常见问题快速理解与解决

PCAN驱动开发避坑指南:从初始化失败到高频丢包的实战解析 你有没有遇到过这样的场景? 设备插上了,驱动也装了,可 CAN_Initialize() 就是返回 PCAN_ERROR_UNKNOWN ; 程序跑着跑着突然开始“丢帧”,日…

CMake成果打包

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、基础必备文件(开发阶段)二、如果 mylib 本身依赖其他库,是否需要额外打包?1. 依赖“静态库”(.a/…

高校电工实验中Multisim元器件图标的教学实践指南

高校电工实验中,如何教学生“看懂”Multisim里的那些小图标?你有没有遇到过这样的场景:一堂《电路分析》实验课上,老师刚讲完共射放大电路的原理。学生们打开Multisim准备仿真,结果有人把电解电容接反了极性&#xff0…

深度剖析Packet Tracer汉化文件结构:技术细节公开

深度拆解 Packet Tracer 汉化机制:从文件结构到实战落地你有没有试过打开 Packet Tracer,面对满屏英文菜单时的“劝退感”?尤其是刚接触网络工程的学生,在记命令的同时还要背单词,“enable是什么?”、“con…

用于体素医学图像分割的跨视图差异-依赖网络/文献速递-基于人工智能的医学影像技术

2026.1.9该研究提出了一种名为CvDd-Net的体积医学图像分割模型,通过利用多视图切片先验,并引入差异感知形态强化(DaMR)和依赖感知信息聚合(DaIA)模块来有效捕获视图间的差异和依赖性,从而显著提…

I2C与UART对比入门:初学者的核心区别分析

I2C与UART实战入门:从连线到选型的全维度对比你有没有遇到过这种情况:手头有两个传感器,一个用I2C,一个用UART;主控芯片引脚又紧张;调试时串口输出还和另一个模块冲突……最后只能反复改电路、换引脚、加电…

或非门在工业控制中的逻辑设计:深度剖析应用原理

或非门如何成为工业控制中的“安全守护神”?在自动化车间里,一台设备突然失控,操作员按下急停按钮——千钧一发之际,是PLC程序响应?还是某个嵌入式系统从休眠中唤醒?都不是。真正起决定性作用的&#xff0c…

开源模型落地实践|Qwen2.5-7B-Instruct结构化生成全解析

开源模型落地实践|Qwen2.5-7B-Instruct结构化生成全解析 一、引言:为何结构化输出成为大模型落地的关键能力? 随着大语言模型(LLM)在企业级应用中的深入,非结构化文本生成已无法满足生产环境对数据可解析…

模拟I2C协议在远程IO模块中的操作指南

模拟I2C驱动远程IO:从原理到实战的完整指南你有没有遇到过这样的场景?主控芯片上的硬件I2C接口已经用完,但项目又急需扩展十几个数字输入输出点。或者,你在工业现场调试时发现,标准I2C通信在长线传输下频繁丢包&#x…

拒绝“天价”硬件吃灰:企业AI转型如何避开“只烧钱不落地”的深坑?

在数字化转型的浪潮下,很多企业管理者都面临着一种尴尬的“AI焦虑”:不搞AI怕被时代淘汰,搞了AI却发现是个“无底洞”。许多老板在听完各种高大上的概念后,大手一挥批预算,购买昂贵的GPU服务器、搭建复杂的机房环境。然…

基于SPICE的二极管IV特性曲线全面讲解

从零开始搞懂二极管IV曲线:用SPICE仿真揭开非线性特性的真相你有没有遇到过这种情况?设计一个电源电路时,明明理论计算没问题,可实测发现效率偏低、发热严重。排查半天,最后发现问题竟出在那个不起眼的“小二极管”上—…

Qwen2.5-7B代码解释:程序理解与注释生成

Qwen2.5-7B代码解释:程序理解与注释生成 1. 技术背景与核心价值 1.1 大模型在代码理解中的演进需求 随着软件系统复杂度的持续上升,开发者对自动化代码理解、文档生成和维护支持的需求日益迫切。传统静态分析工具虽能解析语法结构,但在语义…

RS485协议驱动开发:项目应用中的代码优化策略

RS485驱动开发实战:从时序坑点到高效通信的代码精进之路在工业现场,你是否遇到过这样的场景?系统明明运行正常,但每隔几分钟就丢一帧数据;主站轮询电表,偶尔收到乱码;多个节点同时响应&#xff…

优化I2S音频抗干扰能力:操作指南与实践

让I2S不再“咔哒”:从PCB到代码,打造抗干扰音频链路的实战笔记最近在调试一款工业级语音采集模块时,又碰上了那个老对手——I2S音频中的周期性“咔哒”声。设备一靠近变频器,声音就开始断续,像是被电磁噪声“咬了一口”…

基于MATLAB的周期方波与扫频信号生成实现(支持参数动态调整)

一、周期方波信号生成 1. 核心函数与参数 function [t, y] generate_square_wave(f, A, duty, T, fs)% 参数说明:% f: 基频 (Hz)% A: 幅值 (V)% duty: 占空比 (0-100%)% T: 信号周期 (s)% fs: 采样率 (Hz)t 0:1/fs:T; % 时间向量(覆盖1个周期…

手把手教你用Driver Store Explorer清理无效驱动

让老电脑“瘦身”成功:用这款神器精准清理Windows无效驱动 你有没有遇到过这样的情况?一台用了三四年的笔记本,SSD只有256GB,系统盘却总是提示空间不足。明明没装几个软件,杀毒扫描也没发现大文件,可 C:\…