我参与了一些有关Linux的图书馆的辩论,并想确认一些事情。 这是我的理解(请纠正我,如果我错了,我会编辑我的post后),build立一个应用程序时有两种使用库的方式: 静态库(.a文件):在链接时,将整个库的副本放入最终应用程序,以便库中的函数始终可供调用应用程序使用 共享对象(.so文件):在链接时,只需通过相应的头文件(.h)对其API进行validation即可。 直到运行时才需要使用该库。 静态库的明显优势在于它允许整个应用程序是自包含的,而dynamic库的好处是可以replace“.so”文件(即:由于安全性需要更新错误),而不需要重新编译基础应用程序。 我听说有些人在共享对象和dynamic链接库(DLL)之间做了区分,尽pipe它们都是“.so”文件。 在Linux或任何其他符合POSIX标准的操作系统(例如:MINIX,UNIX,QNX等)上进行C / C ++开发时,共享对象和DLL之间是否有区别? 我被告知,一个关键的差异(到目前为止)是共享对象只是在运行时使用,而DLL必须首先使用应用程序中的dlopen()调用打开。 最后,我也听说一些开发人员提到“共享档案”,据我了解,这也是静态库本身,但从来没有被应用程序直接使用。 相反,其他静态库将链接到“共享归档”,以将共享归档中的一些(但不是全部)function/资源引入正在构build的静态库中。 预先感谢您的帮助。 更新 在向我提供这些条款的背景下,我发现了这些术语之间的细微差别,甚至可能只是我的行业中的俗语: 共享对象:程序启动时自动链接到程序的库,作为独立文件存在。 该库在编译时包含在链接列表中(例如,对于名为mylib.so的库文件,LDOPTS + = – lmylib)。 该库必须在编译时和应用程序启动时出现。 静态库(Static Library):在构build时将一个库合并到实际的程序本身中,用于包含应用程序代码的单个(较大的)应用程序,以及在构build该程序时自动链接到程序中的库代码,以及包含两者主程序和库本身作为一个独立的二进制文件存在。 该库在编译时包含在链接列表中(例如,对于名为mylib.a的库文件,LDOPTS + = – lmylib)。 库必须在编译时出现。 DLL:基本上与共享对象相同,但不是在编译时包含在链接列表中,而是通过dlopen() / dlsym()命令加载该库,以便该库不需要在构build时存在编译的程序。 此外,库不需要在应用程序启动或编译时出现(必然) ,因为只在调用dlopen / dlsym时才需要。 共享存档:基本上与静态库相同,但是使用“导出共享”和“-fPIC”标志进行编译。 该库在编译时包含在链接列表中(例如,对于名为mylib S .a的库文件,LDOPTS + = – lmylib S )。 两者之间的区别在于,如果共享对象或DLL想要将共享存档静态链接到其自己的代码中并且能够使共享对象中的function可用于其他程序,则不需要仅仅使用它们内部的DLL。 这在有人向您提供静态库的情况下非常有用,并且您希望将其重新打包为SO。 库必须在编译时出现。 其他更新 “ DLL […]
这里的许多人可能都熟悉Joel Spolsky最受欢迎的博客文章之一, 请问先生,我可以有一个链接器 ,在那里他要求删除.NET框架上的依赖关系,这样就可以开发一个独立的应用程序,出售。 当时Visual Studio开发团队的Jason Zander 对这个主题提出了自己的观点 ,他认为这个主题有些没有实际意义 – 解决运行时安全问题的能力是其主要的关注点。 总的来说,小的开销是值得的。 快进到2009年。现在有几个团体声称拥有C#连接器。 (Jason Zander甚至说自己不需要太多的实现)。我们现在有了一个大型的200-300 MB跨平台完整的.NET 3.5安装程序,而不是像.NET 1.0那样可爱,十几兆的下载。其中包含用于x86,x64和ia64的.NET版本。 微软对减less运行时间的build议包括: 解压缩可再发行组件,删除不需要的目标平台,然后重新组合 使用仅为您的平台下载库的Web引导程序 使用客户端configuration文件安装程序(2008年末新增),它具有有限的库,只适用于x86 更糟糕的是,据我了解(请纠正我,如果我错了)客户端configuration文件甚至没有注册与Windows 3.5安装.NET 3.5。 这意味着如果在计算机上安装了多个.NET 3.5客户端应用程序,则不会看到对方,并且运行时将被重新安装! 我真的不知道微软在这里想的是什么。 即使假设最糟糕的情况下安装将是针对一个目标平台(例如x64),只有那些库需要包含在内,您仍然需要在应用程序开销60 mb以上。 即使是最知名的.NET应用程序之一,Paint.NET,也充满了安装应用程序的困难,因为.NET依赖性很大。 如果他们在发布免费应用程序时遇到问题,那么世界其他地方呢? 最后,他们不得不安装Microsoft Installer 3.1,.NET运行时引导程序,以及所有其他依赖库,然后才能安装自己的应用程序。 那么怎么样呢。 一个链接器。 是否有任何好的存在 – 或者只是简单地构build一个C#应用程序而不需要用户安装大量.NET运行时的工具? 更新:所以,它看起来像有几个选项: 单声道: 单声道有它自己的链接器 。 从下面的答案看来,它看起来很好。 。净: Xenocode似乎是可用和可用的。 Thinstall是另一个推荐的,它是由VMware。 Remotesoft还有另外一个链接器 。 他们认为这是一个“混淆器”。 那里有任何想法? Rustemsoft发现另一个名为Skater .NET混淆器 。 […]
Linux二进制文件通常dynamic链接到核心系统库(libc)。 这使得二进制文件的内存占用量相当小,但依赖于最新库的二进制文件不能在较早的系统上运行。 相反,链接到较旧库的二进制文件将在最新的系统上运行愉快。 因此,为了确保我们的应用程序在分发过程中有良好的覆盖率,我们需要找出我们可以支持的最古老的libc,并将其与我们的二进制文件进行链接 我们应该如何确定我们可以链接到的最古老的libc版本?
我试图从VPS中的makefile编译这个源代码,但它不工作。 VPS是一个64分的操作系统 这是完整的错误 # make gcc -c -O3 -w -DLINUX -I../SDK/amx/ ../SDK/amx/*.c g++ -c -O3 -w -DLINUX -I../SDK/amx/ ../SDK/*.cpp g++ -c -O3 -w -DLINUX -I../SDK/amx/ *.cpp g++ -O2 -fshort-wchar -shared -o "TCP_V1.so" *.o /usr/bin/ld: TCP-LINUX_V1.o: relocation R_X86_64_32 against `.rodata.str1.8' can not be used when making a shared object; recompile with -fPIC TCP-LINUX_V1.o: could not read […]
我试图链接到OS X上的静态库。我在gcc命令中使用了-static标志,但是我收到以下错误消息: ld_classic:找不到文件:-lcrt0.o collect2:ld返回1退出状态 我查看了man页面,内容如下: 除非所有库(包括libgcc.a)都已经使用-static编译,否则此选项在Mac OS X上将不起作用。 由于既没有提供静态版本的libSystem.dylib也没有提供crt0.o,所以这个选项对大多数人没有用处。 有没有另一种方法链接到这个静态库?
我所看到的–whole-archive连接器选项的唯一真正用处是从静态库创build共享库。 最近我遇到了Makefile(s),它在与内部静态库链接时总是使用这个选项。 这当然会导致可执行文件不必要地引用未引用的目标代码。 我对此的反应是,这显然是错误的,我在这里错过了什么? 我有第二个问题必须处理我阅读有关整个档案选项,但不能parsing。 如果可执行文件还与一个共享库链接,而这个共享库又与静态库(部分)具有相同的目标代码,那么应该在与静态库链接时使用–whole-archive选项。 这就是共享库和静态库在目标代码方面有重叠。 使用此选项将强制所有符号(无论使用)在可执行文件中parsing。 这是为了避免目标代码重复。 这是令人困惑的,如果一个符号在程序中被引用,它必须在链接时唯一地解决,那么这个业务是如何重复的呢? (请原谅,如果这段不是清晰的缩影) 谢谢
我感到奇怪的是,使用-Wl,-Bstatic来告诉gcc我想静态链接哪些库。 毕竟我直接告诉gcc所有关于链接库的其他信息( -Ldir , -llibname )。 是否有可能直接告诉gcc驱动程序哪些库应该静态链接? 澄清:我知道,如果某个库只存在于静态版本中,它将使用它,而不使用-Wl,-Bstatic ,但是我想暗示gcc偏好静态库。 我也知道,直接指定库文件将链接它,但我更喜欢保持包括静态和dynamic库相同的语义。
我一直在想。 我知道编译器会将你编写的代码转换成二进制文件,但是连接器是做什么的? 他们一直是我的一个谜。 我大致了解“连接”是什么。 这是对库和框架的引用被添加到二进制文件。 除此之外,我什么都不明白。 对我来说,它“只是工作”。 我也理解dynamic链接的基础知识,但没有深入。 有人可以解释这些条款吗?
我正在使用一个GNU工具链build立一个项目,一切工作正常,直到我连接它,连接器抱怨它缺less/找不到crti.o 这不是我的目标文件之一,它似乎与libc有关,但我不明白为什么它需要这个crti.o ,它不会使用库文件,例如libc.a ? 我正在为arm平台交叉编译。 我有工具链中的文件,但我如何让链接器包含它? crti.o是在“图书馆”的searchpath之一,但它应该寻找库path上的.o文件? gcc和ld的searchpath是否相同?
我想在Ubuntu 10.04下编译Android源代码。 我得到一个错误说, / usr / bin / ld:找不到-lz 你能告诉我怎样才能解决它? 什么cannot find -lz是什么意思? 以下是完整的错误消息: external/qemu/Makefile.android:1101: warning: overriding commands for target `external/qemu/android/avd/hw-config-defs.h' external/qemu/Makefile.android:933: warning: ignoring old commands for target `external/qemu/android/avd/hw-config-defs.h' host SharedLib: libneo_cgi (out/host/linux-x86/obj/lib/libneo_cgi.so) /usr/bin/ld: skipping incompatible /usr/lib/gcc/i486-linux-gnu/4.4.3/../../../libz.so when searching for -lz /usr/bin/ld: skipping incompatible /usr/lib/gcc/i486-linux-gnu/4.4.3/../../../libz.a when searching for -lz /usr/bin/ld: skipping incompatible /usr/lib/libz.so when searching […]