[轉]Linux中configure/makefile

本文教你如何使用autoconf、automake等來製做一個以源代碼形式(.tar.gz)發佈的軟件、並可在執行configure時使用自定義參數。linux


1、概述和基礎知識ios

  在Linux下獲得一個以源代碼形式發佈的包(通常爲.tar.gz或.tar.bz2格式),咱們能夠用 ./confiugure、make、make install來編譯安裝,其中在運行./configure的時候還能夠根據本身的須要加入不一樣的參數(可用./configure --help來查看參數表)。架構

  先說說執行./configure後會生成什麼東西?運行後系統會根據用戶的實際狀況生成config.h和多個Makefile。其中Makefile是運行make時所用的模板;而config.h則會以宏(Marco)的形式記錄用戶的自定義參數,編譯器能夠根據config.h來對源代碼進行預編譯(pre-compile),從而生成個性化的執行檔。函數


2、咱們的「軟件」測試

  如今咱們能夠動手設計一個本身的「軟件」了,爲了更切合實際,將使用多個源程序,首先創建一個目錄tt,用來放咱們的東西,而後在tt下創建一個src目錄,通常來講源代碼都放在src中(好像已經成爲一個不成文的規矩了:P)。總體架構以下:
  <tt>
   |-configure.in
   |-Makefile.am
   |-acconfig.h
   |-<src>
     |-tt.c
     |-qq.c
     |-qq.h
     |-Makefile.am網站

※說明:
1. configure.in 這是最重要的文檔,整個安裝過程都靠它來主導。
2. Makefile.am automake會根據它來生成Makefile.in,再由./configure 把Makefile.in變成最終的Makefile,通常來講在頂級目錄和各個子目錄都應該有一個Makefile.am
3. acconfig.h autoheader會根據它來生成config.h.in,再由./configure 把config.h.in變成最終的config.h
4. tt.c qq.c qq.h 這是咱們的源程序。spa

※源代碼內容:.net

tt.c命令行

#include <stdio.h>
#include <qq.h>

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

int main(void)
{
   int a = 23;

   printf( "Hello, I am teacher(%d), pls tell me your names!/n", a );

   #ifdef POPO
   printf("My name is PoPo!/n");
   #endif

   qq();

   return 0;
}

qq.c設計

#include <stdio.h>
#include <qq.h>

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

void qq(void)
{
   printf("My name is QQ/n");

   #ifdef POPO
   printf("QQ: Hey PoPo, long time no see./n");
   #endif
}

qq.h

#ifndef __QQ__
#define __QQ__

void qq(void);

#endif

※運行流程:

 1. 首先老師來點名。
 2. 若是PoPo有來的話,將會報出本身的名字。
 3. 接著輪到QQ報到,若是PoPo有來的話,QQ會向PoPo問好。

  顯然易見,PoPo是否出席,徹底取決於POPO這個宏(Macro)有否被定義,咱們只要在編譯前決定要不要定義它,就能實現不一樣的效果。

  若是config.h存在的話,編譯時Makefile會把宏HAVE_CONFIG_H傳給編譯器,因此若是沒有定義HAVE_CONFIG_H 的話,咱們的程序不該該把config.h include進去。

3、製做流程

請按照如下的執行順序一步一步作:

第一步 編寫configure.in

  生成configure.in的方法有兩個,一個是本身從零開始寫,另外一個方法是用autoscan,執行autoscan後會生成configure.scan,其中包含了一些模板內容,使用時只要把名字改爲.in就能夠。

  configure.in中使用的命令有兩種,一種是以AC開頭,表示是由autoconf提供,另外一種是以AM開頭,表明由automake提供。

  在configure.in咱們能夠完成不少檢測動做,好比檢查編譯所需的程式、頭文件、庫等等,總之功能是十分強大,不過咱們這裏只檢測了編譯器和頭文件,詳細用法請看 GNU Manuals Online

  以"dnl"爲首的行爲註釋行(代碼中綠色部份)。

  configure.in

dnl 初始化autoconf,參數爲入口函數所在的文件
AC_INIT(src/tt.c)

dnl 初始化automake,參數爲軟件名稱及版本號
AM_INIT_AUTOMAKE(tt, 0.1.0)

dnl 告訴automake咱們所用的配置文件,通常爲config.h
AM_CONFIG_HEADER(config.h)

dnl 這裏是實現自定義參數的部份,見下面的說明
AC_ARG_ENABLE(popo, [ --enable-popo PoPo is present],,enable_popo=no)
if test "$enable_popo" = yes ; then
   echo "PoPo is here!"
   AC_DEFINE(POPO)
else
   echo "PoPo isn't here!"
fi

dnl 檢測編譯器
AC_PROG_CC

dnl 檢測Standard C的頭文件
AC_HEADER_STDC

dnl 輸出文件,通常來講頂級目錄和各子目錄都應有Makefile輸出
AC_OUTPUT(Makefile src/Makefile)

 

./configure的自定義參數有兩種,一種是開關式(--enable-XXX或--disable-XXX),另外一種是開放式,即後面要填入一串字符(--with-XXX=yyyy)參數。
  上述代碼中用的是開關式,第一個參數是參數名,第二個是說明(執行"./configure --help"後所顯示出來的內容),最後一個參數是默認值。通常來講默認值和用戶提示應該是互斥的,即默認值是no的話,應提示用戶用enable進行修改,反之亦然。
  從上面的代碼中能夠看到,若是$enable_popo爲yes的話,就用AC_DEFINE來定義POPO這個宏(Macro),不然就不定義,咱們在這裏所使用到的宏,必定要在acconfig.h中聲明。

第二步 運行aclocal 在tt目錄下運行aclocal,將會生成aclocal.m4。

第三步 編寫acconfig.h

  在configure.in中使用到的宏(Macro),都應該在這個文件聲明,通常用#undef來聲明。

acconfig.h

#undef POPO

 


第四步 運行autoheader

  運行autoheader後會根據configure.in、acconfig.h和系統預設的acconfig.h來生成config.h.in。

第五步 編寫Makefile.am

  通常來講,在頂級目錄和各子目錄都應有一個Makefile.am。


Makefile

AUTOMAKE_OPTIONS = foreign
SUBDIRS = src

 

  第一行是告訴automake不要檢測目錄中是否存在AUTHORS、README等文件。
  第二行是告訴automake處理src這個子目錄。


src/Makefile

AUTOMAKE_OPTIONS = foreign
bin_PROGRAMS = tt
tt_SOURCES = tt.c qq.c qq.h

 

  第一行做用同前。
  第二行是目標執行檔的名稱。
  第三行是生成tt這個執行檔所需的全部源程序和頭文件名稱。

第六步 運行automake

  接著能夠執行automake了,在命令行下輸入
    automake -a 和
    automake -a src/Makefile
  使用"automake -a"或"automake --add-missing",會自動將install.sh、mkinstalldirs等文件補齊,不然會出錯,切記!

第七步 運行autoconf

  最後,能夠執行autoconf了,完成後將會生成最終的configure!


4、編譯&測試

  用默認值編譯: 
[root@chiosoft tt]# ./configure
Checking for ......
PoPo isn't here!
Checking for ......

[root@chiosoft tt]# make
......

[root@chiosoft tt]# src/tt
Hello, I am teacher(23), pls tell me your names!
My name is QQ

 

  默認狀態下,咱們沒有定義宏POPO,因此./configure時輸出"PoPo isn't here!",運行時也只有QQ來報到。

  再看看這個: 
[root@chiosoft tt]# ./configure --help
......
--enable and --with options recognized:
 --enable-popo PoPo is present

[root@chiosoft tt]# ./configure --enable-popo
Checking for ......
PoPo is here!
Checking for ......

[root@chiosoft tt]# make
......

[root@chiosoft tt]# src/tt
Hello, I am teacher(23), pls tell me your names!
My name is PoPo!
My name is QQ
QQ: Hey PoPo, long time no see.

 

  能夠看到./configure時輸出"PoPo is here!",執行結果也徹底不同!

  此外,咱們也能夠用make install來安裝,預設是安裝至/usr/local/bin下,固然,這些都是能夠修改的。


5、生成發佈包tarball

  好了,至今爲止,咱們的小軟件已經測試完畢,能夠發佈了,在tt下有不少文件,有的是咱們本身寫的,也有些是編譯時生成的臨時檔案,到底哪些須要打包到發行包中呢?固然你能夠本身一個一個文件挑選,但用automake生成的Makefile提供了幾個極方便的功能給咱們。

  咱們能夠用make dist或make distcheck來生成相應的tarball,其中後者還會幫咱們測試發佈包可否正常工做,因此我的推薦使用make distcheck。

  看到了吧?發佈包tt-0.1.0.tar.gz已經放到tt下了,有沒有留意,這裏用的軟件名及版本號正是 configure.in中AM_INIT_AUTOMAKE所帶的兩個參數!如今你能夠試試把它解壓安裝了。

相關文章
相關標籤/搜索