Automake十分鐘速成教程

AUTOMAKE

小試牛刀

所需文件

使用automake管理單個可執行程序

  • 所需文件
  1. hello–文件夾
  2. hello/Makefile.am
  3. hello/configure.ac
  4. hello/inc–文件夾
  5. hello/src–文件夾
  6. hello/src/main.c
  7. hello/src/Makefile.am
  8. hello/README

文件內容如下:

andrew@andrew-Thurley:~/work/hello$ cat configure.ac 
AC_INIT([hello], [1.0], [[email protected]])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([
    Makefile
    src/Makefile
])
AC_OUTPUT
andrew@andrew-Thurley:~/work/hello$ 

andrew@andrew-Thurley:~/work/hello$ cat Makefile.am 
SUBDIRS = src
dist_doc_DATA = README
andrew@andrew-Thurley:~/work/hello$ 

andrew@andrew-Thurley:~/work/hello$ cat README 
This is a test for automakeandrew@andrew-Thurley:~/work/hello$ 


andrew@andrew-Thurley:~/work/hello$ cat src/Makefile.am 
bin_PROGRAMS = hello
hello_SOURCES = main.c


andrew@andrew-Thurley:~/work/hello$ cat src/main.c 
#include <stdio.h>
#include "config.h"

int main(int argc, char* argv[])
{
    puts("Hello world!\n");
    puts("This is " PACKAGE_STRING ".");
    return 0;
}

執行步驟

執行autoreconf --install

andrew@andrew-Thurley:~/work/hello$ autoreconf --install 
configure.ac:3: installing './compile'
configure.ac:2: installing './install-sh'
configure.ac:2: installing './missing'
src/Makefile.am: installing './depcomp'

除了生成上述三個文件之外,執行 autoreconf --install之後還會生成,configure config.h.in Makefile.in and src/Makefile.in,帶有後綴in的是臨時文件,執行configure之後會生成對應的config.h Makefile src/Makeifle.

autoreconf其實是一個腳本,會按照正確的順序調用autoconf automake等, 所以僅需調用autoreconf就不用擔心自己調用腳本的順序是否正缺正確了,autoreconf會按照正確的順序執行對應的命令。

執行./configure

執行./configure用於生成對應Makeifle腳本和config.h頭文件。

andrew@andrew-Thurley:~/work/hello$ ./configure 
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... no
checking for mawk... mawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
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 ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating config.h
config.status: executing depfiles commands

執行make

執行make生成可執行文件

andrew@andrew-Thurley:~/work/hello$ make
make  all-recursive
make[1]: Entering directory '/home/andrew/work/hello'
Making all in src
make[2]: Entering directory '/home/andrew/work/hello/src'
gcc -DHAVE_CONFIG_H -I. -I..     -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
mv -f .deps/main.Tpo .deps/main.Po
gcc  -g -O2   -o hello main.o  
make[2]: Leaving directory '/home/andrew/work/hello/src'
make[2]: Entering directory '/home/andrew/work/hello'
make[2]: Leaving directory '/home/andrew/work/hello'
make[1]: Leaving directory '/home/andrew/work/hello'

文件含義

configure.ac

configure.ac會用於autoconfautomake用於生成makefile.ins

andrew@andrew-Thurley:~/work/hello$ cat configure.ac 
# AC_ autoconf 宏,初始化autoconf
# AC_INIT 中的參數列表,代表的意思,文件夾名,版本號,bug報告地址
AC_INIT([hello], [1.0], [[email protected]])
# AM_ automake 宏 初始化automake
# AM_INIT_AUTOMAKE 中的參數列表是,傳遞給automake的,
# foreign 告訴automake這個工程不是標準的GNU項目,有些文件GNU中的必要的文件可以缺失
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
# 告訴configure去尋找C編譯器,並使用CC編譯hello,configure將CC定義成對應編譯工具
AC_PROG_CC
# autoconf會將上述定義的變量,生成對應的宏定義放到對應的config.h中
AC_CONFIG_HEADERS([config.h])
# 定義 configure應該根據 *.in等臨時文件,生成的文件
AC_CONFIG_FILES([
    Makefile
    src/Makefile
])
# 結束命令,實際生成,AC_CONFIG_HEADERS  AC_CONFIG_FILES 中註冊的文件
AC_OUTPUT

Makefile.am

# SUBDIRS 指定需要構建的文件夾
# make dist時,會自動的將README發佈,這裏的dist_doc_DATA 是留給make install使用的
# The line dist_doc_DATA = README causes README to be distributed and installed in
# docdir.
andrew@andrew-Thurley:~/work/hello$ cat Makefile.am 
SUBDIRS = src
dist_doc_DATA = README
andrew@andrew-Thurley:~/work/hello$ 

# 包含automake指令,用於構建和安裝hello
# bin_PROGRAMS 是需要安裝的可執行文件,如果文件不需要安裝可以使用 noinst_PROGRAMS
# _PROGRAMS構建文件
# _SCRIPTS 生成腳本
# _DATA 生成數據文件
# _LIBRARIES 生成庫文件
# make dist 發佈文件時,source文件也會打到發佈的文件中
andrew@andrew-Thurley:~/work/hello$ cat src/Makefile.am 
bin_PROGRAMS = hello
hello_SOURCES = main.c

說明:

The line dist_doc_DATA = README causes README to be distributed and installed in docdir. Files listed with the _DATA primary are not automatically part of the tarball built with make dist, so we add the dist_ prefix so they get distributed. However, for README it would not have been necessary: automake automatically distributes any README file it en- counters (the list of other files automatically distributed is presented by automake --help). The only important effect of this second line is therefore to install README during make install.

發佈程序

make dist

andrew@andrew-Thurley:~/work/hello$ make dist
make  dist-gzip am__post_remove_distdir='@:'
make[1]: Entering directory '/home/andrew/work/hello'
if test -d "hello-1.0"; then find "hello-1.0" -type d ! -perm -200 -exec chmod u+w {} ';' && rm -rf "hello-1.0" || { sleep 5 && rm -rf "hello-1.0"; }; else :; fi
test -d "hello-1.0" || mkdir "hello-1.0"
 (cd src && make  top_distdir=../hello-1.0 distdir=../hello-1.0/src \
     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)
make[2]: Entering directory '/home/andrew/work/hello/src'
make[2]: Leaving directory '/home/andrew/work/hello/src'
test -n "" \
|| find "hello-1.0" -type d ! -perm -755 \
	-exec chmod u+rwx,go+rx {} \; -o \
  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
  ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
  ! -type d ! -perm -444 -exec /bin/bash /home/andrew/work/hello/install-sh -c -m a+r {} {} \; \
|| chmod -R a+r "hello-1.0"
tardir=hello-1.0 && ${TAR-tar} chof - "$tardir" | GZIP=--best gzip -c >hello-1.0.tar.gz
make[1]: Leaving directory '/home/andrew/work/hello'
if test -d "hello-1.0"; then find "hello-1.0" -type d ! -perm -200 -exec chmod u+w {} ';' && rm -rf "hello-1.0" || { sleep 5 && rm -rf "hello-1.0"; }; else :; fi

example

編譯可執行文件

#Makefile.am文件
bin_PROGRAMS = xxx
#bin_PROGRAMS 表示指定要生成的可執行應用程序文件,這表示可執行文件在安裝時需要被安裝到系統
#中;如果只是想編譯,不想被安裝到系統中,可以用noinst_PROGRAMS來代替

xxx_SOURCES = a.c b.c c.c main.c d.c xxx.c
#xxx_SOURCES表示生成可執行應用程序所用的源文件,這裏注意,xxx_是由前面的bin_PROGRAMS
#指定的,如果前面是生成example,那麼這裏就是example_SOURCES,其它的類似標識也是一樣

xxx_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\" -DLIBRARY_DIR=\"$(pkglibdir)\"
#xxx_CPPFLAGS 這和Makefile文件中一樣,表示C語言預處理參數,這裏指定了DCONFIG_DIR,以後
#在程序中,就可以直接使用CONFIG_DIR。不要把這個和另一個CFLAGS混淆,後者表示編譯器參數

xxx_LDFLAGS = -export-dynamic -lmemcached
#xxx_LDFLAGS 連接的時候所需庫文件的標識,這個也就是對應一些如-l,-shared等選項

noinst_HEADERS = xxx.h
#這個表示該頭文件只是參加可執行文件的編譯,而不用安裝到安裝目錄下。如果需要安裝到系統中,
#可以用include_HEADERS來代替

INCLUDES = -I/usr/local/libmemcached/include/
#INCLUDES  鏈接時所需要的頭文件

xxx_LDADD = $(top_builddir)/sx/libsession.a \
                $(top_builddir)/util/libutil.a
#xxx_LDADD 鏈接時所需要的庫文件,這裏表示需要兩個庫文件的支持

編譯動態庫

#Makefile.am文件
xxxlibdir=$(libdir)//新建一個目錄,該目錄就是lib目錄,運行後xxx.so將安裝在該目錄下 
xxxlib_PROGRAMS=xxx.so  
xxx_so_SOURCES=xxx.c
xxx_so_LDFLAGS=-shared -fpic //GCC編譯動態庫的選項

編譯靜態庫

#Makefile.am文件 noinst 說明該庫不需要安裝
noinst_LTLIBRARIES = xxx.a
noinst_HEADERS = a.h b.h
xxx_a_SOURCES = a.c b.c xxx.c

完整代碼地址鏈接

在這裏插入圖片描述

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