SCons使用静态库(.a)创建共享库(.so)

时间:2010-02-11 17:48:30

标签: static static-libraries portability static-linking scons

我正在尝试让SCons创建一个共享库。进入.so的其中一项是.a静态库。

我有一句话:

env_2.SharedLibrary('libstuff.so', \
  Split("""stuff.cxx mylib/libMine.a""")

运行后,我收到此错误:

scons: *** Source file: mylib/libMine.a \
is static and is not compatible with shared target: libstuff.so

但是,我知道可以通过以下命令从.a创建共享库:

g++ -m32 -shared -o libstuff.so stuff.o mylib/libMine.a

任何有关实现此功能或任何变通方法的想法都将不胜感激。


相关问题:如何让scons在-shared调用的LINK命令行上添加额外的字符串Program()?如果我能做到这一点,我认为它会满足我的需求。

6 个答案:

答案 0 :(得分:10)

尝试在SConstruct中设置env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME']=1

答案 1 :(得分:1)

此问题并非特定于scons。要构建共享库,您需要使用与位置无关的代码(-fPIC)编译的对象。最好的办法是使用正确的选项编译源文件中的共享库。

在SCons中,您可以定义用于构建libMine.a和libShared.so的目标列表。


更新:对于您的第二个问题,SharedLibrary构建器可能会执行您所需的操作:

SharedLibrary('foo', ['f1.c', 'f2.c', 'f3.c'])

如果没有,LINKFLAGS设置传递给链接命令的标志。

答案 2 :(得分:0)

env_2.SharedLibrary('libstuff.so', Split("""stuff.cxx"""), LIBS='libMine.a', LIBPATH='mylib')

这应该有用。

答案 3 :(得分:0)

我在cygwin下遇到了同样的问题。我在构建对象时将'-fPIC'选项传递给gcc并得到以下警告:

  

警告:-fPIC被目标忽略(所有代码都与位置无关)

我还将'-shared'传递给了link命令。我终于得到了错误

  

“***。lib是静态的,与共享目标不兼容:myso.dll”

似乎scons不允许直接从obj或lib文件创建,并且可以从源列表文件(使用SharedLibrary())或源文件+'LIBS'选项创建,如dummytaurus所说。我很好奇。

答案 4 :(得分:0)

问题出在函数SharedFlagChecker(Default.py)中,它仅检查内部“共享”标志。 SCons文档使您相信它通过后缀(SHOBJSUFFIX)保持共享对象和静态对象之间的区别,但不是这样。修复很容易。在文件scons-local.../SCons/Default.py中找到SharedFlagChecker并修改:

def SharedFlagChecker(source, target, env):
    same = env.subst('$STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME')
    if same == '0' or same == '' or same == 'False':
        for src in source:
            try:
                shared = src.attributes.shared
            except AttributeError:
                # Replace this line: shared = None
                shared = env.Dictionary()['SHOBJSUFFIX'] == src.suffix
            if not shared:
                raise SCons.Errors.UserError("Source file: ...") 

现在,通过SharedObject构建器创建的对象可以在共享库中链接。

答案 5 :(得分:0)

解决此问题的解决方案已被用作“ SharedObject”,如下所示:

ASN1CObjectFile = envCProcesses.SharedObject(target = "OTCMsg.os",
                                             source = "OTCMsg.c",
                                             CFLAGS = envCProcesses["CFLAGS"] + ["-Wno-unused"])

和:

OTCLibSharedLibrary = envCProcesses.SharedLibrary(env["OTC_LIBPATH"] + "/libOTCLib" + env["SHLIBSUFFIX"],
                                              ASN1CObjectFile +
                                              [ASN1AllocatorSource,
                                               "OTCLib.c"],
                                              LIBPREFIX = "")

最诚挚的问候,