问题标签 [static-linking]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
visual-c++ - 如何找出是什么让我的应用程序混合了静态和动态链接的 CRT
很抱歉接下来的长篇文章。
我知道混合使用 Microsoft 提供的静态链接和动态链接的 C 和 C++ 运行时并不是一个好主意。不幸的是,我们在工作中的应用程序已经将它们混合在一起,我们一直在努力解决这个问题。由于各种原因(其中不熟悉 MSI,我们使用的 NSIS 可能不能很好地支持 MSM,缺乏时间和资源),我们决定静态链接 CRT 而不是动态链接。我知道这不是一个好主意的原因,但这是我们现在的选择。
我们的代码主要是标准 C++,并辅以大量其他开源库。
应用程序的结构是:产生静态库的各种模块,它们本身链接在一起以创建各种东西,其中一个可执行文件给我们带来了问题。
在 Release 中,我们使用 /MT 构建所有代码。对于一些开源库,我们使用了预编译的二进制文件,其中一些是使用 /MD 预编译的 dll,这使我们混合了运行时。所以我们自己用 /MT 重新编译了它们,并让它们生成静态库而不是 dll。这种转换不是针对每个库都完成的,所以我们仍然链接一些使用 /MD 的 dll。
现在的结果是,在depends.exe 中,除了一个可执行文件之外,我们所有的东西都不直接依赖于msvcr80.dll 或msvcp80.dll。不直接依赖是指msvcr80.dll不是depends.exe 显示的树根的子级。有时我们确实发现 msvcr80.dll 被其中一个库 dll 拉入,但那是树中更深的一些级别。
我如何找出为什么 msvcr80.dll 在那个讨厌的可执行文件的第一级?是什么使该可执行链接直接指向 msvcr80.dll?
一个原因可能是我们静态链接到使用 /MD 链接的库 A,因此它与 CRT 动态链接。所以库 A 中的代码最终在我们的可执行文件中,因此我们的可执行文件与 msvcr80.dll 链接。但是我如何找出哪个库做到了这一点?
到目前为止我尝试了什么:
- 在depends.exe中加载静态链接的.lib文件->不起作用,因为depends.exe需要可执行文件或dll而不是静态库
- 在静态链接的 .lib 文件上使用 dumpbin.exe /DIRECTIVES -> 它们都没有显示 msvcrt80.dll (在调试中,我们尝试将 /MDd 用于所有内容,但它们确实显示了 msvcrt80d.dll,这让我认为方法是很好,它证明所有静态链接的开源库都用 /MT 正确编译)
- 使用 /VERBOSE:LIB 链接器标志 -> 它表明它确实在引入 msvcrt.lib,这是 msvcr80.dll 的导入库,所以我们遇到了麻烦,但它没有说明它为什么这样做
- 在 Visual Studio 中使用 /VERBOSE 链接器标志 +:附加依赖项 libcmt.lib + 忽略所有默认库 YES + 忽略特定库:msvcrt.lib 拼命尝试让 msvcrt.lib 消失或看看是谁拉了它。结果把我难住了:
据我了解,libcmt.lib 中的 typinfo.obj 引用了一个符号,在 msvcrt.lib 中搜索它,然后在 ti_inst.obj 中找到它会引发一个错误,它被定义了两次。但这没有意义。如果 libcmt.lib 已经有符号,为什么它最终会在 msvcrt.lib 中搜索它并因此将 msvcr80.dll 带入我的可执行文件中?更一般地说,为什么静态库要在动态导入库中搜索符号?如果我在 Ignore 特定库中有链接器,为什么还要查看 msvcrt.lib?
谢谢你的耐心 :-)。
gcc - #pragma comment(lib, "xxx.lib") 在 Linux 下等效?
我有一个名为 的静态库文件libunp.a
,我知道我可以gcc -lunp xx
用来链接到该库。
我可以#pragma comment(lib,"xxx.lib")
用来告诉 Microsoft C/C++ 编译器包含该库;我怎么能在 Linux/GCC 下做到这一点?
c - 编译时如何将libevent与gcc静态链接?
我在我的项目中使用了 event.h,但它必须运行的服务器不支持它。此外,我也无法安装它。有没有办法以最少的修改运行我的项目。
它必须编译为静态链接,但我该怎么做呢?
iphone - 如何在 XCode for iPhone 中为不同的构建配置文件链接不同的预编译库?
我的客户为我提供了两个预编译库,blah-device.a 和 blah-simulator.a。如何告诉 xcode 在设备编译模式下使用 blah-device.a 在模拟器编译模式下使用模拟器?
我的客户给了我这些指示
- 打开 Targets 组(在 Groups & Files 面板中),右键单击项目图标,然后选择 Add > Existing Frameworks。
- 在链接库部分中,单击添加库图标 (+) 图标,然后单击添加其他。
- 选择 blah-device.a(用于直接在 iPhone 设备上开发)或 blah-simulator.a(用于在 iPhone 模拟器上开发),然后单击添加。
我已经在其中复制了头文件,但是这些说明并不能使使用不同的配置文件轻松构建。
使用 DEVICE 配置文件构建时如何让 Xcode 链接 blah-device.a 和使用 SIMULATOR 配置文件构建时链接 blah-simulator.a?
任何帮助是极大的赞赏。
windows - 在 Linux 和 Windows 上将可加载插件与可执行文件中的符号链接起来
在 Mac 上将可加载插件创建为捆绑包并使其使用Host 可执行文件中的符号非常重要。这如何在 Linux 和 Windows 上完成?
我听说-rdynamic
Linux 上可能会派上用场,但就 Windows 而言,我完全不知所措。
关键是不要将主机和插件都链接到共享库,而是转向静态构建的主机。
linux - 共享库中库函数的选择性静态链接
我想创建一个使用第三方静态库中的函数的共享库。例如foo
,bar
从libfoobar.a
. 我知道我的主要应用程序也在使用foo
并将导出该符号。所以我只是想链接bar
以节省代码大小并使'foo'未解决(因为它将由主应用程序提供)。如果我包含libfoobar.a
,链接器ld将在我的共享库中包含这两个函数。如果我不包含libfoobar.a
,我的库将无法访问函数bar
,因为应用程序本身没有链接到bar
. 问题:
- 有没有办法告诉ld在构建共享库时只解析某些符号?
- 变成
libfoobar.a
共享库? - 提取包含函数
bar
的文件libfoobar.a
并在链接器行上指定它? - 不用担心,运行时加载器将从您的应用程序中使用,因此不会加载共享库中
bar
的副本?bar
c - 为什么要从 .o 创建一个 .a 文件用于静态链接?
考虑这段代码:
一.c:
二.c:
程序.c
我想将这些程序链接在一起。所以我这样做:
这工作得很好。
或者我可以创建一个静态库:
所以我的问题是:为什么我要使用第二个版本——我创建“.a”文件的那个版本——而不是链接我的“.o”文件?它们似乎都是静态链接的,那么彼此之间是否存在优势或架构差异?
c++ - 静态链接使用不同版本的 C 运行时库构建的库,好还是坏?
考虑这种情况:应用程序链接到第 3 方库 A。
A 是使用 MSVC 2008 构建的,并且静态链接(即使用 /MT 构建)到 C 运行时库 v9.0。
该应用程序是使用 MSVC 2005 构建的,并且静态链接到 A 和(使用 /MT)到 C 运行时库 v8.0。
我可以看到这个问题 - 例如,如果运行时库版本之间的标头中的类型发生了变化。
是否注意保持运行时库标头在版本之间兼容,或者是否应该始终确保所有静态链接的库都链接到相同版本的运行时库?
static-linking - 链接的可执行文件中缺少静态库符号
我正在尝试将静态创建的.a
库与另一段 C 代码链接。
nm
但是,在最终的可执行文件中,当使用该命令查看时,会发现缺少几个符号(函数名称) 。这是因为链接器(被调用)正在剥离与库链接的另一段代码gcc
中未引用的符号。C
我尝试使用该命令查找的函数符号在库nm
中可见。.a
如何使链接器不以这种方式删除省略的符号?
c - Glade 和静态链接
如果我在 FreeBSD 8 下静态链接 GTK+ 程序,gtk_builder_add_from_file()
突然返回错误:
如何解决?使用动态链接一切正常。
更新:链接由以下人员完成:
或者换句话说,在 Makefile 我有: