1. 程式人生 > >Linux下Makefile的自動生成步驟

Linux下Makefile的自動生成步驟

一、 Makefile 介紹
              Makefile 是用於自動編譯和連結的 ,一個工程有很多檔案組成 ,每一個檔案的改變都會導致工程的重新連結 ,但是不是

        所有的檔案都需要重新編譯 ,Makefile 中紀錄有檔案的資訊 ,在 make 時會決定在連結的時候需要重新編譯哪些檔案。

              Makefile 的宗旨就是 :讓編譯器知道要編譯一個檔案需要依賴其他的哪些檔案。當那些依賴檔案有了改變 ,編譯器會自動

       的發現最終的生成檔案已經過時 ,而重新編譯相應的模組 。

             使用 automake ,程式開發人員只需要寫一些簡單的含有預定義巨集的檔案,由 autocon f根據一個巨集檔案生成 configure ,

      由 automake 根據另一個巨集檔案生成 Makefile.in ,再使用configure 依據 Makefile.in 來生成一個符合慣例的 Makefile 。下面

      我們將詳細介紹 Makefile的 automake 生成方法。

二、下面以 helloworld 為例

      1、在自己的工作目錄下建一 個 helloworld 目錄,新建三個檔案:
           helloworld.c

int main(int argc, char* argv[])
{
  printf("Hello World! ");
  return 0;
}

      2 、生成 configure

            我們使用 autoscan 命令來幫助我們根據目錄下的原始碼生成一個 configure.in 的模板檔案。

            命令:

                  $ autoscan

            執行後在 hellowrold 目錄下會生成一個檔案: configure.scan ,我們可以拿它作 為configure.in 的藍本。

            現在將 configure.scan 改名為 configure.in ,並且編輯它,按下面的內容修改,去掉無關的語句:

======================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)
======================configure.in 內 容 結 束=================================

            然後執行命令 aclocal 和 autoconf ,分別會產生 aclocal.m4 及 configure 兩個檔案:

            $ aclocal

            $ autoconf

            $ ls

            aclocal.m4 autom4te.cache configure configure.in helloworld.c

            可以看到 configure.in 內容是一些巨集定義,這些巨集經 autoconf 處理後會變成檢查系統特性、環境變數、軟體必須的引數的 shell 指令碼。

            autoconf 是用來生成自動配置軟體原始碼指令碼 ( configure ) 的工具。 configure 指令碼能獨立於 autoconf 執行,且在執行的過程中,不需要使用者的干預。

            要生成 configure 檔案,你必須告訴 autoconf 如何找到你所用的巨集。方式是使用 aclocal程式來生成你的 aclocal.m4 。

            aclocal 根據 configure.in 檔案的內容 , 自動生成 aclocal.m4 檔案。 aclocal 是一個 perl 指令碼程式,它的定義是 :“ aclocal - create aclocal.m4 by

            scanningconfigure.ac ” 。

            autoconf 從 configure.in 這個列舉編譯軟體時所需要各種引數的模板檔案中創 建configure 。

            autoconf 需要 GNU m4 巨集處理器來處理 aclocal.m4 ,生成 configure 指令碼。

            m4 是一個巨集處理器。將輸入拷貝到輸出,同時將巨集展開。巨集可以是內嵌的,也可以是使用者定義的。除了可以展開巨集, m4 還有一些內建的函式,用來引用檔案,

           執行命令,整數運算,文字操作,迴圈等。 m4 既可以作為編譯器的前端,也可以單獨作為一個巨集處理器。

      3、新建 Makefile.am

AUTOMAKE_OPTIONS=foreign
bin_PROGRAMS=helloworld
helloworld_SOURCES=helloworld.c

           automake 會根據你寫的 Makefile.am 來自動生成 Makefile.in 。

           Makefile.am 中定義的巨集和目標 , 會指導 automake 生成指定的程式碼。例如,巨集bin_PROGRAMS 將導致編譯和連線的目標被生成。

      4 、執行 automake

           $ automake --add-missing

             configure.in: installing `./install-sh'

             configure.in: installing `./mkinstalldirs'

             configure.in: installing `./missing'

             Makefile.am: installing `./depcomp'

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

      5 、執行 configure 生成 Makefile

           $ ./configure

checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
checking for C compiler default output... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ANSI C... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
configure: creating ./config.status
config.status: creating Makefile
config.status: executing depfiles commands
          

           $ ls -l Makefile        

            -rw-rw-r-- 1 yutao yutao 15035 Oct 15 10:40 Makefile

           $ make

            if gcc -DPACKAGE_NAME="" -DPACKAGE_TARNAME="" -DPACKAGE_VERSION="" -DPACKAGE_STRING="" -DPACKAGE_BUGREPORT="" -DPACKAGE=

            "helloworld"-DVERSION="1.0"-I. -I. -g -O2 -MT helloworld.o -MD -MP -MF ".deps/helloworld.Tpo"-c -o helloworld.o `test -f 'helloworld.c' || echo './'`helloworld.c;

            then mv -f ".deps/helloworld.Tpo" ".deps/helloworld.Po";else rm -f ".deps/helloworld.Tpo"; exit 1;

            fi

           gcc -g -O2 -o helloworld helloworld.o

           執行 helloworld

           $ ./helloworld

           Hello World!

三、針對上面提到的各個命令,我們再做些詳細的介紹。
      1 、 autoscan
            autoscan 是用來掃描原始碼目錄生成 configure.scan 檔案的。autoscan 可以用目錄名做為引數,但如果你不使用引數的話,那麼 autoscan 將認為使用的是當前目錄。     

            autoscan 將掃描你所指定目錄中的原始檔,並建立 configure.scan 檔案。

      2 、 configure.scan

            configure.scan 包含了系統配置的基本選項,裡面都是一些巨集定義。我們需要將它改名為 configure.in

      3 、 aclocal

             aclocal 是一個perl 指令碼程式。aclocal 根據configure.in 檔案的內容,自動生成aclocal.m 4檔案。aclocal 的定義是:“aclocal - create aclocal.m4 by scanning configure.ac ” 。

      4 、 autoconf

             autoconf 是用來產生 configure 檔案的。configure 是一個指令碼,它能設定源程式來適應各種不同的作業系統平臺,並且根據不同的系統來產生合適的Makefile ,從而可以使

             你的原始碼能在不同的作業系統平臺上被編譯出來。configure.in 檔案的內容是一些巨集,這些巨集經過 autoconf 處理後會變成檢查系統特性、環境變數、軟體必須的引數的 shell

             指令碼。 configure.in 檔案中的巨集的順序並沒有規定,但是必須在所有巨集的最前面和最後面分別加上 AC_INIT 巨集和 AC_OUTPUT 巨集。

             在 configure.ini 中:

               # 號表示註釋,這個巨集後面的內容將被忽略。

               AC_INIT(FILE)

                  這個巨集用來檢查原始碼所在的路徑。

               AM_INIT_AUTOMAKE(PACKAGE, VERSION)

                這個巨集是必須的,它描述了我們將要生成的軟體包的名字及其版本號: PACKAGE 是軟體包的名字, VERSION 是版本號。當你使用 make dist 命令時,它會給你生成

             一個類 似helloworld-1.0.tar.gz 的軟體發行包,其中就有對應的軟體包的名字和版本號。

            AC_PROG_CC      這個巨集將檢查系統所用的 C 編譯器。

            AC_OUTPUT(FILE)         這個巨集是我們要輸出的 Makefile 的名字。

               我們在使用 automake 時,實際上還需要用到其他的一些巨集,但我們可以用 aclocal 來幫我們自動產生。執行aclocal 後我們會得到 aclocal.m4 檔案。

            產生了configure.in 和  aclocal.m4 兩個巨集檔案後,我們就可以使用 autoconf 來產生configure 檔案了。

      5 、Makefile.am

            Makefile.am 是用來生成 Makefile.in 的 , 需要你手工書寫 。 Makefile.am 中定義了一些內容:

            AUTOMAKE_OPTIONS

              這個是 automake 的選項。在執行 automake 時,它會檢查目錄下是否存在標準 GNU 軟體包中應具備的各種檔案,例如 AUTHORS 、 ChangeLog 、 NEWS 等檔案。

           我們將其設定 成foreign 時, automake 會改用一般軟體包的標準來檢查。

           bin_PROGRAMS

              這個是指定我們所要產生的可執行檔案的檔名 。 如果你要產生多個可執行檔案 , 那麼在各個名字間用空格隔開。

            helloworld_SOURCES

              這個是指定產生 “ helloworld ” 時所需要的原始碼。如果它用到了多個原始檔,那麼請使用空格符號將它們隔開。比如需要 helloworld.h ,helloworld.c 那麼請寫成

            helloworld_SOURCES= helloworld.h helloworld.c 。

            如果你在 bin_PROGRAMS 定義了多個可執行檔案 , 則對應每個可執行檔案都要定義相對的 filename_SOURCES 。

      6 、 automake

            我們使用 automake --add-missing 來產生 Makefile.in 。選項 --add-missing 的定義是 “ add missing standard files to package ” , 它會讓 automake 加入一個標準的

            軟體包所必須的一些檔案。我們用 automake 產生出來的 Makefile.in 檔案是符合 GNU Makefile 慣例的接下來我們只要執行 configure 這個 shell 指令碼就可以產生合的          

            Makefile 檔案了。

      7 、 Makefile

            在符合 GNU Makefiel 慣例的 Makefile 中,包含了一些基本的預先定義的操作:

             make

                 根據 Makefile 編譯原始碼,連線,生成目標檔案,可執行檔案。

             make clean

                 清除上次的 make 命令所產生的 object 檔案(字尾為 “ .o ” 的檔案)及可執行檔案。

             make install

                 將編譯成功的可執行檔案安裝到系統目錄中,一般為 /usr/local/bin 目錄。

             make dist

                  產生髮布軟體包檔案 ( 即 distribution package ) 。 這個命令將會將可執行檔案及相關檔案打包成一個 tar.gz 壓縮的檔案用來作為釋出軟體的軟體包。

             它會在當前目錄下生成一個名字類似“ PACKAGE-VERSION.tar.gz ” 的檔案。PACKAG E和 VERSION,是我們在 configure.in 中定義的

             AM_INIT_AUTOMAKE(PACKAGE,VERSION) 。

             make distcheck

                生成釋出軟體包並對其進行測試檢查,以確定釋出包的正確性。這個操作將自動把壓縮包檔案解開,然後執行 configure 命令,並且執行 make,來確認編譯不出現錯誤,

            最後提示你軟體包已經準備好,可以釋出了。

            ===============================================

            helloworld-1.0.tar.gz is ready for distribution

            ===============================================

            make distclean

               類似 make clean ,但同時也將 configure 生成的檔案全部刪除掉,包括 Makefile 。