まず、私がやろうとしていることの簡単な説明は次のとおりです。

まず、私がやろうとしていることの簡単な説明は次のとおりです。

私はsnipersimが非常に一般的な「プロジェクト」ではないことを知っていますが、これは他の何よりもLinux /リンクの問題に近いのでここに残っていると仮定します。開発者にも連絡しましたが、まだ答えを受けていません。

まず、私がやろうとしていることの簡単な説明は次のとおりです。

修士論文では、建設シミュレータの狙撃兵(snipersim)を使用しました。http://www.snipersim.org)。私のローカルコンピュータ(Linux Mint 17.2を実行)にダウンロードしてビルドして使用を開始しました。すべてがうまくいきます。

それぞれ数時間かかる数百のシミュレーションを実行する必要があるため、x86_64 OpenSUSE 13.1システムでHTCondorを使用して大学コンピューティングクラスタにアクセスできました。明らかに、クラスタへのルートアクセス権がありません。

ディストリビューションが異なるため、単にバイナリをコピーすることはできないので(後で試してみましたが、コードが異常に機能するため)snipersimを再コンパイルしたいと思います。

私の編集プロセス

condor_submitを使用して並列ジョブを送信できるクラスタのアクセスマシンからsnipersimフォークを複製しました。

SQLite3

必要なライブラリがインストールされていることを確認しましたが、libsqlite3が見つからないことがわかりました。この問題を解決するために、SQLite.orgのウェブサイトからsqlite-autoconf-3090200.tar.gzをダウンロードし、~/sqlite(./configure -prefix=~/sqlite)にインストールするように設定した後make && make install

その後、両方を指すようにSQLITE_PATH設定しました。~/sqliteLIBRARY_PATHLD_LIBRARY_PATH~/sqlite/lib

今まではそんなに良くなった。

(今後の参考のためにはい、SQLite3は-fPICでコンパイルされます)

狙撃兵

すべてのライブラリが完成したら、スナイパーコンパイルを開始しました。ホームディレクトリに切り替えてを入力しますmake。私のホームコンピュータのように、すべてが大丈夫に見えます。メインの実行可能ファイルをリンクする最終段階に達する前に、すべての依存関係、ソースファイルなどを通過しますsniper。ここで突然エラーが発生して停止します。

[LD    ] lib/sniper
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.4/../../../../x86_64-pc-linux-gnu/bin/ld: ~/sniper/standalone/../standalone/standalone.o: relocation R_X86_6ldrelocationssnipecompilation4_32S against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
~/sniper/standalone/../standalone/standalone.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
Makefile:34: recipe for target '~/sniper/standalone/../lib/sniper' failed
make: *** [~/sniper/standalone/../lib/sniper] Error 1

このエラーメッセージは私をパニックにさせました。すべてが-fPICでコンパイルされるため、エラーは外部からインポートされたいくつかのライブラリに関連している必要があります。

ここで接続のために実行したコマンド(スナイパーを使ったことがない人のため)(実際には「~」ではなくフルパスを使用しますが、個人識別情報がたくさん含まれているので「~」に置き換えました):

g++ -L~/sniper/standalone/../lib -L~/sniper/standalone/../sift -L~/sniper/standalone/../pin_kit/extras/xed-intel64/lib -L~/sqlite/lib -L~/sniper/standalone/../pin_kit/extras/xed2-intel64/lib -o ~/sniper/standalone/../lib/sniper ~/sniper/standalone/../standalone/exceptions.o ~/sniper/standalone/../standalone/standalone.o -lcarbon_sim -lpthread -lsift -lxed -L~/sniper/standalone/../python_kit/intel64/lib -lpython2.7 -lrt -lz -lsqlite3 -lxed -O2 -g -std=c++0x

具体的には、-lcarbon_sim -siftこのプロセスの前半でコンパイルされたカスタムライブラリを参照し、makeIntel -lxedPINライブラリ(プロセッサの検出に使用されます)を参照してください。

私の考え/私が試したこと

これは素晴らしいエラーメッセージです。何らかの理由で、Standalone.oは場所依存であり、共有オブジェクトにコンパイルできないと述べられています。みんなコンパイル段階には-fPIC(トリプルチェック)があります。もう一度考えるのは、引き付けるライブラリの1つが-fPICなしでコンパイルされたことです。その可能性は低く、何か見落としていることは明らかです。 ldにインポートするすべてのライブラリのリストを印刷させる方法はありますか?たとえば、問題を特定できる場合は、手動でコンパイルされたライブラリをインポートすることもできます。

私の自宅のコンピュータで再配置を確認しましたが、ldが(R_X86_64_32S against .rodata.str1.1)について文句を言うスタンドアロン.oファイルに同じ再配置がありますが、すべてがうまくいきます。

私はこれがSQLite3のカスタムインストールのためであると思って(自宅のコンピュータのパッケージマネージャを介してインストールしました)、クラスタと同じプロセスで自宅のコンピュータにコピーをインストールしてみました。すべてがまだ機能し、lddを介して実際に私のコピー(システムバージョンではない)に接続されていることを確認しました。

また、2つのシステム間のgcc、g ++、ldバージョンを比較しましたが、一致しました。

また、奇妙なことを発見しました。ファイル~/sniper/lib/pin_sim.so(インテルPINライブラリをインポートするいくつかの狙撃コードでコンパイルされています)は、64ビットの動的にリンクされたELF実行可能ファイル(予想どおり)ですが、自宅のコンピュータで実行すると印刷するとすべてldd pin_sim.so印刷not a dynamic executableされます。使用される共有ライブラリ。pin_sim.so私のコンピュータからクラスタにコピーしようとしましたが、lddもそれを読み取ることができませんでした。readelf -d pin_sim.soそれでも両方のコンピュータで動作します。

これはとても奇妙です。 readelf / objdumpなしでlddが失敗することについて私が見つけることができる唯一の参照は、64ビットシステムの32ビット実行可能ファイルから呼び出されたときです。この場合、実行可能ファイルとシステムは両方とも64ビットなので、そうではありません。


私は何をすべきかわからない。同様の問題に対する解決策を見つけるために今日約5時間Webを検索しましたが、成功しませんでした。ここに誰かがアイデアを持っていることを願っています。


編集1:2つのシステム間のリンカーパラメータの比較

-vsblingxが提案したように、リンカ(collect2)を呼び出すときの違いを見つけるために、引数を使用して両方のシステムでg ++を実行しました。私はそれらを少しクリーンアップし(フルパスではなく関連ファイル名のみ)、ライブラリディレクトリを削除しました(-L):

一般的に使用されるパラメータ:

--eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o lib/sniper
crti.o crtn.o
standalone/exceptions.o standalone/standalone.o
-lcarbon_sim -lpthread -lsift -lxed -lpython2.7 -lrt -lz -lsqlite3 -lxed -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc 

私の家のコンピュータに固有のパラメータ(スナイパーが動作するLinux Mint 17.2):

--sysroot=/ --build-id -z relro
crt1.o crtbegin.o crtend.o

クラスタシステム関連パラメータ(効果がない場合):

-pie -z now
Scrt1.o crtbeginS.o crtendS.o

接続についてはわかりませんが、私の家の設定には含まれていcrt1.o crtbegin.o crtend.oてクラスタには含まれていますScrt1.o crtbeginS.o crtendS.o(追加の「S」を参照)。これらのファイルが正確にどのような役割を果たしているのか、そしてSファイル名とはどういう意味ですか? (私の考えでは、「共有」または「静的」のいずれかのようです。)

ベストアンサー1

理由

"-pie"パラメーターがSniperのコンパイルを中断するようです。私の自宅のコンピュータに追加しようとしましたが、同じエラーで失敗しました。クラスタラインからそれを削除すると、リンカは成功します。

ユーザーsilynxが述べたように、OpenSUSE(少なくともクラスタ内のもの)は接続時に実行可能ファイルにPIEを使用するように強制しますが、Linux Mintはそうではありません。


解決策

COLLECT_GCC_OPTIONSをオーバーライドするために-fno-pieファイルに$(TARGET)リンカー呼び出しを追加すると、すべてがうまくいくようです。standalone/Makefile-pie

ldd pin_sim.soそれでも動作しませんが、これはまったく別の問題です。実際、これについては別の質問を投稿することもできます。

おすすめ記事