标签: dynamic-linking

ld-linux 动态链接器/解释器的相对可执行路径

我想要发布和归档二进制文件(带有库的可执行文件),它们向后和向前兼容尽可能多的 Linux 发行版,并且整个包可重定位。libc据我了解,还需要提供系统库,因为给定不同版本的libc. 同时libc似乎是耦合的ld-linux (例如,在 Debian 测试上编译的二进制文件已经无法在 Ubuntu 18.04 LTS 上工作),所以我ld-linux也需要打包。

我的解决方案是将所有可执行文件和库放入一个目录并将 rpath 设置为$ORIGIN(通过使用 链接-Wl,rpath=$ORIGIN或设置chrpathpatchelf)。这使得库可以与可执行文件一起重定位,并且适用于除ld-linux链接器本身之外的所有库。

可以通过以下方式更改动态链接器路径-Wl,--dynamic-linker=/my/path/ld-linux.so或设置它patchelf,但路径必须是绝对路径:

  1. 诡计$ORIGIN不起作用
  2. 相对路径./有效,但仅当当前目录与加载器本身相同时才有效(从其他地方启动时,可执行文件会因错误而崩溃)
  3. 我可以编写一个 shell 脚本来检测所有路径并使用 启动可执行文件/my/path/ld-linux.so /my/path/myexecutable $@,但这意味着我想避免另一层间接和开销。

有没有办法将ld-linux相对于可执行文件的路径直接设置为可执行文件?

也许有一种方法可以静态链接 ld-linux 加载程序?

linux installation elf relocation dynamic-linking

10
推荐指数
1
解决办法
2538
查看次数

CGO_ENABLED 如何影响动态链接和静态链接?

我们正在编译要在 docker 上运行的 Go 代码,并且正在调查为什么我们的二进制文件没有执行。我们发现它缺少一些动态库(尽管我们想要静态链接的二进制文件)。

这就是它的编译方式。

env GOOS=linux CGO_ENABLED=1 GO111MODULE=on GOPRIVATE=github.com/ourrepo GOPROXY=https://proxy.golang.org go build --installsuffix cgo --ldflags='-extldflags=-static' -o program main.go

使用相同的构建命令CGO_ENABLED=0最终解决了问题,并且输出二进制文件是静态链接的。

现在奇怪的部分是我们有另一个程序使用相同的构建命令,这次是CGO_ENABLED=1and...它是静态链接的!

所以我很困惑为什么在某些情况下CGO_ENABLED=1会产生动态链接,有时会产生静态链接。很高兴提供更多细节。

dynamic-linking go static-linking

10
推荐指数
1
解决办法
7197
查看次数

-symbolic和-shared GCC标志之间有什么区别?

从文档的描述中,他们似乎做了同样的事情,除了"并非所有系统"支持共享和"只有一些系统"支持符号(不清楚这些是否是同一组系统):

-shared生成一个共享对象,然后可以将其与其他对象链接以形成可执行文件.并非所有系统都支持此选项.对于可预测的结果,还必须指定在指定此选项时用于生成代码(-fpic,-fPIC或模型子选项)的同一组选项.[1]

-symbolic在构建共享对象时绑定对全局符号的引用.警告任何未解决的引用(除非被链接编辑器选项-Xlinker -z -Xlinker defs覆盖).只有少数系统支持此选项.

我怀疑区别在于"生成一个共享对象,然后可以与其他对象链接以形成可执行文件"部分,但这听起来像任何库都是如此.是否意味着生成的共享对象也可以静态链接?

c gcc shared-libraries dynamic-linking compiler-flags

9
推荐指数
1
解决办法
3709
查看次数

推荐用于跨平台进程内动态库绑定的C++包装器(即轻量级,高性能COM或CORBA)

我们正在开发一个具有插件"架构"的应用程序,以允许应用程序的消费者提供他们自己的专有算法.(我们基本上会有一组解析器,并允许第三方提供自己的解析器)

域空间需要非常高的性能,因此进程外绑定不起作用,我们宁愿留下像CORBA和COM这样的重量级东西.

基本上我们正在寻找一个简单的跨平台包装器:

  • 从相对路径加载库
  • 提供特定dll/.so到某个配置/名称的映射
  • 做一些初始化并查询库以确保它提供必要的功能

我认为这只是一个环绕loadlibrary()和方法调用导出.我们可以自己写这个,但我们宁愿使用现有的代码,因为我们已经足够了.

同样,吞吐量和性能非常重要.

类似的问题是:

COM的跨平台替代方案 - 这个很接近,但我们只想在进程中进行 - 不需要进程,我们的需求有点"重量轻".

C++跨平台动态库; Linux和Windows

这适用于非托管C++ - 我们不能使用.NET

编辑 - 我们发现了什么

我们发现Poco非常适合我们的需求.作为奖励这个页面是一个非常赞赏的关于C++开发状态和语言方向的评论...

这是一个简单的跨平台包装,我们需要Poco提供.真的没有多少,但仍然节省了我们的时间和测试.运行时没有额外的开销.

c++ cross-platform shared-libraries dynamic-linking

9
推荐指数
1
解决办法
4459
查看次数

如何部署依赖于动态库的应用程序?

我正在开发一个使用GStreamer库的应用程序.为了便于部署,我想收集本地捆绑中的所有GStreamer库.为此我写了一个小脚本,执行以下操作:

  • 递归遍历依赖项(使用otool -L)
  • 将所有依赖项复制到本地目录
  • 制作相对于@executable_path的所有依赖路径(使用install_name_tool)

(如果您有兴趣,可以查看Ruby脚本.)

但是,我现在看到gst_init呼叫上的运行时错误:

(process:22843): GLib-GObject-CRITICAL **: gtype.c:2458: initialization assertion failed, use g_type_init() prior to this function

(process:22843): GLib-CRITICAL **: g_once_init_leave: assertion `initialization_value != 0' failed
Run Code Online (Sandbox Code Playgroud)

只有在我使用本地化库时才会出现这些错误.


Are there certain 'common pitfalls' when it comes to using install_name_tool? Does anyone have an idea what I could be doing wrong? If you need to know certain details then feel free to ask.

Update
I changed a few things:

  • For the …

c++ macos dynamic-linking install-name-tool

9
推荐指数
1
解决办法
1162
查看次数

@rpath用于嵌入框架中的动态库

我有一个应用程序,称之为Animal.app.Contents/Frameworks比如,它的文件夹里面是一个框架Mammal.framework.Versions/A/Frameworks在框架的文件夹中,我有dog.dylib.安装名称dog.dylib是@ rpath/dog.dylib.对于"Runpath Search Paths"框架的设置,我已经指定了@loader_path/../Frameworks.(我对最后一个设置的推理是dylib的"loader"将是路径的框架的二进制文件Mammal.framework/Versions/A/Mammal.)

我在运行时收到一条错误消息:

Dyld Error Message:
  Library not loaded: @rpath/dog.dylib
  Referenced from: /Volumes/VOLUME/*/Animal.app/Contents/MacOS/../Frameworks/Mammal.framework/Versions/A/Mammal
  Reason: image not found
Run Code Online (Sandbox Code Playgroud)

我已经阅读了Apple的"Run-Path Dependent Libraries"文档和Mike Ash的博客文章@rpath,但我仍然看不出我做错了什么.

macos rpath dynamic-linking

9
推荐指数
1
解决办法
6890
查看次数

gperftools CPU Profiler到底是怎么开始的?

gperftools文档libprofiler应该链接到目标程序:

$ gcc myprogram.c -lprofiler
Run Code Online (Sandbox Code Playgroud)

(不改变程序代码).

然后程序应该使用特定的环境变量运行:

CPUPROFILE=/tmp/profiler_output ./a.out
Run Code Online (Sandbox Code Playgroud)

问题是:libprofile当仅仅加载探测器时,如何有机会启动和完成探查器,但是它的功能没有被调用?

该库中没有构造函数(证明). 库代码中"CPUPROFILE"的所有情况都不会引用启动分析器的任何位置.

我没有想法,在哪里看下一个?

linker gcc dynamic-linking google-perftools gperftools

9
推荐指数
1
解决办法
4852
查看次数

在编译和链接C++文件时关于-ldl标志

参考以下代码

test_linker.cpp

int main() {

    srand(time(0));
    for (int i = 0; i < 10; ++i) {
        cout << rand() % 10 << endl;
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

urandom.cpp

#include <iostream>
using std::cout;
using std::endl;
#include <dlfcn.h>

int rand() throw() {

    // get the original rand() function
    static auto original_rand = (decltype(&rand)) dlsym(RTLD_NEXT,"rand");

    cout << "Call made to rand()" << endl;
    return original_rand();
}
Run Code Online (Sandbox Code Playgroud)

当我尝试使用以下命令编译代码时

g++ -std=c++11 -Wall -Werror -Wextra -Wvla -pedantic -O3 urandom.cpp -c
g++ -std=c++11 -Wall -O3 test_linker.cpp urandom.o …
Run Code Online (Sandbox Code Playgroud)

c++ linux dynamic-linking c++11

9
推荐指数
1
解决办法
9228
查看次数

dlopen 与标准动态链接的用例是什么?

根据文档,dlopendlopen一起dlsym用于加载库,并获取指向符号的指针。

但这已经是动态加载器/链接器所做的。此外,这两种方法都基于ld.so

使用时实际上似乎有两个不同之处dlopen

  1. 该库可以有条件地加载。
  2. 编译器不知道我们正在使用的符号(类型、原型...),因此不会检查潜在的错误。顺便说一下,这是实现自省的一种方式。

但是,它似乎并没有激发使用dlopen超标准加载,除了边际示例:

  1. 就内存占用优化而言,当共享库已被另一个程序使用时,条件加载并不是很有趣:加载已使用的库不会增加内存占用。
  2. 避免编译器监督是不安全的,也是编写错误的好方法......我们也错过了潜在的编译器优化。

那么,是否有其他用途dlopen比标准动态链接/加载更受欢迎?

c shared-libraries dynamic-linking

9
推荐指数
1
解决办法
2936
查看次数

`var@GOTPCREL(%rip)` 是什么意思?

这是什么<some symbol>@GOTPCREL(%rip)意思?

我遇到过这一行mov var@GOTPCREL(%rip), %rax,并对奇怪的语法感到有点困惑。

有人可以推荐我应该阅读以理解这一点的相关文档吗?谢谢!

assembly x86-64 dynamic-linking att got

9
推荐指数
1
解决办法
3397
查看次数