现代CMake高级教程 - 第 4 章:对象的属性

news2024/12/26 5:57:40

双笙子佯谬老师的【公开课】现代CMake高级教程课程笔记

第 4 章:对象的属性

除了 POSITION_INDEPENDENT_CODE 还有哪些这样的属性?

add_executable(main main.cpp)

set_property(TARGET main PROPERTY CXX_STANDARD 17)				# 采用 C++17 标准进行编译(默认 11)
set_property(TARGET main PROPERTY CXX_STANDARD_REQUIRED ON)  	# 如果编译器不支持 C++17,则直接报错(默认 OFF)
set_property(TARGET main PROPERTY WIN32_EXECUTABLE ON)       # 在 Windows 系统中,运行时不启动控制台窗口,只有 GUI 界面(默认 OFF)
set_property(TARGET main PROPERTY LINK_WHAT_YOU_USE ON)      # 告诉编译器不要自动剔除没有引用符号的链接库(默认 OFF)
set_property(TARGET main PROPERTY LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)   # 设置动态链接库的输出路径(默认 ${CMAKE_BINARY_DIR})
set_property(TARGET main PROPERTY ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)   # 设置静态链接库的输出路径(默认 ${CMAKE_BINARY_DIR})
set_property(TARGET main PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)   # 设置可执行文件的输出路径(默认 ${CMAKE_BINARY_DIR})

set_target_properties 批量设置多个属性

add_executable(main main.cpp)

set_target_properties(main PROPERTIES
	CXX_STANDARD 17	# 采用 C++17 标准进行编译(默认 11)
	CXX_STANDARD_REQUIRED ON	# 如果编译器不支持 C++17,则直接报错(默认 OFF)
	WIN32_EXECUTABLE ON	# 在 Windows 系统中,运行时不启动控制台窗口,只有 GUI 界面(默认 OFF)
	LINK_WHAT_YOU_USE	# 告诉编译器不要自动剔除没有引用符号的链接库(默认 OFF)
	LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib	# 设置动态链接库的输出路径(默认 ${CMAKE_BINARY_DIR})
	ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib	# 设置静态链接库的输出路径(默认 ${CMAKE_BINARY_DIR})
	RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin	# 设置可执行文件的输出路径(默认 ${CMAKE_BINARY_DIR})
	)

通过全局的变量,让之后创建的所有对象都享有同样的属性

相当于改变了各个属性的初始默认值。要注意此时 set(CMAKE_xxx) 必须在 add_executable 之前才有效

set(CMAKE_CXX_STANDARD 17)				# 采用 C++17 标准进行编译(默认 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)  	# 如果编译器不支持 C++17,则直接报错(默认 OFF)
set(CMAKE_WIN32_EXECUTABLE ON)       # 在 Windows 系统中,运行时不启动控制台窗口,只有 GUI 界面(默认 OFF)
set(CMAKE_LINK_WHAT_YOU_USE ON)      # 告诉编译器不要自动剔除没有引用符号的链接库(默认 OFF)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)   # 设置动态链接库的输出路径(默认 ${CMAKE_BINARY_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)   # 设置静态链接库的输出路径(默认 ${CMAKE_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)   # 设置可执行文件的输出路径(默认 ${CMAKE_BINARY_DIR})

add_executable(main main.cpp)

不要使用编译器限定关键字

如果你从百度学的 CMake,你可能会犯如下的错误

对于 CXX_STANDARD 这种 CMake 本就提供了变量来设置的东西,就不要自己去设置 -std=c++17 选项,会和 CMake 自己设置好的冲突,导致出错。请始终用 CXX_STANDARD 或是全局变量 CMAKE_CXX_STANDARD 来设置 -std=c++17 这个 flag,CMake 会在配置阶段检测编译器是否支持 C++17。CUDA 的 -arch=sm_75 也是同理,请使用 CUDA_ARCHITECTURES 属性。

再说了 -std=c++17 只是 GCC 编译器的选项,无法跨平台用于 MSVC 编译器。

使用动态链接库

假如你一定要用动态链接库(Windows 对动态链接很不友好)

mylib/mylib.cpp

#include <cstdio>

#ifdef _MSC_VER
__declspec(dllexport)
#endif
void say_hello()
{
	printf("Hello, world!\n");
}

mylib/mylib.h

#pragma once

#ifdef _MSC_VER
__declspec(dllexport)
#endif
void say_hello();

mylib/CMakeLists.txt

add_library(mylib SHARED mylib.cpp mylib.h)

CMakeLists.txt

cmake_minimum_required(VERSION 3.15)

add_subdirectory(mylib)

add_executable(main main.cpp)
target_link_libraries(main PUBLIC mylib)

常见问题:链接了自己的 dll,但是为什么运行时会找不到?

这是因为你的 dll 和 exe 不在同一目录。Windows 比较蠢,他只会找当前 exe 所在目录,然后查找 PATH,找不到就报错。而你的 dll 在其他目录,因此 Windows 会找不到 dll。
解决1:把 dll 所在位置加到你的 PATH 环境变量里去,一劳永逸。
解决2:把这个 dll,以及这个 dll 所依赖的其他 dll,全部拷贝到和 exe 文件同一目录下。

手动拷贝 dll 好麻烦,能不能让 CMake 把 dll 自动生成在 exe 同一目录?

归根到底还是因为 CMake 把定义在顶层模块里的 main 放在 build/main.exe。而 mylib 因为是定义在 mylib 这个子模块里的,因此被放到了 build/mylib/mylib.dll。

解决 1:设置 mylib 对象的 xx_OUTPUT_DIRECTORY 系列属性

所以,可以设置 mylib 的这些属性,让 mylib.dll 文件输出到 PROJECT_BINARY_DIR,也就是项目根目录(main 所在的位置)。这样 main.exe 在运行时就能找到 mylib.dll 了。
是的,为了伺候这睿智的 Wendous 系统,需要设置全部 6 个属性,是不是非常繁琐?

mylib/CMakeLists.txt

add_library(mylib SHARED mylib.cpp mylib.h)
set_property(TARGET mylib PROPERTY RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
set_property(TARGET mylib PROPERTY ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
set_property(TARGET mylib PROPERTY LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
set_property(TARGET mylib PROPERTY RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_BINARY_DIR})
set_property(TARGET mylib PROPERTY ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${PROJECT_BINARY_DIR})
set_property(TARGET mylib PROPERTY LIBRARY_OUTPUT_DIRECTORY_DEBUG ${PROJECT_BINARY_DIR})
set_property(TARGET mylib PROPERTY RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_BINARY_DIR})
set_property(TARGET mylib PROPERTY ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${PROJECT_BINARY_DIR})
set_property(TARGET mylib PROPERTY LIBRARY_OUTPUT_DIRECTORY_RELEASE ${PROJECT_BINARY_DIR})

而 Linux 系统支持 RPATH,CMake 会让生成出来可执行文件的 RPATH 字段指向他链接了的 .so 文件所在目录,运行时会优先从 RPATH 里找链接库,所以即使不在同目录也能找到。

所以还有第三种解决方案:微软,我卸卸你全家(指卸载)。然后安装 Arch Linux 系统。

需要手动修改或查看一个 ELF 文件的 RPATH,可以用 chrpath 或 patchelf 命令。

❯ chrpath -l build/main
build/main: RUNPATH=/mnt/h/Code/lessonCode/CMakeLession/build
❯ ldd build/main
        linux-vdso.so.1 (0x00007ffebc63c000)
        libmylib.so => /mnt/h/Code/lessonCode/CMakeLession/build/libmylib.so (0x00007fa063d5b000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa063b29000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fa063d67000)

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

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

相关文章

STC15W104 8脚单片机串口下载程序

单片机串口下载是一种常见的单片机程序下载方式&#xff0c;它通过串口线连接单片机的串口引脚和电脑的串口接口实现。下面是单片机串口下载的基本原理和操作方法&#xff1a; 原理 确定下载模式&#xff1a;大多数单片机芯片都支持串口下载模式&#xff0c;需要在程序中设置…

常识性概念图谱建设与应用

目录 一、知识图谱背景介绍 &#xff08;一&#xff09;基本背景 &#xff08;二&#xff09;与NLP的关系 &#xff08;三&#xff09;常识性概念图谱的引入对比 二、常识性概念图谱介绍 &#xff08;一&#xff09;常识性概念图谱关系图示例 &#xff08;二&#xff09…

深度学习-tensorflow 使用keras进行深度神经网络训练

概要 深度学习网络的训练可能会很慢、也可能无法收敛&#xff0c;本文介绍使用keras进行深度神经网络训练的加速技巧&#xff0c;包括解决梯度消失和爆炸问题的策略&#xff08;参数初始化策略、激活函数策略、批量归一化、梯度裁剪&#xff09;、重用预训练层方法、更快的优化…

linux进程描述指令:ps与top

这里写自定义目录标题 一 ps指令1 ps -aux2. ps -a3. ps -u4.ps -x 二 top指令1 top2 top -d 时间3. top -i4 top -p ID 一 ps指令 1 ps -aux 显示系统中的所有进程 PID就是进程的唯一编号&#xff0c;操作系统书里有一个PCD的概念&#xff0c;就是一个标识性的控制单元 [ro…

学系统集成项目管理工程师(中项)系列16b_风险管理(下)

1. 规划风险应对 1.1. 针对项目目标&#xff0c;制订提高机会、降低威胁的方案和措施的过程 1.2. 制订风险应对措施 1.3. 制订风险应对计划 1.4. 次生风险是实施风险应对措施的直接结果 1.5. 应对措施必须与风险的重要性相匹配&#xff0c;能经济有效地应对挑战 1.5.1. 【…

项目管理-计算专题(三点估算、PERT估算)

基本概念 通过考虑估算中的不确定性和风险&#xff0c;可以提高活动持续时间估算的准确性。这个概念源自计划评审技术(PERT)。PERT使用三种估算值来界定活动持续时间的近似区间: 最可能时间(tM)&#xff1a;基于最可能获得的资源、最可能取得的资源生产率、对资源可用时间的现…

C语言CRC-16 MODBUS格式校验函数

C语言CRC-16 MODBUS格式校验函数 CRC-16校验产生2个字节长度的数据校验码&#xff0c;通过计算得到的校验码和获得的校验码比较&#xff0c;用于验证获得的数据的正确性。基本的CRC-16校验算法实现&#xff0c;参考&#xff1a; C语言标准CRC-16校验函数。 不同应用规范通过对…

Simulink 自动代码生成电机控制:弱磁控制从仿真到硬件开发板验证实验

目录 前言 仿真 生成代码在硬件上运行 总结 前言 测试了一个新的小电机&#xff0c;24V只能跑2000RPM左右&#xff0c;在此基础上测试一下弱磁控制&#xff0c;由于MTPA只适用于表贴电机&#xff0c;测试效果不能直观看出来&#xff0c;一般是通过测试效率。而前馈解耦的响…

【Paper】2019_DoS/数据注入攻击下基于一致性的信息物理系统安全性研究_曹雄

2019_DoS/数据注入攻击下基于一致性的信息物理系统安全性研究_曹雄 文章目录 第2章 拒绝服务攻击下多智能体系统安全性研究2.1 问题描述2.1.1 系统模型2.1.2 拒绝服务攻击模型 2.2 安全估计与一致性分析2.4 数值仿真2.4.1 观测器网络受到攻击下的结果及分析2.4.1.1 线性多智能体…

视频分享平台PeerTube的搭建

老苏下载了吴恩达的 Prompt for developer 课程&#xff0c;不管是否有兴趣&#xff0c;都可以看看&#xff0c;早晚我们都得学会使用 ChatGPT 虽然课程对话是英文&#xff0c;但有中文字幕&#xff0c;课程地址&#xff1a;https://www.aliyundrive.com/s/H3CpaapD87Z 这个软…

使用ChatGPT+Xmind一键生成思维导图,简直泰裤辣

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…

python 编写K210控制步进电机的程序示例

今天正好看到K210的脉冲章节&#xff0c;就顺便拿出步进电机做个小实验&#xff0c;也好巩固一下所学的知识。下面是K210关于脉冲的相关介绍&#xff1a; 构造函数 machine.PWM(tim, freq, duty, pin, enableTrue) PWM 对象在 machine 模块下 【tim】K210 的 PWM 依赖…

789. 数的范围(C++和Python3)——2023.5.3打卡

文章目录 QuestionIdeasCode Question 给定一个按照升序排列的长度为 n 的整数数组&#xff0c;以及 q 个查询。 对于每个查询&#xff0c;返回一个元素 k 的起始位置和终止位置&#xff08;位置从 0 开始计数&#xff09;。 如果数组中不存在该元素&#xff0c;则返回 -1 -…

【C++从0到王者】第二站:类和对象(上)

文章目录 一、面向过程与面向对象二、类的引入三、类的访问限定符四、类的定义五、封装六、类的作用域七、类的实例化八、类对象模型1.如何计算类对象的大小2.类对象存储方式猜测 九、this指针1.this指针的引出2.this指针的特性 一、面向过程与面向对象 C语言是面向过程的&…

Web2与Web3开发的不同之处

Web2是引入交互功能的第二代互联网&#xff0c;也是我们今天所熟悉的。随着Web的不断发展&#xff0c;第三代互联网&#xff0c;也被称为Web3&#xff0c;正处于积极开发中。Web3引入了在区块链上运行的去中心化和无需许可的系统。但是Web2和Web3开发之间有什么区别呢&#xff…

23.5.1总结

这几天都在写项目&#xff1a; 在实现页面&#xff0c;调用数据库的时候&#xff0c;总是把数据库的表改了又改&#xff0c;然后完善了下数据库的表。 存储的思路大概是&#xff1a; 一个课程下可以有多个班级&#xff0c;所以以课程id作为主键建一个表&#xff0c;内容包括…

在win11搭建ubuntu目标机器的QT开发环境的实践

环境&#xff1a; 笔记本电脑 16G内存 win11 尝试wsl的方案&#xff1a; wsl2 ubuntu gnome xrdp wsl安装ubuntu并设置gnome图形界面详细步骤&#xff08;win11ubuntu18&#xff09;_heusjh的博客-CSDN博客 wsl2 ubuntu gnome VcXsrv Windows中WSL2 配置运行GNOM…

Centos7快速安装Elasticsearch 7.17.7

从 Elasticsearch 7.x 版本开始&#xff0c;Elasticsearch 发行版包括了自己的 JDK。因此&#xff0c;您不需要单独安装 Java。以下是在 CentOS 7 上安装 Elasticsearch 7.17.7 的完整步骤&#xff1a;&#xff08;数据默认保存在/var/lib/elasticsearch下&#xff0c;自行更改…

vmware安装arch linux

vmware安装arch linux 1、下载镜像2、安装2.1、VMware 系统版本选择 其他Linux 5.x 内核 64位2.2、进行磁盘分区 3、重启系统后登录进来发现没有地址 由于安装系统时没有安装任何软件 只安装了1个vim 无法动态获取地址4、安装必需的软件 最小化安装5、编辑/etc/ssh/sshd_config…

【Python】flask框架学习 flask框架的基本使用

flask框架是什么&#xff1f; Flask 是一个轻量级的 Web 框架&#xff0c;用于构建 Web 应用程序。它基于 Python 编程语言和 Werkzeug 工具包&#xff0c;提供了简单易用的 API&#xff0c;可以轻松地创建 RESTful API 和 Web 应用程序。 flask的特点 轻量级&#xff1a;Fl…