web-dev-qa-db-ja.com

「共有オブジェクトの作成時に、 `.rodata.str1.8 'に対するR_X86_64_32の再配置は使用できません」でコンパイルが失敗する

このソースコードをVPSのメイクファイルからコンパイルしようとしていますが、動作しません。 VPSは64 Cent OSです

ここに完全なエラーがあります

# make
gcc -c -O3 -w -DLINUX -I../SDK/amx/ ../SDK/amx/*.c
g++ -c -O3 -w -DLINUX -I../SDK/amx/ ../SDK/*.cpp
g++ -c -O3 -w -DLINUX -I../SDK/amx/ *.cpp
g++ -O2 -fshort-wchar -shared -o "TCP_V1.so" *.o
/usr/bin/ld: TCP-LINUX_V1.o: relocation R_X86_64_32 against `.rodata.str1.8' can not be     used when making a shared object; recompile with -fPIC
TCP-LINUX_V1.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [all] Error 1

ここに私のメイクファイルがあります:

GPP=g++
GCC=gcc
OUTFILE="TCP_V1.so"

COMPILE_FLAGS=-c -O3 -w -DLINUX -I../SDK/amx/

all:
    $(GCC) $(COMPILE_FLAGS) ../SDK/amx/*.c
    $(GPP) $(COMPILE_FLAGS) ../SDK/*.cpp
    $(GPP) $(COMPILE_FLAGS) *.cpp
    $(GPP) -O2 -fshort-wchar -shared -o $(OUTFILE) *.o

誰が間違っているか知っていますか?

68
user1667191

コンパイラから指示されたとおりに実行します。つまり、-fPICで再コンパイルします。この場合、このフラグが何をするのか、なぜ必要なのかについては、GCCマニュアルのコード生成オプションをご覧ください。

簡単に言うと、位置独立コード(PIC)は、メモリアドレスに依存しない生成されたマシンコードを指します。つまり、それがどこであるかについての仮定を行いません。 RAMにロードされました。共有オブジェクト(SO)にはRAM内の位置を動的に変更する機能があるはずなので、位置に依存しないコードのみを共有オブジェクト(SO)に含めることになっています。

最後に、Wikipediaでそれについて読むことができます。

105

私の場合、makeコマンドがLDFLAGS環境変数で示されるリモートディレクトリから共有ライブラリ(*.soファイル)を取得することを期待していたため、このエラーが発生しました。誤って、そこでは静的ライブラリのみが利用可能でした(*.laまたは*.aファイル)。

したがって、私の問題はコンパイルしているプログラムにあるのではなく、取得しようとしているリモートライブラリにあります。そのため、再配置エラーによって中断されたコンパイルにフラグ(たとえば、-fPIC)を追加する必要はありませんでした。むしろ、リモートライブラリを再コンパイルして、共有オブジェクトが利用できるようにしました。

基本的に、それは偽装されたfile-not-foundエラーです

私の場合、共有ライブラリと静的ライブラリの両方がデフォルトとしてビルドされているため、必要なプログラムのconfigure呼び出しの誤った--disable-sharedスイッチを削除する必要がありました。


ほとんどのプログラムが両方のタイプのライブラリを同時にビルドすることに気づいたので、私の場合はおそらくコーナーケースです。一般に、デフォルトに応じて、共有ライブラリを有効にする必要がある場合があります。

コンパイルスイッチとデフォルトの特定の状況を調べるには、通常[オプション機能]セクションにある./configure --help | lessで表示される概要を読み上げます。多くの場合、この読み取り値は、依存関係プログラムの進化中に更新されないインストールガイドよりも信頼性が高いことがわかりました。

41
XavierStuvw

コンパイルフラグに関するものではありません。distccを使用する場合、gentooでも同じエラーが発生します。

その理由は、distccサーバーでは強化されていないプロファイルを使用しており、クライアントではプロファイルが強化されているためです。このディスカッションを確認してください: https://forums.gentoo.org/viewtopic-p-7463994.html

10
EIIPII

「きれいな」が私のためにそれを解決しました。

私のプロジェクトはC++アプリケーションです(共有ライブラリではありません)。多くのビルドが成功した後、このエラーがランダムに発生しました。

4

リンカステージの-no-pieオプションで修正:

g++-8 -L"/home/pedro/workspace/project/lib" -no-pie ...
0
Pedro H

同じ問題がありました。 -fPICフラグを使用して再コンパイルしてみてください。

0