Linux下使用g++进行静态编译

Sup*_*dra 4 c++ linux openssl g++

我静态编译了 OpenSSL 库。我想MyModule使用 OpenSSL 库进行静态编译。我正在使用 Makefile 来执行相同的操作

LDFLAGS      = $(LD_SHARED_FLAGS) -fPIC -static -lssl -lcrypto
Run Code Online (Sandbox Code Playgroud)

LD_SHARED_FLAGS在根Makefile中有

LD_SHARED_FLAGS     = -z text
Run Code Online (Sandbox Code Playgroud)

当我运行 make 时,我得到这个,

g++ -shared -L../../lib  -z text -fPIC -static -lssl -lcrypto  -o libMyModule.so debug_utils.o  MyModule.o   labels.o -L/path_to_openssl/lib -lssl -lcrypto -lc
Run Code Online (Sandbox Code Playgroud)
/usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbeginT.o: relocation R_X86_64_32 against `__TMC_END__' can not be used when making a shared object; recompile with -fPIC

/usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbeginT.o: error adding symbols: Bad value

collect2: error: ld returned 1 exit status

make: *** [libMyModule.so] Error 1
Run Code Online (Sandbox Code Playgroud)

我是否使用了正确的静态编译标志?

我该如何修复这个错误?

Mik*_*han 7

看来您想要将静态库链接libssl.alibcrypto.a共享库中libMyModule.so

将 GCC 选项添加-static到链接命令不仅会产生这种效果,还会产生更大的效果。它的作用是请求完全静态的链接。链接器必须查找并使用所有必需库的静态版本:不仅是您在链接命令中指定的库,还包括默认库:libclibstdc++libgcc,以及 C 运行时支持二进制文件的静态链接变体crt*.o.

也许,您并不想要所有这些-static东西,即使您不介意拥有它,它也与-shared.

-shared当然,您需要创建一个共享库。链接到共享库的所有目标文件必须是位置无关代码,并使用-fPIC.

您遇到的错误:

/usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbeginT.o: \
relocation R_X86_64_32 against `__TMC_END__' can not be used when making a shared object; \
recompile with -fPIC
Run Code Online (Sandbox Code Playgroud)

告诉您crtbeginT.o链接所需的 C 运行时二进制文件未使用-fPIC;进行编译 不是位置无关的代码,因此不能链接到共享库中。

crtbeginT.o对于您通过-static选项进行链接是必需的。如果您没有指定-static,则将crtbeginS.o改为链接,这是此运行时二进制文件的 PIC 变体,用于与共享库链接,并且不会发生错误。

所以不要指定-static。它不会与 混合,也不是将和 的静态版本链接到-shared的方式libssllibcryptolibMyModule.so

实现这一目标的方法不止一种。-lssl -lcrypto 最简单的方法是在链接命令中替换为显式指定这些库的静态版本的选项,即

-l:libssl.a -l:libcrypto.a
Run Code Online (Sandbox Code Playgroud)