在没有-fPIC的情况下将静态库链接到共享库 [英] Linking a static library into a shared library without -fPIC

查看:120
本文介绍了在没有-fPIC的情况下将静态库链接到共享库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将目标文件和静态库合并到共享库中,但是静态库不应公开,它仅在进入共享库的对象文件中被引用.我认为在这种情况下,我不需要使用 -fPIC 编译静态库,但是我不知道如何告诉链接器我不会使用静态库中的符号的事实.为了说明我的问题,请获取以下文件:

I want to combine object files and a static library into a shared library but the static library shall not be exposed, it is only referred in the object files that go into the shared library. I think that in this case, I do not need to compile the static library with -fPIC but I do not know how to tell the linker that the fact that I will not use the symbols from the static library. As an illustration of my problem, take the following files:

文件 foo.cpp :

#include "static.h"
using namespace std;

string version_info()
{
    return static_version_info();
}

文件 static.cpp :

#include"static.h"
#include <vector>
using namespace std;
string static_version_info()
{
    std::vector<int> ivec;
    return to_string(ivec.size());
}

文件 static.h :

#ifndef STATIC_H
#define STATIC_H
#include<iostream>
using namespace std;
std::string static_version_info();
#endif 

然后做

$ g++ -c foo.cpp -o foo.o -fPIC
$ g++ -c static.cpp -o static.o
$ gcc-ar rcs static.a static.o
$ g++ -shared foo.o static.a
/usr/bin/ld: static.a(static.o): relocation R_X86_64_PC32 against symbol `_ZNSt6vectorIiSaIiEEC1Ev' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status

问题:如何调整上一个命令,这样我不会出现错误?这可能吗?

Question: How can I adjust the last command such I do not get an error? Is this possible?

请注意,我不想使用 -fPIC 编译 static.cpp 不需要共享库中的符号(此处 return_static_version_info() ).

推荐答案

您不能(或者至少您不应该)将静态库链接到共享库.

You cannot (or at least you should not) link a static library into a shared library.

即使您似乎成功地将非PIC静态库 libX.a 链接到共享库 libY.so 中,结果也不会与位置无关的代码(因此会有很多无用"或烦人"的重定位).

Even if you happen to apparently succeed in linking a non-PIC static library libX.a into a shared library libY.so, the resulting thing won't have position-independent code (so would have a lot of "useless" or "annoying" relocations).

共享库只需要包含与位置无关的代码(实际上);但是静态库不包含PIC.

A shared library needs to contain only position-independent code (in practice); but a static library does not contain PIC.

我不想用-fPIC编译static.cpp

I do not want to compile static.cpp with -fPIC

但是你真的应该.

有关详细信息,请阅读Drepper的 如何编写共享库 .

Read Drepper's How to Write Shared Libraries for details.

顺便说一句,某些Linux发行版(例如Debian)提供了一个 libc6-pic 软件包,其中提供了/usr/lib/x86_64-linux-gnu/libc_pic.a 等文件这是与位置无关的代码的静态库.这可能用于扩展系统的 libc.so.6 ,例如您自己的函数(或您自己的 malloc 等).

BTW, some Linux distributions (e.g. Debian) provide a libc6-pic package giving files such as /usr/lib/x86_64-linux-gnu/libc_pic.a which are a static library of position-independent code. This might be used to extend your system's libc.so.6 with e.g. your own function (or your own malloc, etc...).

在实践中,您最好使用 -fPIC 重新编译静态库代码;BTW x86-64 ISA旨在促进PIC.

In practice, you'll better recompile your static library code with -fPIC; BTW the x86-64 ISA was designed to facilitate PIC.

最后,如果您关心优化,则有很多其中.您是否考虑过使用 gcc -O3 -fPIC -flto 进行编译和链接?在某些情况下,您可以考虑使用 -ffast-math (可针对C标准进行优化),或将 -O3 替换为 -Ofast .

At last, if you care about optimizations, there are many of them. Did you consider compiling and linking with gcc -O3 -fPIC -flto ? In some cases, you might consider -ffast-math (which enables optimizations against the C standard), or replacing -O3 with -Ofast.

您当然应该使用最新的GCC或Clang编译器(或最新的专有 icc ).这个古老的问题(在您的评论中提到)约为4.7.2018年秋季的当前GCC是 GCC 8 Clang 7 .编译器在优化方面不断取得进步.

And you surely should use a recent GCC or Clang compiler (or a recent proprietary icc). This old question (mentioned in your comments) is about 4.7. Current GCC in fall 2018 is GCC 8, and GCC 9 is worked upon (so should appear in spring 2019). Current Clang is Clang 7. Compilers are continuously making progress on optimizations.

您可能要下载最新版本的GCC或Clang的 source tarball,并在计算机上进行构建.这是拥有这些编译器最新版本的好方法,因为发行商通常更喜欢它们的较旧版本(即使与非标准兼容代码兼容).

You might want to download the source tarball of the latest release of GCC or of Clang and build that on your computer. This is a good way to have a recent version of these compilers, since distribution makers often prefer an older variant of them (which is compatible even with non-standard compliant code).

这篇关于在没有-fPIC的情况下将静态库链接到共享库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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