2020年1月29日 星期三

Autotools 用法舉例


1. 參考網路文章,整理操作步驟如下

  • 先建立程式碼,並在對應目錄內先寫好 Makefile.am
  • 執行 autoscan 生成 configure.scan, 複製成 configure.ac 並進行修改
  • 執行 aclocal 命令。掃描 configure.ac 檔案生成 aclocal.m4 檔案。
  • 執行 autoheader 命令。該命令生成 config.h.in 檔案。
  • touch NEWS README AUTHORS ChangeLog
NEWS README AUTHORS ChangeLog:
這些檔案是GNU軟體的標配,不過在專案中不一定需要加入。
如果專案中沒有這些檔案,每次autoreconf會提示缺少檔案,不過這並不影響。
  • 執行 automake -a -c -f 該命令生成 Makefile.in 檔案。
  • 執行 autoconf 命令。這個命令將 configure.ac 檔案中的巨集展開,生成 configure 指令碼。
  • 執行 ./congigure 命令。將Makefile.in命令生成Makefile檔案,開始編譯
$ ./configure --prefix=`pwd`/../test
$ make
$ make install
  • 若再次修改 configure.ac,則需要重複下列步驟
$ aclocal
$ autoheader
$ automake -a -c -f
$ autoconf


2. 實際測試步驟整理如下
a. 先安裝 autotool
$ sudo apt install autotools-dev m4 autoconf
$ sudo apt install autoconf-archive gnu-standards autoconf-doc libtool
b. 假設原始目錄架構如下
~/test/autotool_test$ tree
.
  ├── inc
  │   └── liba.h
  ├── src
  │   └── liba.c
  └── test
      └── test.c
c. 在對應目錄內先寫好 Makefile.am
Makefile.am
SUBDIRS = src test
src/Makefile.am
AM_CFLAGS = -I../inc
liba_LIBRARIES = liba.a
liba_a_SOURCES = liba.c liba.h
include_HEADERS = ../include/liba.h
test/Makefile.am
LDADD = ../libs/liba.a
AM_CFLAGS = -I../inc
bin_PROGRAMS = test
test_SOURCES = test.c 
d. 按照上述操作步驟生成 configure.ac, 修改後的檔案如下
AC_PREREQ([2.69])
AC_INIT(mytest, 1.0.0, alb423@gmail.com)
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([src/liba.c])
AC_CONFIG_HEADERS([config.h])
AC_PROG_CC
AC_PROG_RANLIB
AC_CONFIG_FILES([Makefile
   src/Makefile
   test/Makefile])
AC_OUTPUT
e. 後續按照上述操作步驟執行即可。

參考資料

  • https://www.slideshare.net/zzz00072/gnu-make-autotools-cmake
  • https://slidesplayer.com/slide/15153334/
  • https://www.lrde.epita.fr/~adl/autotools.html



Makefile 中的 CFLAGS 變數套用順序

當使用 make 編譯程式時,若有多處定義 CFLAGS,則最終結果應該為何呢?

針對此疑問,整理相關資訊如下:

1. 若在命令列有先指定 CFLAGS, 則 Makefile 內的變數就不會套用。
例如: 執行 make CFLAGS=-g ,則 Makefile 內的 CFLAGS 便會失效 
原文如下:
If a variable has been set with a command argument (see Overriding Variables), then ordinary assignments in the makefile are ignored. If you want to set the variable in the makefile even though it was set with a command argument, you can use an override directive, which is a line that looks like this:
https://www.gnu.org/software/make/manual/html_node/Overriding.html


2.  若在命令列有先指定 CFLAGS, 但仍想要讓 Makefile 內的 CFLAGS有效,可使用 override 關鍵字
原文如下:
Variable assignments marked with the override flag have a higher priority than all other assignments, except another override. Subsequent assignments or appends to this variable which are not marked override will be ignored.
https://www.gnu.org/software/make/manual/html_node/Override-Directive.html#Override-Directive 
實際例子如下
https://github.com/buildroot/buildroot/blob/master/package/irrlicht/0001-override-CPPFLAGS-CXXFLAGS-and-CFLAGS-in-Makefile.patch

3. 若編譯時,命令列沒有帶入 CFLAGS,則直接參考 Makefile 內的 CFLAGS 設定即可。