0

32 ビット組み込みプロセッサ用に記述された大規模なコードベースをコンパイルして、シミュレーション/単体テスト用に 64 ビット デスクトップ プロセッサで実行しようとしています。結果のオブジェクトを共有ライブラリにする必要があります。これは Windows の問題ではありません。このような dll (/DWIN32) をビルドでき、問題なく動作します。

Linux では、gcc とリンカーの両方に -m32 オプションを指定してコンパイルおよびリンクし、共有ライブラリを取得できます。問題は、このライブラリが (-m32 で指定したように) 32 ビット ライブラリであり、私の 64 ビット アーキテクチャでは動作しないことです。Python で、ライブラリをロードしようとします (ctypes.cdll.LoadLibrary() を使用)

OSError: out.so: wrong ELF class: ELFCLASS32

-mx32 オプションを発見しました。ドキュメントによると、これはまさに私が望むものです:

-mx32 オプションは、int、long、およびポインター型を 32 ビットに設定し、x86-64 アーキテクチャー用のコードを生成します。

そのため、-mx32 をコンパイラとリンカーに渡し (-m32 オプションを置き換えます)、次の結果を取得します (出力を切り取りました)。

/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/libstdc++.so when searching for -lstdc++
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/libstdc++.a when searching for -lstdc++
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/32/libstdc++.so when searching for -lstdc++
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/32/libstdc++.a when searching for -lstdc++
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/libstdc++.so when searching for -lstdc++
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/libstdc++.a when searching for -lstdc++
/usr/bin/ld: cannot find -lstdc++
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libm.so when searching for -lm
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libm.a when searching for -lm
/usr/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libm.so when searching for -lm
/usr/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libm.a when searching for -lm
/usr/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libm.so when searching for -lm
/usr/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libm.a when searching for -lm
/usr/bin/ld: cannot find -lm

gcc 4.7 と gcc 4.8 で同じ結果が得られます。上記の出力は gcc 4.8 からのものです。

gcc-4.8-multilib と g++-4.8-multilib がインストールされています。

私のライブラリパスは次のとおりです。

LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:/usr/lib/gcc/x86_64-linux-gnu/4.8/32:/usr/lib/gcc/x86_64-linux-gnu/4.8/

.bashrc から、リンカーが機能するライブラリにのみバインドすることを読んだ後、絶望的に /4.8/ および /4.8/32/ を追加して、このように指定しました (以下)。

export LIBRARY_PATH=/usr/lib/$(gcc -print-multiarch):/usr/lib/gcc/x86_64-linux-gnu/4.8/32:/usr/lib/gcc/x86_64-linux-gnu/4.8/

私が言及したように、これはWindows上でdllとしてすでに非常にうまく機能しています。何かが欠けているだけだと信じなければなりません。ポインターは 32 ビット、long は 32 ビットである必要があり、すべてが x86_64 で実行される必要があります。-mx32 は、まさにそれを行うと言っています (そうですか?)。

-m32 でコンパイルした後、オブジェクトの 1 つを確認します。

$:~/project$ file foo.o
foo.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped

-mx32 でコンパイルした後、同じオブジェクトをチェックします。

$:~/project$ file foo.o
foo.o: ELF 32-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

私はこれについて間違った方法で進んでいますか?32 ビットの共有ライブラリを何らかの互換性レイヤーで引き続き使用できますか?

これらのリンク エラーに関する gcc 4.7 に対するバグ レポートを見ましたが、結論はあまり出ていませんでした。 このページには、gcc 4.8 が x32 の推奨される最小値であると記載されているため、インストールしました。それでも -- リンクできません。-m32 リンクは問題ありません。

4

2 に答える 2

4

-m32は通常の 32 ビット モードであり、ほとんどの x86-64 GNU/Linux システムには、まだインストールされていない場合にインストールできる 32 ビット ライブラリによるマルチアーキテクチャ サポートがあります。

オプションは、-mx32あなたが望むものではありません。32 ビット アドレスと 64 ビット レジスタおよび命令を使用する x32 ABI のコードをコンパイルします。結果のコードは、32 ビット プロセッサとは互換性がありません (64 ビット命令を使用するため)。また、64 ビット コード (64 ビット アドレスを使用する) との互換性もありません。そのため、libc を含め、ユーザー空間のすべてを念頭に置いてコンパイルする必要があり、カーネルでさえ x32 ユーザー空間とシステムコールをサポートする必要があります: https://unix.stackexchange.com/questions/121424/linux-and- x32-abi-how-to-use (つまり、32 ビット バイナリをサポートするのと同じように、x32 は事実上別のアーキテクチャです。)

問題をさらに複雑にしているのは、あなたが Windows で行ってきたテストが、あなたが考えていることをまったく実行していないということです。/DWIN32Visual C++ コンパイラに渡すと、呼び出されるマクロのみが定義されますWIN32( -DWIN32GCC の場合のように)。コンパイラが 32 ビット バイナリを生成することはありません。64 ビット Windows 実行可能ファイルは32 ビット ライブラリをロードできません。テストしたライブラリは実際には 64 ビットでした。

32 ビット コードを単体テストする場合は、-m32. x32 はそのようなシステムではありません。(ただし、64 ビット カーネルでの 4GiB ではなく、組み込みシステムのユーザー空間で使用できるアドレス空間が 2G または 3GiB しかないことを心配しない限り、64 ビット カーネルでの 32 ビット コードは問題ありません。 .)

于 2015-10-19T21:18:30.847 に答える
1

Your initial error, trying to load the library you successfully built, indicates that you are NOT using a 32-bit version of Python, so it can't build the 32-bit shared library.

If you install an i386 (32-bit) version of Python it should be able to load the library. What's more, that is the version of Python you'll need to run on your embedded i386 target.

Note that all the above assumes your "32bit embedded processor" is i386 compatible. If its not (its an ARM or MIPS or some other 32bit embedded processor instead), you'll need to install cross compilers for that target to build your library and an emulator (such as QEMU) to run executables.

于 2015-10-19T21:26:09.967 に答える