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


84

このソースコードをVPSのメイクファイルからコンパイルしようとしていますが、機能しません。VPSは64セントの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

誰が何が悪いのか知っていますか?


6
やってみましたrecompile with -fPICか?
Joachim Isaksson 2013年

申し訳ありませんが、これを行う方法がわかりません。グーグルで「-fPIC」について何も見つかりません。
user1667191 2013年

4
次のようなものを試してくださいCOMPILE_FLAGS=-c -O3 -w -DLINUX -fPIC -I../SDK/amx/
Joachim Isaksson 2013年


9
グーグルで-fPICを検索しても、確かに何も見つかりません。マイナスを削除するか、引用符「-fPIC」を使用します。そうしないと、fPICを含むすべての結果が省略されます。
d00d 2017

回答:


119

コンパイラが指示したことを実行し-fPICます。つまり、で再コンパイルします。このフラグの機能と、この場合にフラグが必要な理由については、GCCマニュアルのコード生成オプションを参照してください。

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

最後に、ウィキペディアでもそれについて読むことができます。


3
-fPICで再コンパイルする方法を説明していただけますか?
Beni Bogosel 2014

12
@Beni Bogosel:これはとても簡単です。ライブラリの-fPICすべてのソースファイル(ファイルなどの翻訳単位*.cpp)のすべてのコンパイラ呼び出しにを追加するだけです。これを行う具体的な方法は、使用するビルドシステムによって異なります。たとえば、CMakeではを発行できますset_target_properties(${LIBRARY_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON)。この人の場合(プレーンな古いMakeを使用)、彼はCOMPILE_FLAGS+=-fPICこの変数を使用してライブラリのすべてのソースファイルのコンパイルフラグのセットを示すため、実行する必要があります。
アレクサンダーシュカエフ2014

1
configure使っ-fPICを有効にする:のconfigure --enable-共有を参照してくださいstackoverflow.com/a/850464/440403
カミノ

49

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

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

基本的に、それは変装したファイルが見つからないというエラーでした。

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


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

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


1
完璧です、「それは変装したファイルが見つからないエラーでした」。私の場合、依存関係はまだインストールされていません。
Litty 2017

+1私の場合、opensslの新しいコピーが手動で作成され、共有ライブラリなしでインストールされました。私が構築しようとしていたライブラリは、すでに-fPICでコンパイルされています。とにかく、コンパイラがこのエラーを認識して、「共有ライブラリlibssl.soが見つかると予想されますが、互換性のない静的ライブラリ/usr/local/ssl/lib/libssl.aしか見つかりませんでした」などのわかりにくいエラーメッセージが表示される可能性はありますか。?
Rohan Mahy 2017

1
ありがとう。make -jがあり、このソフトウェアパッケージの並列実行は許可されていませんでした。
MikeBergmann

私の場合、「find_library(NGHTTP2_LIB NAMES libnghttp2.a libnghttp2.solibnghttp2.dylib)」という行があります。。それは私のための前の仕事に使用しているもの、それが唯一.Aの1を拾った、私は後で(NGHTTP2_LIB NAMES libnghttp2.so libnghttp2.a libnghttp2.dylib)find_libraryにそれを変更」し、それが仕事を始めた私の懸念は、あります?
ナバチンデ

1
@NabaChinde私はあなたの結果に関する文脈情報が不足しているので、あなたの質問に対する答えがないのではないかと心配しています。私は確かにあなたがあなたの労働状況と予期しない行動を説明する別の質問を投稿することをお勧めします。
XavierStuvw

11

必ずしもコンパイルフラグについてではありません。distccを使用すると、gentooでも同じエラーが発生します。

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


9

-no-pieリンカー段階のオプションで修正しました:

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

4

プロジェクトを掃除するだけで解決しました。

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


2

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


0

https://stackoverflow.com/a/19365454/10593190に対する@caminoのコメントとXavierStuvwの返信と同じ解決策を取得しています

私はそれを(ffmpegをインストールするために)最初からすべてのインスタンスを$ ./configure置き換えて再インストールするだけで動作するようになりました$ ./configure --enable-shared(最初に、前回の試行から.soファイルを含むすべてのフォルダーとファイルを削除してください)。

どうやらこれはhttps://stackoverflow.com/a/13812368/10593190のために動作します

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.