RPM、DEB、Flatpak、Snapなどのバイナリパッケージを作成する開発者の場合は、さまざまなターゲットプラットフォーム用にコードをコンパイルする必要があります。一般的なターゲットには、32ビットおよび64ビットのx86とARMが含まれます。さまざまな物理マシンまたは仮想マシンでビルドを実行できますが、それは複数のシステムを維持することを意味します。代わりに、GNUコンパイラコレクション(GCC)を使用してクロスコンパイルし、単一のビルドマシンからいくつかの異なるアーキテクチャのバイナリを生成できます。
クロスコンパイルしたい単純なサイコロを振るゲームがあると仮定します。ほとんどのシステムではCで記述されたものは比較的簡単なので、リアリズムのために複雑さを加えるために、この例をC ++で記述しました。したがって、プログラムはCに存在しないものに依存します( iostream 、具体的には)。
#include <iostream>
#include <cstdlib>
using namespace std;
void lose (int c);
void win (int c);
void draw ();
int main() {
int i;
do {
cout << "Pick a number between 1 and 20: \n";
cin >> i;
int c = rand ( ) % 21;
if (i > 20) lose (c);
else if (i < c ) lose (c);
else if (i > c ) win (c);
else draw ();
}
while (1==1);
}
void lose (int c )
{
cout << "You lose! Computer rolled " << c << "\n";
}
void win (int c )
{
cout << "You win!! Computer rolled " << c << "\n";
}
void draw ( )
{
cout << "What are the chances. You tied. Try again, I dare you! \n";
}
g ++を使用してシステムでコンパイルします コマンド:
$ g++ dice.cpp -o dice
次に、それを実行して、機能することを確認します。
$ ./dice
Pick a number between 1 and 20:
[...]
ファイルで作成したバイナリの種類を確認できます コマンド:
$ file ./dice
dice: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically
linked (uses shared libs), for GNU/Linux 5.1.15, not stripped
また、同様に重要なのは、 lddとリンクするライブラリです。 :
$ ldd dice
linux-vdso.so.1 => (0x00007ffe0d1dc000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6
(0x00007fce8410e000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
(0x00007fce83d4f000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6
(0x00007fce83a52000)
/lib64/ld-linux-x86-64.so.2 (0x00007fce84449000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1
(0x00007fce8383c000)
これらのテストから2つのことを確認しました。実行したバイナリは64ビットであり、64ビットライブラリにリンクされています。
つまり、32ビット用にクロスコンパイルするには、 g ++を指定する必要があります。 宛先:
- 32ビットバイナリを生成する
- デフォルトの64ビットライブラリではなく32ビットライブラリへのリンク
32ビットにコンパイルするには、システムに32ビットライブラリとヘッダーがインストールされている必要があります。純粋な64ビットシステムを実行している場合、32ビットライブラリやヘッダーはなく、基本セットをインストールする必要があります。少なくとも、CおよびC ++ライブラリ( glibc )が必要です。 およびlibstdc++ )32ビットバージョンのGCCライブラリ( libgcc )。これらのパッケージの名前は、ディストリビューションごとに異なる場合があります。 Slackwareでは、32ビット互換の純粋な64ビットディストリビューションが multilibから入手できます。 AlienBOBが提供するパッケージ。 Fedora、CentOS、およびRHELの場合:
$ yum install libstdc++-*.i686
$ yum install glibc-*.i686
$ yum install libgcc.i686
使用しているシステムに関係なく、プロジェクトで使用する32ビットライブラリもインストールする必要があります。たとえば、 yaml-cppを含める場合 プロジェクトに、32ビットバージョンの yaml-cppをインストールする必要があります または、多くのシステムでは、 yaml-cppの開発パッケージ (たとえば、 yaml-cpp-devel Fedoraで)コンパイルする前に。
それが処理されたら、コンパイルはかなり簡単です:
$ g++ -m32 dice.cpp -o dice32 -L /usr/lib -march=i686
-m32 フラグは、GCCに32ビットモードでコンパイルするように指示します。 -march =i686 オプションは、使用する最適化の種類をさらに定義します( info gcc を参照) オプションのリストについて)。 -L flagは、GCCがリンクするライブラリへのパスを設定します。これは通常/usr / lib 32ビットの場合。ただし、システムの設定方法によっては、 / usr / lib32になる場合があります。 または/opt / usr / lib または、32ビットライブラリを保持していることがわかっている場所。
コードがコンパイルされたら、ビルドの証明を参照してください:
$ file ./dice32
dice: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
dynamically linked (uses shared libs) [...]
そしてもちろん、 ldd ./dice32 32ビットライブラリを指します。
Linuxターミナル
- Linux用の上位7つのターミナルエミュレータ
- Linuxでのデータ分析のための10個のコマンドラインツール
- 今すぐダウンロード:SSHチートシート
- 高度なLinuxコマンドのチートシート
- Linuxコマンドラインチュートリアル
同じプロセッサファミリの64ビットで32ビットをコンパイルすると、GCCはコードのコンパイル方法について多くの仮定を立てることができます。まったく異なるプロセッサ用にコンパイルする必要がある場合は、適切なクロスビルドGCCユーティリティをインストールする必要があります。インストールするユーティリティは、コンパイルする対象によって異なります。このプロセスは、同じCPUファミリ用にコンパイルするよりも少し複雑です。
同じファミリのクロスコンパイルを行う場合、Linuxディストリビューションが両方を維持しているため、64ビットライブラリと同じ32ビットライブラリのセットを見つけることが期待できます。まったく異なるアーキテクチャ用にコンパイルする場合、コードに必要なライブラリを探す必要があるかもしれません。ディストリビューションがターゲットシステムのパッケージを提供していないか、便利な場所にあるすべてのパッケージをミラーリングしていない可能性があるため、必要なバージョンがディストリビューションのリポジトリにない可能性があります。コンパイルしているコードがあなたのものである場合、おそらくその依存関係が何であるか、そしておそらくそれらをどこで見つけるかについての良い考えを持っているでしょう。コードがダウンロードしてコンパイルする必要があるものである場合は、おそらくその要件に精通していないでしょう。その場合は、コードを正しくビルドするために何が必要かを調べて(通常、それらはREADMEファイルまたはINSTALLファイルにリストされており、確かにソースコード自体にリストされています)、コンポーネントを収集します。
たとえば、ARM用にCコードをコンパイルする必要がある場合は、最初に gcc-arm-linux-gnuをインストールする必要があります。 (32ビット)または gcc-aarch64-linux-gnu (64ビット)FedoraまたはRHEL、または arm-linux-gnueabi-gcc およびbinutils-arm-linux-gnueabi Ubuntuで。これにより、(少なくとも)単純なCプログラムを構築するために必要なコマンドとライブラリが提供されます。さらに、コードで使用するライブラリが必要です。ヘッダーファイルは通常の場所( / usr / include )に配置できます ほとんどのシステムで)、または選択したディレクトリに配置し、 -Iを使用してGCCにポイントさせることができます。 オプション。
コンパイルするときは、標準の gccを使用しないでください またはg++ 指図。代わりに、インストールしたGCCユーティリティを使用してください。例:
$ arm-linux-gnu-g++ dice.cpp \
-I/home/seth/src/crossbuild/arm/cpp \
-o armdice.bin
作成したものを確認します:
$ file armdice.bin
armdice.bin: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV) [...]
これは、クロスコンパイルの使い方の簡単な例です。実際には、ソースコードは単一のバイナリ以上のものを生成する可能性があります。これは手動で管理できますが、それを行う理由はおそらくありません。次の記事では、コードを移植可能にするために必要なほとんどの作業を行うGNUAutotoolsについて説明します。