如何在scons中添加--whole-archive链接器选项? [英] How do I add --whole-archive linker option in scons?

查看:137
本文介绍了如何在scons中添加--whole-archive链接器选项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个仅在静态范围内与应用程序交互的库.这要求我使用--whole-archive选项链接库,以避免链接器优化"库(这样做是因为链接器从未真正看到我的库正在使用).

I have a library that only interacts in static scope with an application. This requires me to link the library with the --whole-archive option to avoid the linker from "optimizing" out the library (this is done because the linker never actually sees my library being used).

问题是我还没有找到在scons中为特定库添加此链接器选项的方法.

The issue is that I haven't found a way to add this linker option for a specific library in scons.

env.Append(LIBS=['mylib']) #I don't have the linker option
env.Append(LINKFLAGS=['-Wl,--whole-archive','-lmylib']) #I don't add myself to the scons dependency tree, I also get added to the link line before the LIBPATH variable.

我如何在scons中优雅地支持链接器标志?

How do I support linker flags elegantly in scons?

推荐答案

改写的问题:

如何使用--whole-archive链接标志通过scons将静态库链接到共享库,同时保持依赖性.

我正在重申您的问题,以确保我们双方都清楚地了解您要完成的工作.如果我没有正确抓住您问题的意图,请发表评论.

I am restating your question just to make sure we both have a clear understanding of what you are trying to accomplish. Please comment if I am not properly capturing the intent of your question.

您不能将库包含在LIBS中,因为您想用--whole-archive标志将库包围.如果将此条目放置在LINKFLAGS中,则可以使用,但是会丢失依赖项跟踪.

You cannot include the library in LIBS, because you want to surround the library with the --whole-archive flags. If you place this entry in the LINKFLAGS it could work, but you lose your dependency tracking.

将库从LIBS中的条目移动到LINKFLAGS中的条目时,您会失去 implicit 依赖关系,但这很好,只需设置一个 explicit Depends的依赖项.

When you move the library from an entry in LIBS to an entry in LINKFLAGS you lose the implicit dependency, but that's fine, just set an explicit dependency with Depends.

.
├── A.cpp
├── A.h
├── B.cpp
├── B.h
├── main.cpp
└── SConstruct

文件

A.cpp

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;
}

SConstruct

SConstruct

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')

要运行:

将所有文件复制到同一目录,然后在该目录中键入scons.如果您构建并要求依赖树,这是您应该在linux上看到的输出. (我正在使用Fedora 21)

To Run:

Copy all the files to the same directory, and type scons in that directory. This is the output you should see on linux if you build and ask for the dependency tree. (I'm using 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.
  • 使用库A上的--whole-archive链接标志构建动态库B.
  • 构建一个链接到库B中的可执行文件,并执行库B中的一个函数,该库利用库A中的函数.
  • 正确跟踪目标之间的依赖关系.
  • What The Example Does:

    • Builds a static library A.
    • Builds a dynamic library B with the --whole-archive link flag on library A.
    • Builds an executable that links in library B and executes a function from library B that utilizes a function in library A.
    • Properly tracks dependencies between targets.
    • 从上面的依赖关系图中可以看到,库A已正确列出为库B的依赖关系.

      You can see from the dependency graph above that library A is correctly listed as a dependency of library B.

      享受!

      这篇关于如何在scons中添加--whole-archive链接器选项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆