改写的问题:
如何使用 --whole-archive 链接标志和 scons 将静态库链接到共享库,同时维护依赖关系。
我重申你的问题只是为了确保我们都清楚地了解你想要完成的任务。如果我没有正确理解您问题的意图,请发表评论。
为什么它不适合你:
您不能将库包含在LIBS
,因为你想用--whole-archive
旗帜。如果您将此条目放入LINKFLAGS
它可以工作,但你会失去依赖跟踪。
Answer:
当您将库从某个条目移动到LIBS
到一个条目LINKFLAGS
你失去了implicit依赖关系,但是没关系,只需设置一个explicit依赖于Depends
.
工作示例:
文件布局
.
├── A.cpp
├── A.h
├── B.cpp
├── B.h
├── main.cpp
└── SConstruct
Files
A.cpp
#include "A.h"
int foo2(void) {
return 2;
}
A.h
#ifndef __A__
#define __A__
int foo2(void);
#endif
B.cpp
#include "B.h"
#include "A.h"
int bar(void) {
return 2 * foo2();
}
B.h
#ifndef __B__
#define __B__
int bar(void);
#endif
main.cpp
#include <iostream>
#include "B.h"
using namespace std;
int main() {
cout << "Sum of foo and bar = " << bar() << endl;
return 0;
}
构建
import os
# Top level Build Environment
env = Environment()
# Library A
envA = env.Clone()
libA = envA.StaticLibrary('A.cpp')
# Library B
envB = env.Clone()
envB.Append(LINKFLAGS=['-Wl,--whole-archive,./libA.a,--no-whole-archive'])
libB = envB.SharedLibrary('B.cpp')
Depends(libB, libA)
# Test Program
envE = env.Clone()
envE.Append(LIBS=['B'],
LIBPATH=['.'],
RPATH=[os.path.abspath(os.curdir)])
envE.Program('example', 'main.cpp')
To Run:
将所有文件复制到同一目录,然后输入scons
在该目录中。如果您构建并请求依赖关系树,这是您应该在 Linux 上看到的输出。 (我使用的是 Fedora 21)
>> scons --version
SCons by Steven Knight et al.:
script: v2.3.4, 2014/09/27 12:51:43, by garyo on lubuntu
engine: v2.3.4, 2014/09/27 12:51:43, by garyo on lubuntu
engine path: ['/usr/lib/scons/SCons']
Copyright (c) 2001 - 2014 The SCons Foundation
>> scons --tree=prune
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o A.o -c A.cpp
g++ -o B.os -c -fPIC B.cpp
g++ -o main.o -c main.cpp
ar rc libA.a A.o
ranlib libA.a
g++ -o libB.so -Wl,--whole-archive,./libA.a,--no-whole-archive -shared B.os
g++ -o example -Wl,-rpath=/full/path/to/build/directory main.o -L. -lB
+-.
+-A.cpp
+-A.h
+-A.o
| +-A.cpp
| +-A.h
| +-/bin/g++
+-B.cpp
+-B.h
+-B.os
| +-B.cpp
| +-A.h
| +-B.h
| +-/bin/g++
+-SConstruct
+-example
| +-main.o
| | +-main.cpp
| | +-B.h
| | +-/bin/g++
| +-/bin/g++
| +-libB.so
| +-[B.os]
| +-libA.a
| +-[A.o]
| +-/bin/ar
| +-/bin/ranlib
+-[libA.a]
+-[libB.so]
+-main.cpp
+-[main.o]
scons: done building targets.
>> ./example
Sum of foo and bar = 4
该示例的作用:
- 构建静态库A。
- 构建动态库B
--whole-archive
库 A 上的链接标志。
- 构建一个链接到库 B 的可执行文件,并执行库 B 中使用库 A 中函数的函数。
- 正确跟踪目标之间的依赖关系。
结论:
从上面的依赖关系图中可以看到,库 A 已正确列为库 B 的依赖项。
Enjoy!