1. 程式人生 > >GCC 64位程式的makefile條件編譯心得——32位版與64位版、debug版與release版(相容MinGW、TDM-GCC)

GCC 64位程式的makefile條件編譯心得——32位版與64位版、debug版與release版(相容MinGW、TDM-GCC)

  為了適應現在越來越流行的64位系統,經常需要將程式碼分別編譯為32位版和64位版。其次,除了需要生成debug版用於開發測試外,還需要生成release版用於釋出。本文介紹瞭如何利用makefile條件編譯來生成這些版本,而且不僅相容Linux下的GCC,還支援MinGW、TDM-GCC等Windows下的GCC編譯器。


一、C程式程式碼

  為了測試條件編譯的效果,以下面這個C語言程式為例(gcc64_make.c)——

複製程式碼
#include <stdio.h>
#include <assert.h>

// 獲取程式位數(被編譯為多少位的程式碼)
int GetProgramBits()
{
    
return sizeof(int*) * 8; } int main(int argc, char* argv[]) { printf("bits:\t%d\n", GetProgramBits()); assert( argc>1 ); return 0; }
複製程式碼

  main函式中,前兩條語句的含義為——
第一條語句用於顯示當前程式的位數。如果編譯為32位版,將會顯示“bits: 32”;如果編譯為64位版,將會顯示“bits: 64”。
第二條語句是一條斷言,需要argc變數大於1。如果編譯為debug版,若執行時未加命令引數,該斷言失敗,於是輸出錯誤資訊並終止程式;如果編譯為release版,所有斷言被遮蔽,不會有錯誤資訊。


二、GCC命令列引數

  複習一下GCC命令列引數,看看各個版本的區別——
32位版:加上 -m32 引數,生成32位的程式碼。
64位版:加上 -m64 引數,生成64位的程式碼。
debug版:加上 -g 引數,生成除錯資訊。
release版:加上 -static 引數,進行靜態連結,使程式不再依賴動態庫。加上 -O3 引數,進行最快速度優化。加上-DNDEBUG引數,定義NDEBUG巨集,遮蔽斷言。

  當沒有-m32或-m64引數時,一般情況下會生成跟作業系統位數一致的程式碼,但某些編譯器存在例外,例如——
32位Linux下的GCC,預設是編譯為32位程式碼。
64位Linux下的GCC,預設是編譯為64位程式碼。
Window系統下的MinGW,總是編譯為32位程式碼。因為MinGW只支援32位程式碼。
Window系統下的MinGW-w64(例如安裝了TDM-GCC,選擇MinGW-w64),預設是編譯為64位程式碼,包括在32位的Windows系統下。


三、makefile程式碼

  makefile的程式碼為——

複製程式碼
# flags
CC = gcc
CFLAGS = -Wall
LFLAGS = 

# args
RELEASE =0
BITS =

# [args] 生成模式. 0代表debug模式, 1代表release模式. make RELEASE=1.
ifeq ($(RELEASE),0)
    # debug
    CFLAGS += -g
else
    # release
    CFLAGS += -static -O3 -DNDEBUG
    LFLAGS += -static
endif

# [args] 程式位數. 32代表32位程式, 64代表64位程式, 其他預設. make BITS=32.
ifeq ($(BITS),32)
    CFLAGS += -m32
    LFLAGS += -m32
else
    ifeq ($(BITS),64)
        CFLAGS += -m64
        LFLAGS += -m64
    else
    endif
endif


.PHONY : all clean

# files
TARGETS = gcc64_make
OBJS = gcc64_make.o

all : $(TARGETS)

gcc64_make : $(OBJS)
    $(CC) $(LFLAGS) -o [email protected] $^


gcc64_make.o : gcc64_make.c
    $(CC) $(CFLAGS) -c $<


clean :
    rm -f $(OBJS) $(TARGETS) $(addsuffix .exe,$(TARGETS))
複製程式碼

  為了控制條件編譯,定義了RELEASE、BITS這兩個變數,分別賦初值。然後用ifeq判斷RELEASE、BITS變數的值,分別加上不同的引數。
  因賦有初值,直接執行“make”時,編譯得到的是預設位數的debug版。
  若在執行make時給變數賦值,將會得到不同的版本——
make RELEASE=0:(預設位數的)debug版。
make RELEASE=1:(預設位數的)release版。
make BITS=32:32位(的debug)版。
make BITS=64:64位(的debug)版。
make RELEASE=0 BITS=32:32位的debug版。
make RELEASE=0 BITS=64:64位的debug版。
make RELEASE=1 BITS=32:32位的release版。
make RELEASE=1 BITS=64:64位的release版。


  該makefile的程式碼風格是精心設計的,可以很方便的擴充套件——
需要增加程式碼檔案或依賴關係時,修改“# files”之後的內容。
需要調整編譯引數時,修改前半部分的引數變數。
需要增加新的條件編譯引數時,在“# args”定義一個變數並賦初值,然後再在後面用“ifeq”判斷變數來調整編譯引數。

  最後的“rm -f $(OBJS) $(TARGETS) $(addsuffix .exe,$(TARGETS))”是為了相容MinGW、TDM-GCC等Windows下的GCC編譯器而設計的——
裝好MSYS,再配置一下PATH環境變數,Windows中也可以使用rm命令刪除檔案。
因Windows下的可執行檔案的副檔名是exe,所以使用了addsuffix函式增加“.exe”副檔名。
因Linux下不會生成.exe可執行檔案,而Windows下不會生成無副檔名的可執行檔案,導致rm會因找不到檔案而報錯。這時可以加上-f引數忽略該錯誤。


四、測試結果

4.1 Fedora 17 64位版下的 GCC 4.7.0

  開啟終端,使用cd命令進入程式所在目錄,並執行以下命令——

複製程式碼
make clean
make
./gcc64_make
make clean
make RELEASE=1
./gcc64_make
make clean
make BITS=32
./gcc64_make
make clean
make RELEASE=1 BITS=32
./gcc64_make
gcc --version
複製程式碼

  執行結果——


4.2 Windows XP SP3 32位版下的 GCC 4.6.2(MinGW (20120426))

  開啟命令提示符,使用cd命令進入程式所在目錄,並執行以下命令——

複製程式碼
make clean
make
gcc64_make
make clean
make RELEASE=1
gcc64_make
make clean
make BITS=64
gcc --version
複製程式碼

  執行結果——


4.3 Windows 7 SP1 64位版下的 GCC 4.6.1(TDM-GCC (MinGW-w64))

  開啟命令提示符,使用cd命令進入程式所在目錄,並執行以下命令——

複製程式碼
make clean
make
gcc64_make
make clean
make RELEASE=1
gcc64_make
make clean
make BITS=32
gcc64_make
make clean
make RELEASE=1 BITS=32
gcc64_make
gcc --version
複製程式碼

  執行結果——

相關推薦

GCC 64程式makefile條件編譯心得——3264debugrelease相容MinGWTDM-GCC

  為了適應現在越來越流行的64位系統,經常需要將程式碼分別編譯為32位版和64位版。其次,除了需要生成debug版用於開發測試外,還需要生成release版用於釋出。本文介紹瞭如何利用makefile條件編譯來生成這些版本,而且不僅相容Linux下的GCC,還支援MinGW、TDM-GCC等Windows

64機器上VS2012編譯32程式在XP系統上執行提示Wow64EnableWow64FsRedirection無法定位於輸入點

Wow64EnableWow64FsRedirection()函式是64位計算機用於定義轉向的函式,在32位計算機中不存在轉向問題 因此,在32位計算機中的kernel32.dll庫中就不存在此函式,當程式執行在32位計算機中時,就會提示無法定位 解決方法: 採用函式指標的

Makefile條件編譯debugrelease

原文地址為: Makefile條件編譯debug版和release版 一般,在開發測試階段用debug版本,而上線釋出用release版本。 使用Makefile定製編譯不同版本,避免修改程式和Makefile檔案,將會十分方便。 讀了一些資料,找到一個解決方法,Makefile

MinGW MinGW-w64 TDM-GCC等工具鏈之間的區別聯絡

不當之處,盡請指正。 先科普一下GNU相關: GNU計劃(英語:GNU Project),又譯為革奴計劃,是一個自由軟體集體協作專案,1983年9月27日由理查德·斯托曼在麻省理工學院公開發起。它的目標是建立一套完全自由的作業系統,稱為GNU。理查德·斯托曼最早在

程序間通訊機制管道訊號共享記憶體/訊號量/訊息佇列執行緒間通訊機制互斥鎖條件變數posix匿名訊號量

(1)系統中每個訊號量的資料結構(sem)struct sem {     int semval; /* 訊號量的當前值 */     unsigned short  semzcnt;  /* # waiting for zero */     unsigned short  semncnt;  /* # w

MinGW MinGW-w64 TDM-GCC等工具鏈之間的區別聯絡

不當之處,盡請指正。 相同點: 一、 他們都是用於編譯生成Windows應用程式的工具鏈。 二、 他們都是基於gcc的。 不同之處(只說大的): 一、專案之間的關係 1. MinGW應該是最先誕生

**用Java語言編寫程式,要求: 先輸入10個數字,再按照冒泡法進行排序並輸出通過寫方法來完成**

程式如下: package com.sort; import java.util.Scanner; public class Bubble { public static void main(String[] args) {

ubuntu 64上的GCC如何編譯32程式

執行命令 gcc -v 顯示: Target: x86_64-linux-gnu 所以,我這裡的gcc預設生成64位的程式。 如果想編出32位的程式,就要加 -m32選項。可是我嘗試了,還是不行。 原來,需要安裝東西。 $ sudo apt-get install b

Makefile中用巨集定義進行條件編譯(gcc -D)/在Makefile中進行巨集定義-D

在原始碼裡面如果這樣是定義的: #ifdef   MACRONAME //可選程式碼 #endif 那在makefile裡面 gcc   -D   MACRONAME=MACRODEF 或者 gcc   -D   MACRONAME  這樣就定義了預處理巨集,編譯的時候可選程式碼就會被編譯進去了。 對於G

64ubuntu編譯32程式

如上使用C4這個小工具時遇到來需要模擬32位系統的需求,發現使用-m32引數後,編譯提示錯誤,如下: /usr/bin/ld: 未知的模擬模式: 32 支援的模擬: elf_x86_64 elf32_x86_64 elf_i386 i386linux elf_l1om e

linux64平臺上編譯32程式: GCC編譯選項 -m64 -m32 -mx32

x86-64 與 IA-64 x86-64一般稱為AMD x86-64,難道x86-64不是Intel首先搞出來的指令集麼?這回的確是AMD乾的,但是用的是Intel 16bits升到32bits向下相容的套路。大致是這樣的: x86:從1978年來的8086處理器開

VC2010 中使用條件編譯判斷是32還是64編譯模式

在VC2010中通過platform選擇32位還是64位編譯時,可以通過下面的條件編譯指令來判斷: // 32位編譯 #ifdef _M_IX86 #pragma comment(lib,"QDPay_mt.lib") #endif // _M_IX86 // 64位編譯

在VS2008中編譯64程式以及遇到的問題

安裝64位作業系統不是編譯64位程式的必要條件,關鍵是要裝64位程式的編譯器。雖然標題寫著如何在VS2008中編譯,但其實2005也是類似。 1. 選擇“Build” – “Configuration Manager”選單,開啟配置管理器。點選新建解決方案平臺。 2. 選擇

使用VC6將32程式編譯成為64程式這個才是可行的

看了好多好多資料,自己也太過依賴現有的資料,按部就班不是真理不是真理!!! 建立64位環境             網上資料很多都以SDK2001少數以2003為例,有的說SDK2003是最後支援VC6的,汗,也不知道內在什麼原因,就按部就班的去下了2001/2003,嘗試到後面步驟的時候,雖然編譯通過了

zlib包在64機被編譯32目標代碼的問題

x86_64 -c efi yun mod 文件 配置 chmod pre 一、進入zlib目錄 [[email protected]/* */ \]$ cd /home/yun/zlib-1.2.8 [[email prot

centos64編譯32程式問題

在centos64位上面編譯32位程式的時候遇到編譯不過的問題,解決過程如下: 1.編譯遇到錯誤,提示錯誤如下: [[email protected] code]# make In file included from /usr/include/features.h:399:0

64Arm Lubuntu上編譯Qt MySQLl驅動

                             64位Arm處理器 Lubuntu上編譯Qt MySQL驅動 1.安裝MySQ

Linux下實現進度條程式. 通過makefile進行編譯. 建議自主完成一個彩色的進度條.

Linux下用C語言完成一個彩色進度條 1.建一個Makefile檔案 2.vim Makefile test:test.c

使 64ubuntu 支援32程式

第一步: 確認你有一個64位架構的核心 你可以開啟終端然後輸入: dpkg --print-architecture 你將會看到像下面這樣的內容: amd64 這說明著你已經擁有了64位架構核心。 第二步: 確認你打開了多架構支援功能 (多架構支援可以讓你在有64位庫的情況下使用32位庫。) 輸入:

Makefile同時編譯不同程式

將每個原始檔都編譯為一個可執行檔案 CC := gcc CFLAGS += LDFLAGS += SOURCES := $(wildcard *.c) TARGE