實例學習使用Autotools

經常有程序需要交叉編譯,手工寫Makefile寫的太混亂了,學習用Autotools來生成Makefile方便許多。

下面記錄了一個mp3播放器簡單程序使用Autotools的步驟。
播放器支持使用OSS接口,也支持使用ALSA接口來輸出聲音。

1.進入工程目錄,執行autoscan,在此目錄下生成了configure.scan文件。修改此文件內容,並重新命名爲configure.ac。最終的內容如下:
AC_PREREQ([2.63])
# !!!修改模塊名,版本號,bug report爲自己所需要的內容。
AC_INIT([mp3player], [1.0], [root@localhost])
# !!!手工添加此句。以使用Automake。
AM_INIT_AUTOMAKE(mp3player,1.0)
# 一個有效的代碼文件。可手工改動,亦可保持不變。
AC_CONFIG_SRCDIR([src/main.c])
# 指定Autoheader生成的頭文件名。一般保持config.h不變。
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
# 檢測c編譯器。如果代碼中有c代碼scan時會自動添加
AC_PROG_CC
# 檢測c++編譯器。如果代碼中有c++代碼scan時會自動添加。本項目不用,就註釋掉了。
# AC_PROG_CXX

# Checks for libraries.
# 檢測pthread庫是否存在
#
# AC_CHECK_LIB(庫名稱,需要庫中的函數,[如果找到,[如果沒找到]])
AC_CHECK_LIB(pthread, pthread_create, HAVE_PTHREAD=yes,HAVE_PTHREAD=no)
if test "$HAVE_PTHREAD" = "no"; then
# 輸出錯誤信息。configure會終止。
AC_MSG_ERROR([pthread is required])
fi
# 定義PTHREAD的LDFLAG,以在Makefile.am中加入到鏈接器參數中去。
PTHREAD_LIBS=-lpthread
# AC_SUBST 定義的變量可以在Makefile.am中使用
AC_SUBST(PTHREAD_LIBS)

# Check use OSS or ALSA
# 此宏定義的模塊,可以在configure時通過--with-oss啓用。
AC_ARG_WITH([oss], [AS_HELP_STRING([--with-oss],[Use OSS sound api instead of ALSA])], [USE_ALSA=no], [USE_ALSA=yes])
if test "$USE_ALSA" = "no"; then
# 輸出一些提示信息
AC_MSG_NOTICE(Use OSS api.)
# 在config.h中添加一個宏。程序中可以使用#ifdef來檢測。
AC_DEFINE(USE_OSS,,[Use OSS api if this macro is defined.])
else
    #檢測ALSA庫是不是存在。
    #最小版本號。
    ASOUND_VER=0.9
    # PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [action-if-found], [action-if-not-fount])
    # 前綴是用來定義變量的,MODULES是一個表達式,這兒要注意的是,雖然Alsa庫是libasound,但是其pkg-config配置文件是alsa.pc,所以這兒是檢測alsa而不是ASOUND >= $ASOUND_VER。
    PKG_CHECK_MODULES(ASOUND, alsa >= $ASOUND_VER, HAVE_ASOUND=yes,HAVE_ASOUND=no)
    if test "$HAVE_ASOUND" = "no"; then
    AC_MSG_ERROR([alsa >= $ASOUND_VER is required])
    fi
    # 到這兒時已經自動生成了Alsa庫的CFLAGS,LIBS,用到了前綴。將這兩個宏公佈出去,以在Makefile.am中使用。
    AC_SUBST(ASOUND_LIBS)
    AC_SUBST(ASOUND_CFLAGS)
fi

# Checks for header files.
AC_CHECK_HEADERS([fcntl.h stdlib.h sys/ioctl.h unistd.h])

# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
AC_C_INLINE

# Checks for library functions.
AC_FUNC_MALLOC
AC_CHECK_FUNCS([clock_gettime strncasecmp])

# !!!這句要有
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

2.運行aclocal處理本地宏定義
3.autoconf生成configure文件
4.autoheader生成config.h.in文件
5.創建Makefile.am文件,automake會根據此文件生成Makefile.in文件,最終configure根據Makefile.in生成最後的Makefile。最終的Makefile.am文件內容如下:
# 可執行文件名。後面的變量都會以這個爲前綴。
bin_PROGRAMS= mp3player

# 所有的代碼文件
mp3player_SOURCES= src/main.c src/decoder.c src/device.c src/mp3file.c src/outputter.c src/pcmBuffer.c src/player.c src/playthread.c

# 需要額外鏈接的靜態庫
mp3player_LDADD=./mad/lib/libmad.a

# 需要額外鏈接的動態庫。這兒用到的PTHREAD_LIBS,ASOUND_LIBS都是在configure.ac中公佈出來的。
mp3player_LDFLAGS=$(PTHREAD_LIBS) -lrt $(ASOUND_LIBS)

# 需要額外添加的編譯器參數。
mp3player_CFLAGS=-I./mad/include $(ASOUND_CFLAGS)

# 此選項告訴automake不要檢測此目錄下是否有README,NEWS,AUTHORS,ChangeLog這些文件了
AUTOMAKE_OPTIONS=foreign
6.automake --add-missing --copy
根據Makefile.am 生成Makefile.in文件
7.運行configure,根據Makefile.in生成實際的Makefile。如果不帶任何參數,可以看到輸出有檢測alsa的提示。如果./configure --with-oss就可以看到提示使用OSS接口。並且打開config.h,可以找到#define USE_OSS這個我們在configure.ac中指定的宏。
8.爲了方便添加原文件後,不再重複以上步驟,寫一個autogen.sh腳本,內容如下:
aclocal
autoheader
automake --add-missing --copy
autoconf
以後無論是修改configure.ac增加庫的引用還是修改Makefile.am增加源文件,只要重新執行一遍這個腳本就可以了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章