我有一个项目foo
取决于a
,而b
又取决于c
。configure
依赖make
。我的构建脚本pull / foo.so
/ a.so
是来自源的三个依赖项,并且编译正常。
现在,为了分发b.so
,我还需要将所有依赖项(c.so
,foo.so
和foo
)一起分发。我想构建一个a
,其中包含b
及其所有依赖项的所有对象;这样我可以分发一个库。
c
,foo.so
和gcc -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上,如果重要的话。
答案 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文件中。我的依赖项(a
,b
和c
)都是使用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");