Linux下autoconf與automake

oscar999發表於2020-04-06

機器語言,組合語言與高階語言

機器語言是機器指令的集合。機器指令展開來講就是一臺機器可以正確執行的命令。電子計算機的機器指令是一列二進位制數字。計算機將之轉變為一列高低電平,以使計算機的電子器件受到驅動,進行運算。
早期的程式設計均使用機器語言。程式設計師們將用0, 1數字編成的程式程式碼打在紙帶或卡片上,1打孔,0不打孔,再將程式通過紙帶機或卡片機輸入計算機,進行運算。這樣的機器語言由純粹的0和1構成,十分複雜,不方便閱讀和修改,也容易產生錯誤。

編語言的主體是彙編指令。彙編指令和機器指令的差別在於指令的表示方法上。彙編指令是機器指令便於記憶的書寫格式。

1000100111011000 機器指令
mov ax,bx 彙編指令

將彙編指令轉換成機器指令的翻譯程式,這樣的程式我們稱其為編譯器。程式設計師用匯編語言寫出源程式,再用匯編編譯器將其編譯為機器碼,由計算機最終執行。
由於組合語言依賴於硬體體系,且助記符量大難記,於是人們又發明了更加易用的所謂高階語言。在這種語言下,其語法和結構更類似普通英文,且由於遠離對硬體的直接操作,使得一般人經過學習之後都可以程式設計。

高階語言: 程式導向-C, 物件導向C++,Java.

所以, 高階語言要執行,最終是要經過編譯轉化為組合語言才能被機器執行。

C語言的編譯和連結

編譯是把原始碼編譯成中間程式碼檔案,
在Windows下是.obj檔案, 在Linix下是.o 的檔案,即Object File, 目標檔案

連結處理的是目標檔案之間的呼叫關係。方式就是把目標檔案打個包, 在Windows 下這個包檔案愛你叫Library-庫檔案, 以.lib結尾。
在Linux下叫Archive檔案, 以 .a結尾。

原始檔首先會生成中間目標檔案,再由中間目標檔案生成執行檔案。在編譯時,編譯器只檢測程式語法,和函式、變數是否被宣告。如果函式未被宣告,編譯器會給出一個警告,但可以生成Object File。而在連結程式時,連結器會在所有的Object File中找尋函式的實現。

沒有Makefile的編譯
gcc -o myapp main.c func1.c func2.c func3.c

以上編碼包括程式碼:
主程式程式碼 main.c
三個子函式 : funcx.c

寫在Makefile 檔案中:
myapp: main.c func1.c func2.c func3.c
gcc -o calc main.c func1.c func2.c func3.c
這是一個基本的Makefile語句,它主要分成了三個部分,
第一部分:第一行冒號之前的myapp,我們稱之為目標(target),被認為是這條語句所要處理的物件,具體到這裡就是我們所要編譯的這個程式myapp。
第二部分:冒號後面的部分(main.c func1.c func2.c func3.c),我們稱之為依賴關係表,也就是編譯所需要的檔案
第三部分: 命令部分,就是一條編譯命令

什麼是Makefile?

Makefile是一個檔案。

makefile定義整個工程的編譯規則。一個工程中的原始檔不計數,其按型別、功能、模組分別放在若干個目錄中,makefile定義了一系列的規則來指定,哪些檔案需要先編譯,哪些檔案需要後編譯,哪些檔案需要重新編譯,甚至於進行更復雜的功能操作,因為makefile就像一個Shell指令碼一樣,其中也可以執行作業系統的命令。makefile帶來的好處就是——“自動化編譯”,一旦寫好,只需要一個make命令,整個工程完全自動編譯,極大的提高了軟體開發的效率。

Makefile檔案被 make命令使用。make是如何工作的呢?
在預設的方式下,
1. make會在當前目錄下找名字叫“Makefile”或“makefile”的檔案。
2. 如果找到,它會找檔案中的第一個目標檔案(target),在上面的例子中,他會找到“edit”這個檔案,並把這個檔案作為最終的目標檔案。
3. 如果edit檔案不存在,或是edit所依賴的後面的 .o 檔案的檔案修改時間要比edit這個檔案新,那麼,他就會執行後面所定義的命令來生成edit這個檔案。
4. 如果edit所依賴的.o檔案也存在,那麼make會在當前檔案中找目標為.o檔案的依賴性,如果找到則再根據那一個規則生成.o檔案。(這有點像一個堆疊的過程)
5. make會生成 .o 檔案,然後再用 .o 檔案宣告make的終極任務,也就是執行檔案edit了。
這就是整個make的依賴性,make會一層又一層地去找檔案的依賴關係,直到最終編譯出第一個目標檔案。在找尋的過程中,如果出現錯誤,比如最後被依賴的檔案找不到,那麼make就會直接退出,並報錯,而對於所定義的命令的錯誤,或是編譯不成功,make根本不理。make只管檔案的依賴性,即,如果在我找了依賴關係之後,冒號後面的檔案還是不在,那麼對不起,我就不工作啦

autoconf&automake

Makefile中紀錄有檔案的資訊,在make時會決定在連結的時候需要重新編譯哪些檔案。
Makefile的宗旨就是:讓編譯器知道要編譯一個檔案需要依賴其他的哪些檔案。當那些依賴檔案有了改變,編譯器會自動的發現最終的生成檔案已經過時,而重新編譯相應的模組。
當系統環境變數或路徑發生了變化後,Makefile可能還要跟著修改。這樣就造成了手工書寫Makefile的諸多問題,automake恰好能很好地幫助我們解決這些問題。

使用automake,程式開發人員只需要寫一些簡單的含有預定義巨集的檔案,由autoconf根據一個巨集檔案生成configure,由automake根據另一個巨集檔案生成Makefile.in,再使用configure依據Makefile.in來生成一個符合慣例的Makefile
autoconf用來生成configure configure生成makefile make就去調gcc編譯原始檔

使用autoconf和automake兩個工具來幫助我們自動地生成符合自由軟體慣例的Makefile.

例項

  1. 在工作目錄下新建testmake目錄
mkdir testmake
cd testmake
  1. 編寫原始碼 helloworld.c
    vi helloworld.c
int main(int argc,char** argv)
{
    printf("Hello,My First Linux Make");
    return 0;
}
  1. 生成configure.
    使用autoscan命令,生成configure.scan的檔案
    autoscan
    重新命名為configure.in, 並修改檔案內容
    mv configure.scan configure.in
                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_INIT(helloworld.c)

AM_INIT_AUTOMAKE(helloworld,1.0)

# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_OUTPUT(Makefile)
  1. 執行 aclocal 和autoconf, 產生aclocal.m4及configure
    aclocal根據configure.in檔案的內容,自動生成aclocal.m4檔案。aclocal是一個perl指令碼程式,它的定義是:“aclocal - create aclocal.m4 by scanning configure.ac”。
     autoconf 是用來生成自動配置軟體原始碼指令碼(configure)的工具。configure指令碼能獨立於autoconf執行,且在執行的過程中,不需要使用者的干預。
     autoconf需要GNU m4巨集處理器來處理aclocal.m4,生成configure指令碼。
      m4是一個巨集處理器。將輸入拷貝到輸出,同時將巨集展開。巨集可以是內嵌的,也可以是使用者定義的。除了可以展開巨集,m4還有一些內建的函式,用來引用檔案,執行命令,整數運算,文字操作,迴圈等。m4既可以作為編譯器的前端,也可以單獨作為一個巨集處理器.

5.建立Makefile.am
新建Makefile.am檔案,命令:$ vi Makefile.am
automake會根據你寫的Makefile.am來自動生成Makefile.in。Makefile.am中定義的巨集和目標,會指導automake生成指定的程式碼。例如,巨集bin_PROGRAMS將導致編譯和連線的目標被生成。

AUTOMAKE_OPTIONS=foreign

bin_PROGRAMS=helloworld

helloworld_SOURCES=helloworld.c

6.執行automake –add-missing

automake會根據Makefile.am檔案產生一些檔案,包含最重要的Makefile.in。

  1. 執行configure生成Makefile
./configure

8.使用Makefile編譯程式碼

make 

9.執行

./helloworld

相關文章