對於寫window-c++的程序員來講由IDE幫他們解決源代碼的編譯過程,可是針對linux-c/c++程序寫一個makefile 確實也讓人頭痛
最近源碼編譯開源軟件的時候認識了automake,今天就使用automake作了一個測試,編譯個c++僞工程linux
Linux下automake軟件編譯與發佈之多級目錄結構的處理
多級目錄結構的軟件,通常是單個程序、庫文件或模塊放在各自的目錄中。automake要求每一個目錄都有本身的Makefile.am文件來編譯各自目錄下的代碼。
在頂級的目錄中,有一個Makefile.am文件,該文件經過SUBDIRS指明瞭這個目錄下有多少個直接下級目錄的代碼須要編譯。下級目錄的Makefile.am也指明本身須要編譯的下級目錄。
經過這樣的層層遞歸,從而完成多級目錄結構的編譯。
例子目錄結構以下:
leicc
|src
||--main.cpp
||--main.h
||--global.h
||api
|||--api.h
|||--api.cpp
|||--app.h
|||--app.cpp
||logic
|||--user.h
|||--user.cpp
下面是編譯步驟:
1.運行autoscan產生configure.scan
在頂級目錄leicc下運行autoscan命令。產生configure.scan
2.編輯 mv configure.scan configure.in 而後編輯configure.in
將configure.scan更名成configure.in,而後修改以下:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.c++
AC_PREREQ([2.63])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AM_INIT_AUTOMAKE(main, v1.0) #軟件包名稱和版本號
AC_CONFIG_SRCDIR([src/main.cpp])
AC_CONFIG_HEADERS([config.h])程序員
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
#使用了靜態庫編譯,須要此宏定義
AC_PROG_RANLIBapi
# Checks for libraries.app
# Checks for header files.
AC_CHECK_HEADERS([stdlib.h string.h])ide
# Checks for typedefs, structures, and compiler characteristics.測試
# Checks for library functions.
AC_FUNC_MALLOC
AC_CHECK_FUNCS([memset])
#須要生成的Makefile
AC_OUTPUT(Makefile src/Makefile src/api/Makefile src/app/Makefile)
3.運行aclocal和autoconf/autoheader
configure.in修改完後則前後執行aclocal和autoconf命令。
4.創建各個目錄的Makefile.am文件
在頂級目錄、src目錄和api/logic目錄下分別創建三個Makefile.am文件。內容分別以下:
頂級目錄Makefile.am: ui
AUTOMAKE_OPTIONS=foreign
SUBDIRS=src #本目錄的直接下級目錄src須要編譯
#EXTRA_DIST=doc/userguide #doc/userguide不須要編譯,但要發佈該文件。若是有多個文件,則用空格分開。
src目錄下的Makefile.am:this
AUTOMAKE_OPTIONS=foreign
SUBDIRS=api logic #本目錄的直接下級目錄api須要編譯
bin_PROGRAMS=main #本目錄的文件編譯成可執行文件main。若有多個,用空格分開。而後在下面分別寫它們的SOURCE和LDADD。
main_SOURCES=main.cpp #編譯main須要的源文件列表,若有多個,用空格分開。
main_LDADD=api/libapi.a logic/liblogic.a #編譯main須要的庫文件列表。若有多個,用空格分開。
api目錄下的Makefile.amblog
AUTOMAKE_OPTIONS=foreign
noinst_LIBRARIES=libapi.a #本目錄下的代碼編譯成libapi.a庫。不須要發佈。若是須要發佈,則寫成bin_LIBRARIES。注意,庫的名稱格式必需爲 libxxx.a。由於編譯靜態庫,configure.in須要定義AC_PROG_RANLIB宏。
noinst_HEADERS =api.h app.h #定義頭文件
libapi_a_SOURCES=api.cpp app.cpp #編譯libapi.a須要的源文件。注意將庫名稱中的'.'號改爲'_'號。
logic目錄下的Makefile.am
AUTOMAKE_OPTIONS=foreign
noinst_LIBRARIES=liblogic.a #本目錄下的代碼編譯成libapi.a庫。不須要發佈。若是須要發佈,則寫成bin_LIBRARIES。注意,庫的名稱格式必需爲 libxxx.a。由於編譯靜態庫,configure.in須要定義AC_PROG_RANLIB宏。
noinst_HEADERS =user.h #定義頭文件
liblogic_a_SOURCES=user.cpp #編譯libapi.a須要的源文件。注意將庫名稱中的'.'號改爲'_'號。
6.運行automake --add-missing 以上幾個Makefile.am都書寫完畢後,運行automake --add-missing。 7.運行./configure和make 上面步驟完成後,前後運行./configure和make完成編譯。若是編譯成功,運行make dist能夠將全部文件打包成main-v1.0.tar.gz