,

How to build a executable file can run on 32bit and 64bit machine?

做一個跨平台的軟體,一定會遇到如何讓程式可以在32與64位元上執行。也許你會說:我的32位元執行檔可以在RHEL5 32和64上執行阿! 但在RHEL6 64bit上,預設沒安裝32位元的Libraries喔! 為了解決這個問題,你可以請使用者自己裝,也可以依據不同平台給不同的執行檔,這看各人取捨。如果想要讓執行檔可以同時在32與64上執行,可以參考下面說明。

假設我們有隻程式叫test.c,輸出執行檔為test。要compile成32與64的版本會使用以下command:

# 64-bit version
gcc -O2 -m64 -fPIC -Iinclude -o ./Release/test64 test.c
# 32-bit version
gcc -O2 -m32 -fPIC -Iinclude -o ./Release/test32 test.c

首先使用file指令去確認這兩個執行檔:

file test64
#        test64: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), 
#        dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped
file test32
#        test32: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), 
#        dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped

接著用ldd指令去確認它們使用的dll:

ldd test32
#        linux-gate.so.1 =>  (0xffffe000)
#        libc.so.6 => /lib/libc.so.6 (0x00432000)
#        /lib/ld-linux.so.2 (0x00413000)
ldd test64
#        linux-vdso.so.1 =>  (0x00007fff48ffc000)
#        libc.so.6 => /lib64/libc.so.6 (0x0000003c57800000)
#        /lib64/ld-linux-x86-64.so.2 (0x0000003c57400000)


在RHEL6上預設沒有32bit的dll,test32當然無法執行。我們可以透過以下command去編譯,用static方式將參考的libraies包進執行檔中:

gcc -O2 -m32 -static -s -fPIC -Iinclude -o test test.c

將32bit的dll以static的方式包到執行檔之中,這時後再執行一次file與ldd:

ldd test
#       not a dynamic executable
file test
#       test: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), 
#       for GNU/Linux 2.6.4, statically linked, for GNU/Linux 2.6.4, stripped

我們可以發現test變成非dynamic executable,且使用statically linked。這個方法的缺點就試檔案會變比較大,要用什麼方法就自行取捨了!