64ビットLinuxシステムで32ビットバイナリをコンパイルする方法
1. 序章
最近では、64ビットシステムで32ビットプログラムを実行するのが便利で実用的です。 つまり、これを行う必要がある状況がいくつかあります。 たとえば、64ビットバージョンのアプリケーションが利用できないか、まだ移植されていない可能性があります。 同様に、Windowsアプリケーションを使用するか、Wine互換性レイヤーを使用して古いゲームをプレイする必要がある場合があります。 つまり、一部のアプリケーションでは32ビットOSのサポートが必要です。
この記事では、 gcc コンパイラを使用して、64ビットLinuxシステムで32ビットプログラムをコンパイルする方法について説明します。 また、64ビットシステムで32ビットバイナリをビルドするためのシステム要件と、CMakeを使用してこれらのビルドを自動化する方法についても学習します。
2. 開発ツール
開始する前に、コンパイルバイナリビルドプロセスで使用されるすべての開発ツールがシステムにインストールされていることを確認します。 まず、GCC 、GNUコンパイラコレクションが必要です。 第二に、 binutils は、リンカーやアセンブラーなどのバイナリプログラムを作成および管理するためのツールのセットです。 さらに、 Make – ビルド自動化ツール–とC標準ライブラリg libcをインストールする必要があります。
最も重要なことは、 Multilibをインストールする必要があります。これにより、32ビットプログラムを64ビットシステムで実行できます。また、32ビットライブラリと64ビットライブラリを同じシステムで共存できるようになります。 32ビットプログラムには32ビットライブラリが必要なため、これが必要になります。
Ubuntuを含むDebianのようなディストリビューションでは、 gcc コンパイラ、Cライブラリ、および Makeツールがビルドエッセンシャルパッケージに含まれています。 aptを使用してbuild-essentialおよびbinutilsパッケージをインストールする必要があります。
$ sudo apt -y update
$ sudo apt -y install build-essential binutils
同様に、 gcc-multilib パッケージをインストールして、Multilibメカニズムをシステムに追加します。
$ sudo apt -y install gcc-multilib
Fedora、Redhat、またはCentOSを実行している場合は、 dnf を使用して、 gcc コンパイラ、M ake、、および
$ sudo dnf -y install gcc binutils make
同様に、Redhatのようなディストリビューションに32ビットのサポートを追加するには、次のコマンドを実行します。
$ sudo dnf -y install glibc-devel.i686
3. コンパイラは32ビットですか64ビットですか?
それでは、unameコマンドを使用してハードウェア情報を確認しましょう。
$ uname -m
x86_64
デフォルトでは、コンパイラはアーキテクチャに適したバイナリファイルを生成します。したがって、64ビットプロセッサを使用している場合は、64ビットバイナリを生成します。
それでは、gccのインストールを確認しましょう。
$ gcc -v
Using built-in specs.
COLLECT_GCC=/usr/bin/gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/10/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,objc,obj-c++,ada,go,d,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl --enable-offload-targets=nvptx-none --without-cuda-driver --enable-gnu-indirect-function --enable-cet --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.3.1 20210422 (Red Hat 10.3.1-1) (GCC)
ご覧のとおり、ターゲットはx86_64 です。これは、64ビットプロセッサ(AMDまたはIntel)用のLinuxシステムのアーキテクチャ名です。
4. 64ビットシステムでの32ビットプログラムのコンパイル
前に見たように、コンパイラはターゲットアーキテクチャのバイナリを生成します。この場合はx86_64です。
$ gcc prog.c -o prog
コンパイルプロセスによって生成されたファイルのタイプを確認するには、ファイルツールを使用します。
$ file prog
prog: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=07a13c851f21019b160a777a8ac047bed3a06489, for GNU/Linux 3.2.0, not stripped
システムを32ビット構成と互換性のあるものにせずに32ビットプログラムをコンパイルしようとすると、次のエラーが発生します。
$ $ gcc -m32 prog.c -o prog
In file included from /usr/include/features.h:489,
from /usr/include/bits/libc-header-start.h:33,
from /usr/include/stdio.h:27,
from menu.c:1:
/usr/include/gnu/stubs.h:7:11: fatal error: gnu/stubs-32.h: No such file or directory
7 | # include <gnu/stubs-32.h>
| ^~~~~~~~~~~~~~~~
compilation terminated.
それでは、-m32オプションを使用して32ビットプログラムをコンパイルしましょう:
$ gcc -m32 prog.c -o prog
ここでは、互換性のあるシステムで32ビットプログラムを正常にコンパイルしました。 file コマンドを使用して、バイナリを確認できます。
$ file prog
a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=a711fe476bf35d8e36ff6d5370ac384e3a84539d, for GNU/Linux 3.2.0, not stripped
5. CMakeの使用
それでは、CMakeを使用してコンパイルを自動化しましょう
DebianおよびUbuntuディストリビューションにCMakeをインストールする方法を見てみましょう。
$ sudo apt -y install cmake
FedoraやRedhatのようなシステムにCMakeをインストールするには、次のコマンドを実行します。
$ sudo dnf install cmake
CMakeを使用して32ビットプロジェクトをビルドするには、 main.c、prog.c 、prog.hの3つのファイルで構成されるサンプルプロジェクトを使用します。
$ ls project/
main.c prog.c prog.h
まず、 gccオプションを渡すためのCmakeLists.txtファイルを作成する必要があります:
cmake_minimum_required(VERSION 3.19)
set(GCC_COVERAGE_COMPILE_FLAGS "-m32")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}")
project(prog)
add_executable(prog main.c prog.c)
また、プロジェクトをビルドするには、buildディレクトリを作成する必要があります。
$ cd project && mkdir build && cd build
その後、buildディレクトリからcmakeを実行して、プロジェクトのMakefileを生成します。
$ cmake ..
-- The C compiler identification is GNU 10.3.1
-- The CXX compiler identification is GNU 10.3.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/baeldung/CMake/project/build
最後に、makeツールを使用して Makefileを実行し、実行可能プログラムを生成します。
$ make
scanning dependencies of target prog
[ 33%] Building C object CMakeFiles/hello.dir/main.c.o
[ 66%] Building C object CMakeFiles/hello.dir/prog.c.o
[100%] Linking C executable prog
[100%] Built target prog
その後、fileコマンドを使用してバイナリを確認しましょう。
$ file prog
prog: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=21edad69c38b540f9d3dd508a78509bc2d8c61d8, for GNU/Linux 3.2.0, not stripped
その結果、32ビットのCライブラリにリンクされた32ビットの実行可能プログラムができました。
6. 結論
古いアプリケーションを64ビットシステムに移植するのにかなりの時間と労力を費やすことなく、必要に応じて64ビットシステムで32ビットプログラムを実行できると、私たちにとって有利です。
つまり、開発ツールをインストールして、システムを32ビットプログラムと互換性のあるものにする方法を見てきました。 最後に、CMakeを使用してコンパイルを自動化する方法について説明しました。