cmake:target属性POSITION_INDEPENDENT_CODE和INTERFACE_POSITION_INDEPENDENT_CODE的区别

2023-11-15

cmake定义的target有两个名字类似的属性:POSITION_INDEPENDENT_CODEINTERFACE_POSITION_INDEPENDENT_CODE,本文说明它们的含义和区别

-fPIC

介绍POSITION_INDEPENDENT_CODEINTERFACE_POSITION_INDEPENDENT_CODE属性前先介绍一下-fPIC编译选项。
-fPIC是gcc编译器的编译参数,以下是机器人告诉我的关于-fPIC参数的作用

在GCC编译器中, -fPIC 参数是指生成位置无关代码(Position Independent Code,PIC)。位置无关代码是一种可在内存中的任何位置加载和执行的代码。它通常用于动态链接库(shared library)的编译。

使用 -fPIC 参数编译代码时,生成的目标文件中的代码和数据引用都使用相对地址,而不是绝对地址。这样,当目标文件被加载到内存中时,它可以被放置在任何可用的内存地址上,而不会发生地址冲突。

通过使用位置无关代码,可以使得动态链接库在不同的内存地址空间中被加载和共享,提供更高的灵活性和可移植性。这对于操作系统和应用程序来说是非常重要的,因为它们可以在不同的环境中加载和使用这些动态链接库,而无需担心地址冲突和重新编译的问题。

总结来说, -fPIC 参数的作用是生成位置无关代码,用于编译动态链接库,以提供更高的灵活性和可移植性。

可以看出-fPIC参数是用于动态库的编译参数。

POSITION_INDEPENDENT_CODE

定义 -fPIC 参数最直接的方式是通过CMAKE_CXX_FLAGSCMAKE_C_FLAGS参数定义,
示例如下,因为它只是clang和gcc才有的参数所以在设置-fPIC参数的时候需要判断编译器

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
endif()

但这样在跨平台项目编译时需要更多的维护工作量,为了让CMakeLists.txt脚本更简洁,减少编译器无关性,通过POSITION_INDEPENDENT_CODE属性来定义-fPIC参数是推荐的方式:
POSITION_INDEPENDENT_CODE是cmake为target定义的属性
可以通过set_property,set_target_properties函数来定义POSITION_INDEPENDENT_CODE属性

## set_property示例
set_property(TARGET my_target PROPERTY POSITION_INDEPENDENT_CODE ON)
## set_target_properties 示例
set_target_properties (my_target PROPERTIES POSITION_INDEPENDENT_CODE ON)

根据cmake官方文档说明,当target为动态库时POSITION_INDEPENDENT_CODE 默认值为True,否则为静态库时默认为False;
参见 POSITION_INDEPENDENT_CODE

CMAKE_POSITION_INDEPENDENT_CODE

注意POSITION_INDEPENDENT_CODE是target的属性,所以set_property,set_target_properties 调用只对target有效,而通过CMAKE_CXX_FLAGSCMAKE_C_FLAGS参数定义定义 -fPIC 参数对所有target有效。如果也希望一次定义所有target的POSITION_INDEPENDENT_CODE属性,则可以通过设置CMAKE_POSITION_INDEPENDENT_CODE变量来实现,用于定义所有target的POSITION_INDEPENDENT_CODE属性的默认值

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

INTERFACE_POSITION_INDEPENDENT_CODE

INTERFACE_POSITION_INDEPENDENT_CODE也是target的属性,但它的作用与POSITION_INDEPENDENT_CODE不同
INTERFACE_POSITION_INDEPENDENT_CODE 属性通知消费者(即依赖于当前target的target)是否需要将他们的 POSITION_INDEPENDENT_CODE 属性设置为ON。如果该属性被设置为ON,那么所有消费者的 POSITION_INDEPENDENT_CODE 属性也将被设置为ON。同样地,如果该属性被设置为OFF,那么所有消费者的 POSITION_INDEPENDENT_CODE 属性也将被设置为OFF。如果该属性未定义,那么消费者将通过其他方式确定他们的 POSITION_INDEPENDENT_CODE 属性。
总结就是INTERFACE_POSITION_INDEPENDENT_CODE 用于确保消费者与链接的目标的POSITION_INDEPENDENT_CODE 属性保持一致性。

简单来说就是
如果一个target定义了INTERFACE_POSITION_INDEPENDENT_CODE属性并不会影响自己的POSITION_INDEPENDENT_CODE属性,而是会影响依赖它的Target的POSITION_INDEPENDENT_CODE属性

add_library(a STATIC a.cpp)
set_target_properties (a PROPERTIES 
	POSITION_INDEPENDENT_CODE ON 
	INTERFACE_POSITION_INDEPENDENT_CODE ON)
add_library(b SHARED b.cpp)

如上示例中,静态库a设置了POSITION_INDEPENDENT_CODEONINTERFACE_POSITION_INDEPENDENT_CODEON,因为INTERFACE_POSITION_INDEPENDENT_CODE 的传递作用,
动态库b的POSITION_INDEPENDENT_CODE属性自动为ON

INTERFACE_POSITION_INDEPENDENT_CODE 属性实际只有静态库需要设置,对于动态库不需要设置该属性,因为动态库不需要依赖库保存位置无关代码(PIC)一致性

位置无关代码一致性要求

前面说了-fPIC参数是用于动态库的编译参数。但对于静态库有时也需要指定-fPIC编译出位置无关代码,因为一个动态库连接静态库时,如果其连接的静态库都不是编译为位置无关代码代码(-fPIC),则在连接阶段可能会报错:

/usr/bin/ld: …/…/static.a(file.cpp.o): relocation R_X86_64_TPOFF32 against symbol `_ZGVZN6spdlog7details2os9thread_idEvE3tid’ can not be used when making a shared object; recompile with -fPIC

参考资料

https://cmake.org/cmake/help/latest/prop_tgt/POSITION_INDEPENDENT_CODE.html
https://cmake.org/cmake/help/latest/prop_tgt/INTERFACE_POSITION_INDEPENDENT_CODE.html
https://cmake.org/cmake/help/latest/variable/CMAKE_POSITION_INDEPENDENT_CODE.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

cmake:target属性POSITION_INDEPENDENT_CODE和INTERFACE_POSITION_INDEPENDENT_CODE的区别 的相关文章

  • 在C语言中使用“void”

    我很困惑为什么我们需要通过void转换为 C 函数 int f void return 0 versus int f return 0 什么是正确的做法以及为什么 In C int f 是一种老式的声明 它说f需要固定但未指定数量和类型的参
  • OpenCv读/写视频色差

    我试图简单地使用 openCV 打开视频 处理帧并将处理后的帧写入新的视频文件 我的问题是 即使我根本不处理帧 只是打开视频 使用 VideoCapture 读取帧并使用 VideoWriter 将它们写入新文件 输出文件看起来比输入更 绿
  • 在搜索 List 时,为什么 Enumerable.Any(Func predicate) 比带有 if 语句的 foreach 慢

    最近有件事引起了我的好奇心 Why is the Enumerable Any Func
  • 为什么大多数 C 开发人员使用 Define 而不是 const? [复制]

    这个问题在这里已经有答案了 在许多程序中 define与常量具有相同的用途 例如 define FIELD WIDTH 10 const int fieldWidth 10 我通常认为第一种形式优于另一种形式 它依赖于预处理器来处理基本上是
  • 如何创建可以像 UserControl 一样编辑的 TabPage 子类?

    我想创建一个包含一些控件的 TabPage 子类 并且我想通过设计器来控制这些控件的布局和属性 但是 如果我在设计器中打开子类 我将无法像在 UserControl 上那样定位它们 我不想创建一个带有 UserControl 实例的 Tab
  • 从 MVC 迁移到 ASP.NET Core 3.1 中的端点路由时,具有角色的 AuthorizeAttribute 不起作用

    我正在尝试将我的项目从 UseMVC asp net core 2 2 兼容样式 升级到 UseEndpoint Routing 并且我的所有请求都被重定向到我的验证失败页面 它与声明有关 如果我删除 Authorize Roles Adm
  • 如何使用recv()检测客户端是否仍然连接(并且没有挂起)?

    我写了一个多客户端服务器程序C on SuSE Linux 企业服务器 12 3 x86 64 我为每个客户端使用一个线程来接收数据 我的问题是 我使用一个终端来运行服务器 并使用其他几个终端来运行服务器telnet到我的服务器 作为客户端
  • 访问者和模板化虚拟方法

    在一个典型的实现中Visitor模式 该类必须考虑基类的所有变体 后代 在许多情况下 访问者中的相同方法内容应用于不同的方法 在这种情况下 模板化的虚拟方法是理想的选择 但目前这是不允许的 那么 模板化方法可以用来解析父类的虚方法吗 鉴于
  • 检查算术运算中的溢出情况[重复]

    这个问题在这里已经有答案了 可能的重复 检测 C C 中整数溢出的最佳方法 https stackoverflow com questions 199333 best way to detect integer overflow in c
  • IronPython:没有名为 json 的模块

    我安装了 IronPython 我的 python 文件如下所示 import sys print sys version import json 运行它的代码 var p Python CreateEngine var scope p C
  • C 语言中 =+(等于加)是什么意思?

    我碰到 与标准相反 今天在一些 C 代码中 我不太确定这里发生了什么 我在文档中也找不到它 In ancientC 版本 相当于 它的残余物与最早的恐龙骨头一起被发现 例如 B 引入了广义赋值运算符 使用x y to add y to x
  • 如何将“外部模板”与由同一类中的模板化成员使用的嵌套类一起使用?

    首先 一些背景信息 我尝试以 Herb Sutter 在他的解决方案中介绍的方式使用 Pimpl 习语 得到了 101 http herbsutter com gotw 101 这在头文件中看起来像这样 include pimpl h h
  • 在 2D 中将一个点旋转另一个点

    我想知道当一个点相对于另一个点旋转一定角度时如何计算出新的坐标 我有一个块箭头 想要将其相对于箭头底部中间的点旋转角度 theta 这是允许我在两个屏幕控件之间绘制多边形所必需的 我无法使用和旋转图像 从我到目前为止所考虑的情况来看 使问题
  • 将数据打印到文件

    我已经超载了 lt lt 运算符 使其写入文件并写入控制台 我已经为同一个函数创建了 8 个线程 并且我想输出 hello hi 如果我在无限循环中运行这个线程例程 文件中的o p是 hello hi hello hi hello hi e
  • 为什么我不应该对不是由 malloc() 分配的变量调用 free() ?

    我在某处读到 使用它是灾难性的free删除不是通过调用创建的对象malloc 这是真的 为什么 这是未定义的行为 永远不要尝试它 让我们看看当您尝试时会发生什么free 自动变量 堆管理器必须推断出如何获取内存块的所有权 为此 它要么必须使
  • 通过 NHibernate 进行查询,无需 N+1 - 包含示例

    我有一个 N 1 问题 我不知道如何解决它 可以在这个问题的底部找到完全可重复的样本 因此 如果您愿意 请创建数据库 设置 NUnit 测试和所有附带的类 并尝试在本地消除 N 1 这是我遇到的真实问题的匿名版本 众所周知 这段代码对于帮助
  • 将构建日期放入“关于”框中

    我有一个带有 关于 框的 C WinForms 应用程序 我使用以下方法将版本号放入 关于 框中 FileVersionInfo GetVersionInfo Assembly GetExecutingAssembly Location F
  • 在 C 中使用 GNU automake 中的解析器

    我是 GNU autotools 的新手 在我的项目中使用了 lex 和 yacc 解析器 将它们作为 makefile am 中的源代码会产生以下错误 配置 in AC CHECK PROGS YACC bison yacc none i
  • System.Runtime.InteropServices.COMException(0x80040154):[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我在 C 项目中遇到异常 System Runtime InteropServices COMException 0x80040154 检
  • 使用 Crypto++ 获取 ECDSA 签名

    我必须使用 Crypto 在变量中获取 ECDSA 签名 我在启动 SignMessage 后尝试获取它 但签名为空 我怎样才能得到它 你看过 Crypto wiki 吗 上面有很多东西椭圆曲线数字签名算法 http www cryptop

随机推荐

  • 二分查找BinarySearch

    二分查找 在包含size个元素 从小到大排序的int数组array里查找元素p 如果找到返回下标 如果未找到返回 1 int BinarySearch int array int size int p int left 0 查找区间的左端点
  • 5.7及以上版本的MySQL下载、安装及配置教程

    对版本的说明 之所以说是MySQL5 7及以上版本 是因为从MySQL5 7版本之后 其安全机制有所改变 在安装完成后 登陆MySQL时 需要输入一个密码 这个密码其实是在配置MySQL的过程中生成的一个随机密码 而我们必须找到这个随机密码
  • Eclipse中启动Tomcat无任何反应

    推动了软件业不断发展的可以说有3个方面的东西 过程 方法 技术 方法附会到哲学上应该就是方法论了 做很多事情都是需要方法的 比如写一篇案例 随心随意写也可以写出来 但是别人能否理解 如何检测自己描述清晰都是没有参考的 如果有个模板的 这样按
  • 韩顺平_java 学习路线

    链接 目录 阶段一 Java基础 阶段二 Java高级 阶段三 Java Web 阶段四 主流框架 项目管理相关的技术 阶段五 分布式 微服务 并行架构 阶段六 DevOps 开发运维一体化 自动部署项目管理 解决 CI CD 阶段七 大数
  • 【目标检测】单阶段算法--YOLOv3详解

    论文题目 YOLOv3 An Incremental Improvement 论文地址 https pjreddie com media files papers YOLOv3 pdf 一文读懂YOLOv1 YOLOv1 一文读懂YOLOv
  • 链表(详解)

    一 链表 1 1 什么是链表 1 链表是物理存储单元上非连续的 非顺序的存储结构 数据元素的逻辑顺序是通过链表的指针地址实现 有一系列结点 地址 组成 结点可动态的生成 2 结点包括两个部分 1 存储数据元素的数据域 内存空间 2 存储指向
  • gitee最详细使用教程,汇总了全网,看这一篇就够了

    1 gitee是什么 基于git的代码托管协助平台 2 git网站上的注册登录 打开gitee官网Gitee 基于 Git 的代码托管和研发协作平台打开注册登录即可 邮箱注册最好 非邮箱在个人 设置里添加自己的邮箱 新手请公开自己的邮箱 如
  • 《Vision Transformer (ViT)》论文精度,并解析ViT模型结构以及代码实现

    AN IMAGE IS WORTH 16X16 WORDS TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE 论文共有22页 表格和图像很多 网络模型结构解释的很清楚 并且用四个公式展示了模型的计算过程
  • springboot枚举反序列化,@JsonCreator注解各种报错解决方案

    你多努力一点 获得的打击就多一点 今天使用枚举传参就出现了各种报错 比如这样的 org springframework http converter HttpMessageNotReadableException JSON parse er
  • Android Fragment之间跳转

    1 创建一个接口 public interface ChangeFragment void changge int postion 2 设置一个全局变量 public class GlobalParms private static Hom
  • OpenCV在图片中输出中文乱码解决方案

    转自 http www jeepxie net article 789204 html 一 缘起 在一个项目中需要把中文字符输出到图片上 也就是输出到Mat上 OpenCV 的putText函数不能输出中文 通过搜索 网上普遍的解决方案是使
  • C++不定参数函数实现方式

    文章目录 define 函数定义 VA LIST栈 c 11初始化列表 c 11 变长参数模板template
  • java使用jsch连接ssh服务并远程执行命令、上传、下载操作

    java使用jsch连接ssh服务并远程执行命令 上传 下载操作 关键依赖 jsch 0 1 54 jar 第一 使用用户名和密码连接 使用用户名和密码连接 Test public void test1 throws JSchExcepti
  • php开发俄罗斯方块,动手打造html5俄罗斯方块的(图文)

    在正文开始之前还要啰嗦一下 标题中所谓自给自足 是在没有参考任何设计思路的前提下去开发这游戏的 你可能会不解 如果参考优秀的思路 岂不是事半功倍 当然 参考与不参考都有利 我只说不参考的利 当我煞费苦心 历经数十个BUG修改 终于完成一件作
  • 组件化开发——组件生命周期

    最近刚刚换了工作 原来一直用angular系列 本来一直看好react的 结果facebook自己非要作死 结果就让vue直飞冲天了 现在工作中也用到vue 熟悉之余顺便记下一笔 后续可能会有weex先关的 暂且记录一下 今天看了一下vue
  • C零基础课程-13-关系运算符与关系表达式

    文章目录 C语言中的关系运算符 与 gt 与 lt gt 与 lt 关系表达式的值 初学者常见bug 错写 为 视频地址 https www bilibili com video av73897727 C语言中的关系运算符 C语言中的关系运
  • 不要再用简单的加权平均了 用回归做融合吧

  • 「总结」最全2万字长文解读7大方向人脸数据集v2.0版

    人脸图像是计算机视觉领域中研究历史最久 也是应用最广泛的图像 从人脸检测 人脸识别 人脸的年龄表情等属性识别 到人脸的三维重建等 都有非常多的数据集被不断整理提出 极大地促进了该领域的发展 本次 我们从人脸检测 关键点检测 人脸识别 人脸属
  • 【多模态】22、UniDetector

    文章目录 一 背景 二 方法 2 1 UniDetector 框架结构 2 2 Heterogeneous Label Space Training 2 3 open world inference 三 效果 3 1 数据集 3 2 Obj
  • cmake:target属性POSITION_INDEPENDENT_CODE和INTERFACE_POSITION_INDEPENDENT_CODE的区别

    cmake定义的target有两个名字类似的属性 POSITION INDEPENDENT CODE和INTERFACE POSITION INDEPENDENT CODE 本文说明它们的含义和区别 fPIC 介绍POSITION INDE