如何强制使用静态库而不是共享库?

14

在我的 SConscript 文件中,我有以下这一行:

Program("xtest", Split("main.cpp"), LIBS="mylib fltk Xft Xinerama Xext X11 m")

在与其他库动态链接时,我怎样才能让scons使用mylib.a而不是mylib.so?

编辑:希望尽可能少地使用平台特定的技巧。


这里是否有http://www.scons.org/wiki/StaticallyLink对你有帮助? - BjoernD
该解决方案高度特定于仅限于gcc运行时库。它还使用了一些技巧,比如指定“libNAME.a”,这是Linux特有的(需要在MinGW上编译...)。 - codehero
2个回答

15

将完整的文件路径包装在一个File节点中传递将会强制进行静态链接。例如:

lib = File('/usr/lib/libfoo.a')
Program('bar', 'main.c', LIBS = [lib])

将会生成以下链接器命令行

g++ -o bar main.o /usr/lib/libfoo.a

注意,对于此LIBS条目,"-l"标志未传递给链接器。这实际上强制进行静态链接。另一种选择是修改LINKFLAGS以获得所需的内容,但要注意绕过库依赖扫描器 - 库的状态不会被检查以进行重建。


我已经验证了解决方案的可行性。然而,我要注意我的解决方案更像是:SConscript: ... lib = File(env.MyLibFile)而在 SConstruct 中: env.MyLibFile = "/usr/lib/libfoo.a")这样我的 Windows SConstruct 可以覆盖文件名。 - codehero
这不是平台无关的。要实现这一点,请按照我的答案中所述使用SHLIB后缀。例如File('libfoo'+env ['SHLIBSUFFIX']) - daramarak
是的,对于使用平台无关变量作为前缀和后缀的观点很好。 - BenG
在Linux上,SHLIBSUFFIX是“.so”,用于共享库。您需要LIBSUFFIX(以及LIBPREFIX,而不是显式的“lib”)。 - Evgen

5
为了使这个平台独立,您需要将 env['SHLIBSUFFIX'] 附加到要使用的库上。env['SHLIBSUFFIX'] 可以为您提供此环境中共享库的后缀。
您还可以使用 ['SHLIBPREFIX']、['LIBPREFIX']、['LIBSUFFIX'] 和 ['PROGSUFFIX'],这些对于这种情况非常有用。
编辑: 显然我没有让自己被理解,所以我会澄清一下。 这些查找的返回值是平台使用的前缀/后缀字符串。通过这种方式,您可以在每个平台上引用所需的文件。请注意,您不能将其用作纯字符串,它必须嵌入为文件节点,就像BennyG建议的那样。无论如何,使用节点都是最好的解决方案,因为文件节点比字符串更加灵活多用途。 希望这能帮助到您。

我认为这种情况下没有任何一个变量适用。当链接器在磁盘上发现静态库和动态库时,它实际上会进行选择。您提到的前缀/后缀只会更改在scons中声明的目标的文件名模式。 - BenG
env[SHLIBSUFFIX] 返回一个字符串,其中包含您所需平台的文件后缀。在实际进行踩负评之前测试一下答案是个好主意。 - daramarak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接