标签: dynamic-linking

C++应用程序 - 我应该为库使用静态或动态链接吗?

我将开始一个新的C++项目,该项目将依赖于一系列库,包括部分Boost库,log4cxx或google日志库 - 并且随着项目的发展,其他项目(我还没有预料到) .

它必须在32位和64位系统上运行,很可能是在一个非常多样化的Linux环境中,我不希望所有必需的库都可​​用,也不需要su权限.

我的问题是,我应该通过动态或静态链接到所有这些库来构建我的应用程序吗?

笔记:

(1)我知道静态链接在开发过程中可能会很痛苦(编译时间较长,32位和64位交叉编译,依赖链包含所有库等),但在测试过程中更容易 - 只需移动文件即可运行.

(2)另一方面,动态链接接缝在开发阶段更容易 - 编译时间短(不知道如何处理来自我的32位开发环境的64位库的动态链接),没有依赖链的喧嚣.另一方面,新版本的部署可能很难看 - 特别是在需要新库时(参见上述条件,目标机器上没有su权限,也没有这些库可用).

(3)我已阅读有关此主题的相关问题,但无法确定哪种方法最适合我的方案.

结论:

  1. 谢谢大家的意见!
  2. 我可能会使用静态链接,因为:
    • 部署更容易
    • 在perf期间可预测的性能和更一致的结果.测试(见本文:http://www.inf.usi.ch/faculty/hauswirth/publications/CU-CS-1042-08.pdf)
    • 正如所指出的,静态与动态编译的大小和持续时间似乎并没有那么大的差异
    • 更简单,更快速的测试周期
    • 我可以保留所有的开发.循环我的开发.机

c++ boost cross-compiling dynamic-linking static-linking

13
推荐指数
1
解决办法
4372
查看次数

"未能从共享对象映射段:操作不允许"以及如何调试的可能原因是什么?

我有两个可执行文件,它们都是交叉编译的,可以在Android中运行.我已将两者放在同一目录中的设备上.我已将它们所依赖的所有共享库放在同一目录中,包括ld-linux.so.3.我使用以下命令运行可执行文件:

ld-linux.so.3 --library-path/path/to/libraries executable_name

当作为任何用户运行时,它们都适用于旧版本的Android.如果以root身份运行,两者都可以在最新版本的Android上运行.当以任何用户身份运行时,只有一个可以在最新版本的android上运行.相反,它给出:

无法从共享对象映射段:不允许执行executable_name操作

如何找出不能运行的可执行文件的不同之处?

我在网上看了很多,大多数人都会收到这个错误:

A)没有它们所依赖的库之一或可执行文件本身的执行权限.

要么

B)尝试从作为NOEXEC挂载的目录运行.

这两种情况似乎并非如此.它可以找到所有库,我可以自己加载任何库,看看它依赖于解决的其他东西.此外,我可以从感兴趣的目录运行基本脚本.

较新版本的Android,Jelly Bean,是一个不同的Linux内核版本,我想知道这是否相关.

什么给?我该如何调试?

linker executable android linker-errors dynamic-linking

13
推荐指数
3
解决办法
1万
查看次数

加载时链接期间的符号地址与Linux中的运行时链接

我试图了解Linux中动态库的加载时间链接(使用gcc -l)与运行时链接(使用dlopen(), dlsym())的机制差异,以及这些机制如何影响库的状态及其符号的地址.

本实验

我有三个简单的文件:

libhello.c:

int var;
int func() {
    return 7;
}
Run Code Online (Sandbox Code Playgroud)

libhello.h:

extern int var;
int func();
Run Code Online (Sandbox Code Playgroud)

main.c中:

#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
#include <dlfcn.h>
#include "libhello.h"

int main() {
    void* h = dlopen("libhello.so", RTLD_NOW);
    printf("Address  Load-time linking    Run-time linking\n");
    printf("-------  -----------------    ----------------\n");
    printf("&var     0x%016" PRIxPTR "   0x%016" PRIxPTR "\n", (uintptr_t)&var , (uintptr_t)dlsym(h, "var" ));
    printf("&func    0x%016" PRIxPTR "   0x%016" PRIxPTR "\n", (uintptr_t)&func, (uintptr_t)dlsym(h, "func"));
}
Run Code Online (Sandbox Code Playgroud)

我用命令编译libhello.c gcc -shared -o libhello.so -fPIC …

c c++ linux gcc dynamic-linking

13
推荐指数
1
解决办法
1325
查看次数

如何找到未满足的ELF依赖项?

我使用LSB SDK构建了一个测试ELF程序(注意我的问题不是LSB特有的):

$ /opt/lsb/bin/lsbcc tst.c
$ ls -l a.out 
-rwxr-xr-x 1 math math 10791 2009-10-13 20:13 a.out
$ file a.out 
a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
Run Code Online (Sandbox Code Playgroud)

但我无法启动它(是的,我向你保证,该文件在目录...):

$ ./a.out 
bash: ./a.out: No such file or directory

$ uname -a
Linux math 2.6.28-15-generic #52-Ubuntu SMP Wed Sep 9 10:48:52 UTC 2009 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)

我认为有一个ELF依赖不能实现,但我不知道如何找到它.是否有一个类似于ldd的工具库可用于找到缺失的链接?

我不认为它与2.6.15/2.6.28-15的区别有关,因为LSB编译器正在工作:

$ file /opt/lsb/bin/lsbcc 
/opt/lsb/bin/lsbcc: ELF 64-bit LSB …
Run Code Online (Sandbox Code Playgroud)

linux elf dynamic-linking

12
推荐指数
1
解决办法
2万
查看次数

与LLVM动态链接

我想在模块中执行函数,该模块将在其他模块中解析依赖项.模块可能会改变(动态编译环境)所以我不希望不将所有依赖关系链接到单个单片模块中,也就是说,如果可以避免

我希望使用,Linker::linkModules但这对源模块总是具有破坏性.对于一个模块而言,这是可以的,取决于一个模块,因为如果那个模块发生了变化,这没什么大不了的,但是重建和重新连接N-1模块并不是因为单个模块发生了变化而没有变化吗?

我想知道是否有一个非破坏性的linkModules版本可以用于JIT执行.

c++ llvm dynamic-linking

12
推荐指数
1
解决办法
1699
查看次数

如何将LC_LOAD_DYLIB命令插入Mach-O二进制文件或将静态库加入现有二进制文件(IOS)

这是我第一次询问stackoverflow,我很绝望.

我的任务是加载一个dylib或将静态库加入到IOS设备的现有可执行文件中.

我将使用它static void __attribute__((constructor)) initialize(void)开始调配.这个可执行文件适用于内部企业appstore,所以我不需要通过苹果appstore(因为他们会拒绝它).

这样做的原因是从客户及其签名密钥获取现有IPA,并为其应用程序添加新功能,而无需开发人员干预.

有一家公司正在做这个叫做nukona.您可以在此处观看电影:https://www.youtube.com/watch?feature = player_embedded&v = z9rrOB6lOxY

我可以告诉你,我试图将LSEnvironment放在plist文件中DYLD_INSERT_LIBRARIES但是事实证明LSEnvironment似乎对IOS应用程序的沙箱没有任何影响.

我还尝试使用install_name_tool来更改其中一个依赖项,并将其替换为我的dylib(也具有该依赖项).它没有信息崩溃原因.

显然,如果我将dylib添加到XCode中的测试应用程序并重新编译它是完美的,这是给定的.但是,这是我不能要求的,例如,公司的管理员.重建可能会阻止客户使用此库.

这是我在堆栈溢出时发现的相关链接,但对于osx,我需要它用于IOS. 如何将LC_LOAD_DYLIB命令插入Mach-O二进制文件(OSX)

我唯一可以想到的是编辑二进制加载命令一些如何,但我不知道如何以及如何做到这一点考虑到重定位表等...

欢迎任何替代方案.

感谢您的时间.

mach-o dynamic-linking static-linking ios

12
推荐指数
1
解决办法
4170
查看次数

CMake on Linux:"目标平台不支持动态链接"

我很简单 CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
FIND_PACKAGE(VTK REQUIRED)
PROJECT(test CXX)
Run Code Online (Sandbox Code Playgroud)

那真的什么都没做.正确找到VTK包/usr/lib/vtk-5.8/VTKConfig.cmake.该文件包含许多类型的语句

ADD_LIBRARY(foobar SHARED IMPORTED)
Run Code Online (Sandbox Code Playgroud)

表示共享库libfoobar.so需要在可执行文件中链接.

然而,在使用上述脚本创建Makefile时,CMake会抱怨

CMake Warning (dev) at /usr/lib/vtk-5.8/VTKTargets.cmake:244 (ADD_LIBRARY):
  ADD_LIBRARY called with SHARED option but the target platform does not
  support dynamic linking.  Building a STATIC library instead.  This may lead
  to problems.
Call Stack (most recent call first):
  /usr/lib/vtk-5.8/VTKConfig.cmake:200 (INCLUDE)
  /usr/share/cmake-2.8/Modules/FindVTK.cmake:73 (FIND_PACKAGE)
  CMakeLists.txt:4 (FIND_PACKAGE)
This warning is for project developers.  Use -Wno-dev to suppress it
Run Code Online (Sandbox Code Playgroud)

这个警告意味着什么,它是如何处理的?

这是一个使用CMake 2.8.9的Linux系统.虽然对于包含的所有软件包都会显示此错误消息ADD_LIBRARY(foobar SHARED IMPORTED),但此处将使用VTK-5.8作为示例.

cmake dynamic-linking static-linking

12
推荐指数
2
解决办法
4425
查看次数

g ++为什么你不必链接iostream二进制文件,但对于pthread你呢?

如果你有一个只使用'cout'对象的非常基本的C++程序,你可以在源文件中包含iostream,然后在编译它时你不必链接任何外部库.换句话说,你可以简单地运行

g++ main.cpp -c

g++ main.o -o program

./program

当您想要使用更复杂的对象(如线程)时,不仅包含pthread,而且在链接程序时必须链接到库.

g++ main.cpp -c

g++ main.o -lpthread -o program

./program

所以我的问题是,为什么我不必链接任何库来使用所有的iostream对象?

c++ multithreading dynamic-linking

12
推荐指数
2
解决办法
1729
查看次数

在Ubuntu 14.04下链接错误与`libopencv_highgui.so`,与`libtiff.so.5的奇怪结果

问题

我正在Ubuntu 14.04(64位)编译深度学习库Caffe.

Version: 2.4.8+dfsg1-2ubuntu1从ubuntu软件包服务器安装OpenCV():

sudo apt-get install libopencv-dev

Caffe使用CMake 2.8 编译.

链接错误:

链接CXX可执行文件

/usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8:未定义引用`TIFFOpen@LIBTIFF_4.0'

信息来源

似乎找不到TIFF库的一些符号.我努力找到原因(没有运气).这是关于库的一些信息.

TIFF库链接 libopencv_highgui.so.2.4.8

$ ldd libopencv_highgui.so.2.4.8 | grep tiff

libtiff.so.5 => /usr/lib/x86_64-linux-gnu/libtiff.so.5(0x00007f978313b000)

导入符号 libopencv_highgui.so.2.4.8

$ readelf -s libopencv_highgui.so.2.4.8 | grep TIFFOpen

62:0000000000000000 0 FUNC GLOBAL DEFAULT UND TIFFOpen@LIBTIFF_4.0(9)

注意:@符号名称中只有一个.

$ nm -D libopencv_highgui.so.2.4.8 | grep TIFFOpen

你TIFFOpen

出口符号libtiff.so.5:

$ nm -D /usr/lib/x86_64-linux-gnu/libtiff.so.5

0000000000000000 A LIBTIFF_4.0

...

00000000000429f0 T TIFFOpen

...

$ readelf -s /usr/lib/x86_64-linux-gnu/libtiff.so.5|grep TIFFOpen …

c++ opencv elf dynamic-linking unresolved-external

12
推荐指数
1
解决办法
6879
查看次数

为什么我们在编译期间需要共享库

为什么在可执行文件的编译期间我们需要共享库的存在?我的理由是,由于共享库未包含在我的可执行文件中并在运行时加载,因此在编译期间不应该需要它.还是我错过了什么?

#include<stdio.h>
int addNumbers(int, int); //prototype should be enough, no? 
int main(int argc, char* argv[]){
  int sum = addNumbers(1,2);
  printf("sum is %d\n", sum);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我有libfoo.so我当前的目录,但我改名libfar.so,发现在编译时需要共享库,或者它不能编译.

gcc -o main main.c -L. -lfoomain.c:(.text+0x28): undefiend reference to 'addNumber'

我认为只有共享库的名称才足够.不需要共享库本身,因为它在LD_LIBRARY_PATH中找到并在运行时动态加载.除了共享库的名称之外还需要其他东西吗?

c gcc compilation shared-libraries dynamic-linking

12
推荐指数
1
解决办法
1970
查看次数