当前位置:网站首页>INSTALL_RPATH and BUILD_RPATH problem in CMake
INSTALL_RPATH and BUILD_RPATH problem in CMake
2022-08-09 06:27:00 【Ordinary people who like to play basketball】
1.RPATH和RUNPATH区别
RPATH和RUNPATHBoth can be used to search dynamic libraries at runtime.
- The following is a simple example to illustrate the difference between the two.
- eg:in a small project,有1个头文件和3个源文件.
头文件sub.h中的内容如下:
#ifndef TESTRPATH_SUB_H
#define TESTRPATH_SUB_H
void f1(void);
void f2(void);
#endif
源文件a.c中的内容如下:
#include "sub.h"
void f1(void)
{
}
源文件b.c中的内容如下:
#include "sub.h"
void f2(void)
{
f1();
}
源文件main.c中的内容如下:
#include "sub.h"
int main(void)
{
f2();
}
测试:
- 在Ubuntu16.04 + gcc5.4中编译,命令及结果如下:
[email protected]:~/TestRpath$ gcc a.c -fPIC -shared -o liba.so
[email protected]:~/TestRpath$ gcc b.c -fPIC -shared -L$PWD -la -o libb.so
[email protected]:~/TestRpath$ gcc main.c -L$PWD -Wl,-rpath,$PWD -lb
[email protected]:~/TestRpath$ ldd a.out
linux-vdso.so.1 => (0x00007ffe00568000)
libb.so => /home/madengyun/TestRpath/libb.so (0x00007f8baa94c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8baa582000)
liba.so => /home/madengyun/TestRpath/liba.so (0x00007f8baa380000)
- 在Ubuntu18.10 + gcc5.4中编译,命令及结果如下:
[email protected]:~/TestRpath$ gcc a.c -fPIC -shared -o liba.so
[email protected]:~/TestRpath$ gcc b.c -fPIC -shared -L$PWD -la -o libb.so
[email protected]:~/TestRpath$ gcc main.c -L$PWD -Wl,-rpath,$PWD -lb
[email protected]:~/TestRpath$ ldd a.out
linux-vdso.so.1 (0x00007fff635a1000)
libb.so => /home/mdy/TestRpath/libb.so (0x00007f59d326f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f59d2e7e000)
/lib64/ld-linux-x86-64.so.2 (0x00007f59d3673000)
liba.so => not found
在Ubuntu18.10中编译生成的app,ldd显示找不到liba.so.
- 但其实liba.so和libb.so在同一目录下,ldd可以找到libb.so,却找不到liba.so.
用readelf -dAnalysis of the two environments generatedapp,
- 可以看出Ubuntu16.10中生成的是RPATH,而Ubuntu18.10中生成的是RUNPATH.
解释:
- 简单地说,在搜索appWhen an indirect dependency library is used,RPATH起作用,但RUNPATH不起作用.
- 在使用RUNPATH的情况下,Possibly more cooperationLD_LIBRARY_PATH一块使用.
所以:最好使用RPATH,这样就不用依赖LD_LIBRARY_PATH了
How to control generationRPATH还是RUNPATH?
- 链接时使用–enable-new-dtagsCan be fixedRUNPATH,使用–disable-new-dtagsCan be fixedRPATH.
set_target_properties(XXX LINK_FLAGS "-Wl,--disable-new-dtags")
所以,下面仅对CMake的RPATH进行讨论
2.CMake buildremove afterRPATH
Make对于RPATHThe management is also very humane.
- The official statement is when the compilation of the dynamic library is also in the same directory as the executable file,CMakeAppropriate ones will be added to the executable file automaticallyRPATH
- 具体可以通过readelf -d executable来查看相关的RPATH路径(target_add_library就会增加RPATH到TARGET上).
所以有的时候用QMakeYou have to add it manually after compilingLD_LIBRARY_PATH,而用CMake编译之后,Just execute the executable directly. - 所以CMake搜索库的顺序如下:
搜索.so的优先级顺序
RPATH: 写在elf文件中
LD_LIBRARY_PATH: 环境变量
RUNPATH: 写在elf文件中
ldconfig的缓存: 配置/etc/ld.conf*可改变
默认的/lib, /usr/lib
CMakeIt will be given to you by defaultexe加入相关RPATH的,At this time, there may be undesired correlationsRPATH的需求,Found it after a careful search,CMake里面维护了3个比较重要的RPATH变量,即:
- CMAKE_SKIP_RPATH
- CMAKE_SKIP_BUILD_RPATH
- CMKAE_INSTALL_RPATH.
Not allowed during build and during installationCMakeAdd to youRPATH;
想要追加RPATH,Just set these three variables to FALSE
cmake -B build -DCMAKE_SKIP_RPATH=TRUE
cmake .. -DCMAKE_SKIP_BUILD_RPATH=TRUE
cmake .. -DCMAKE_SKIP_INSTALL_RPATH=TRUE
3.CMake install之后保持RPATH
If you don't explicitly specify
- CMAKE_SKIP_RPATH,
- CMAKE_BUILD_WITH_INSTALL_RPATH,
- CMAKE_SKIP_BUILD_RAPTH,
- CMAKE_SKIP_INSTALL_RPATH
默认CMakeAfter compiling for you,If you use the relevant dynamic library,它会在相应的execAdd the path of your related dynamic library to the file,This way you don't need to do it every time you go to execute itLD_LIBRARY_PATH就可以正常运行.
可以看到,当前myexe中的RPATH字段有一个Library rpath,Which specifies that you generate the corresponding dynamic librarytarget的目标路径
readelf -d myexe
或者
来查看当前executableWhich dynamic libraries have been found.
ldd -r myexe
- 因为目前的RPATH都是写的绝对路径
So mobile relatedshared_lib库的路径,This time you go to runmyexe,You will find that it can no longer find the relevant dynamic library.
make install下CMake是如何处理RPATH的?
- CMakeIn order to facilitate the installation of users,默认在make install之后会自动removeDelete the relevant onesRPATH,This time you go to checkexe的RPATH,It has been found that this field does not exist.
- 因此,当每次make install之后,We enter into the installation path to execute the relevantexe的时候,will find out at this timeexeThe relevant library path has not been found,因为它的RPATH已经被CMake给去除了.
如何让CMake能够在installThe process of writing relatedRPATH,并且该RPATHCan't make it at firstbuild的时候的RPATH呢?
- 答案就是CMAKE_INSTALL_RPATHThis global variable and INSTALL_RPATH这个target属性.
CMakeThere will be a sum during the installation processconfigure一样的安装路径,CMAKE_INSTALL_PREFIX(configure下是–prefix,当然也可以用shell下的全局变量DESTDIR);
This time it will install your installation files to youprefixunder the relative path,So when we want to bemake install的时候,比如当前的share_lib在lib目录下,We hope after installationRPATHIt can be found automatically,我们就可以这么写
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
需要注意的是,这个变量是全局变量,Means all yourstarget的RPATH都会在installwas written as this(包括myexe和不需要RPATH的share_lib)
set_target_properties(myexe PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib" LINK_FLAGS "-Wl,--disable-new-dtags")
This is guaranteed to only target the current onetarget进行make install的时候RPATH的写入了.
在gcc中,设置RPATH的办法
设置linker的rpath选项:$ gcc -Wl,-rpath,/your/rpath/ test.cpp
如果需要设置$ORIGIN:$ gcc -Wl,-rpath,‘$ORIGIN/lib’ test.cpp.
RPATHhas a special identifier in it$ORIGIN.This identifier representselfThe directory where the file itself resides.
When you want to use relative position seeking.so文件,就需要利用$ORIGIN设置RPATH.多个路径之间使用冒号:隔开.在CMake中,Things are a little different.
由于CMakeNeed to take care of software installation,因此CMakeUse two variables to controlRPATH:INSTALL_RPATH和BUILD_RPATH.
SET_TARGET_PROPERTIES(target
PROPERTIES INSTALL_RPATH "$ORIGIN;/another/run/path")
注意,在CMake中,多个RPATH使用分号隔开,而不是冒号.This is estimated because the colon is thereCMakeGrammar has other uses.
边栏推荐
- 单例模式
- MYSQLg advanced ------ batch insert millions of data
- 运算放大器(OPA)超详细参数讲解-运放---以及8个型号的运算放大器分析对比
- Cysteine/Galactose/Perylenediimide Functionalized Fe3O4 Fe3O4 Nanomaterials | Scientific Research Reagents
- 22 high mid term paper topics forecast
- Getting started with kubernetes apparmor
- 网络学习总结
- tidb crash test
- Ferric oxide/bismuth sulfide nanocomposites ([email protected]@BSABiS nanoparticles) | dendrimer-stabilized bismuth sulfide nanop
- IQ Products巨细胞病毒CMV感染检测试剂盒的特征和应用
猜你喜欢
磁性核壳四氧化三铁颗粒负载金纳米星|磁性Fe3O4-POSS-COOH|超顺磁四氧化三铁聚多巴胺核壳结构纳米粒子
Polyamide-amine (PAMAM) dendrimer-bismuth sulfide composite nanoparticles | bismuth sulfide modified Gd‑DTPA‑OA ligand | for scientific research
缓存技术使用
GNNExplainer应用于节点分类任务
vs番茄助手的方便功能和便捷快捷键介绍
Fragments
sql problem solving statement to create a table
DevNet: Deviation Aware Networkfor Lane Detection
Word文件的只读模式没有密码怎么退出?
线程的6种状态
随机推荐
workbench 数据导出
Redis 2 - 高级
C# 利用iTextSharp画PDF
【R语言】交互作用 测试数据
Remember a nest.js route that matches all the path problems that follow
APP商品详情源数据接口(淘宝/京东/拼多多/苏宁/抖音等平台详情数据分析接口)代码对接教程
网络学习总结
After the VB.net program is closed, the background is still connected to SQL
golang zip aes base64
Output method of list string print(*a) print(““.join(str(c) for c in a) )
Deep Learning - Principles of Neural Networks 2
BeautifulSoup4的介绍与使用
Unity backgammon game design and simple AI implementation (1)
Ferric oxide/bismuth sulfide nanocomposites ([email protected]@BSABiS nanoparticles) | dendrimer-stabilized bismuth sulfide nanop
MYSQLg advanced ------ batch insert millions of data
Regular Expression - Determine if a string matches the "AABB" pattern
tidb crash test
The 24th day of the special assault version of the sword offer
报错:FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disab
io.lettuce.core.RedisCommandTimeoutException Command timed out