将多个库静态链接到一个.so

时间:2015-02-22 19:40:28

标签: c gcc

我有一个项目foo取决于a,而b又取决于cconfigure依赖make。我的构建脚本pull / foo.so / a.so是来自源的三个依赖项,并且编译正常。

现在,为了分发b.so,我还需要将所有依赖项(c.sofoo.sofoo)一起分发。我想构建一个a,其中包含b及其所有依赖项的所有对象;这样我可以分发一个库。

cfoo.sogcc -shared ./my/src/*.c \ -I./a/include -I./b/include -I./c/include \ -L ./a/.libs -L./b/.libs -L./c/.libs \ -la -lb -lc \ -o ./foo.so \ -w -fPIC -m64 \ -std=c99 都使用autotools,并在src /目录中生成关联的* .o文件,以及包含通常的.libs /目录* .ar,* .lo,* .lai和* .so文件的所有内容都是有效的。现在,我正在使用这组gcc标志来构建我的readelf -d

foo.so

(请注意,“-la -lb -lc”只是每个依赖项的“-l”标志,我不只是弄乱标志)。

在结果a上使用a确实表明它依赖于/usr/bin/ld: ./a/.libs/a.a(bands.o): relocation R_X86_64_32S against `.rodata' can not be used when making a shared object; recompile with -fPIC ./a/.libs/a.a(bands.o): error adding symbols: Bad value 。鉴于我已经获得了所有依赖项的所有构建文件,我觉得我只是缺少一些标记“在查找要链接的* .o文件时包含此路径”。

我尝试了各种各样的事情,老实说甚至不记得导致它们的不同错误和条件。最有希望的领先是this question,但在删除我的“-l”行以支持“-Wl, - whole-archive”行之后,我得到了这个错误(注意“aa”只是*。 a for {{1}}):

{{1}}

这对我没有意义,因为这些文件需要是PIC才能将它们构建成* .so,对吧?这些依赖项的构建过程产生* .so。

我在Mint Linux上,如果重要的话。

2 个答案:

答案 0 :(得分:3)

错误信息非常清楚需要做什么。

/usr/bin/ld: ./a/.libs/a.a(bands.o): relocation R_X86_64_32S against
`.rodata' can not be used when making a shared object; recompile with -fPIC
                                                      ^^^^^^^^^^^^^^^^^^^^^

./a/.libs/a.a(bands.o): error adding symbols: Bad value

除非使用-fPIC选项编译,否则我们属于静态库的目标代码不能放在共享库中。

答案 1 :(得分:1)

在这里的回答者的帮助下,我得到了一个有效的解决方案。我从根本上误解了autotools生成两组* .o文件,一组是PIC,一组是不是。每个位置都在* .lo文件中。我的依赖项(abc)都是使用autotools构建的,我需要链接PIC版本,而不是组合的静态* .a版本。

我还需要使用libtool将构建过程分成两部分。编译阶段只是为了构建我的代码,以及链接器阶段,它查看了依赖项的PIC版本。

我最终没有一个漂亮的剧本,但是如果有人遇到同样的场景,我的丑陋的gcc线看起来像。希望它会成为一个跳跃点,而不是我想出的那么糟糕。

find ./my/src -name "*.c" -exec \
libtool --mode=compile gcc -c -O -g \
    -I./a/include -I./b/include -I./c/include \
    -L./a/.libs/*.lo -L./b/.libs/*.lo -L./c/.libs/*.lo \
    -la -lb -lc \
    -w -m64 \
    -std=c99 \
    {} \;

gcc \
    -g -O -w -fPIC -m64 -std=c99 -shared \
    -o ./foo.so \
    $(find . -wholename "*.libs/*.o");