GNU Autotools (autoconf, automake, libtool, etc.) 自动化编译 (1)
个人还是推荐使用cmake,更胜一筹!
0. 操作平台: Linux
1. 软件包安装(Debian)
yes | sudo apt-get install gcc make autoconf automake libtool
2. 从一个例子谈起。
2.0 完整拷贝如下代码直接在终端执行或者保存为auto-example.sh,添加执行权限执行。或者参考2.1~2.5逐步执行。
echo "create directory ..."
echo_exit()
{
echo "ERROR: $@"
exit 1
}
# 1.mkdir hello && cd hello || echo_exit "mkdir hello or cd hello failed"
cat > hello.c <<EOF || echo_exit "generates hello.c failed"
#include <stdio.h>
int main()
{
printf("hello auto-tools!\n");
return 0;
}
EOF
# 2.cat > Makefile.am << EOF || echo_exit "generates Makefile.am failed"
bin_PROGRAMS = hello
hello_SOURCES = hello.c
EOF
# 3.cat > configure.ac << EOF || echo_exit "generates configure.ac failed"
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ()
AC_INIT(, , )
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_CONFIG_SRCDIR()
AC_CONFIG_HEADERS()
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_CONFIG_FILES()
AC_OUTPUT
EOF
# 4.
autoreconf --install || echo_exit "autoreconf --install failed"
# 5.
./configure && make || echo_exit "configure or make failed"
# 6.
make dist && make distcheck || echo_exit "make dist && make distcheck failed"
echo "All Do Over Success"
2.1 创建hello目录和源代码hello.c: ~$ mkdir hello && cd hello
~$ cat > hello.c <<EOF
#include <stdio.h>
int main()
{
printf("hello auto-tools!\n");
return 0;
}
EOF 2.2 创建 Makefile.am
~$ cat > Makefile.am << EOF
bin_PROGRAMS = hello
hello_SOURCES = hello.c
EOF 2.3 用 autoscan 生成configure.ac的模板configure.scan
~$ autoscan
~$ cat configure.scan
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ()
AC_INIT(, , )
AC_CONFIG_SRCDIR()
AC_CONFIG_HEADERS()
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_CONFIG_FILES()
AC_OUTPUT
需要修改configure.scan的不问内容并保存为configure.ac。为了方便,直接用如下指令生成configure.ac:
~$ cat > configure.ac << EOF
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ()
AC_INIT(, , )
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_CONFIG_SRCDIR()
AC_CONFIG_HEADERS()
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_CONFIG_FILES()
AC_OUTPUT
EOF 可以看出,只是修改了AC_INIT行,并添加了AM_INIT_AUTOMAKE行。
2.4 使用autoreconf直接生成可执行configure并执行编译:
~$ autoreconf --install
configure.ac:6: installing `./install-sh'
configure.ac:6: installing `./missing'
Makefile.am: installing `./depcomp'
~$ ./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... gawk
checking whether make sets $(MAKE)... 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 for style of include used by make... GNU
checking dependency style of gcc... gcc3
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: executing depfiles commands
~$ make
makeall-am
make: Entering directory `/tmp/hello'
gcc -DHAVE_CONFIG_H -I. -g -O2 -MT hello.o -MD -MP -MF .deps/hello.Tpo -c -o hello.o hello.c
mv -f .deps/hello.Tpo .deps/hello.Po
gcc-g -O2 -o hello hello.o
make: Leaving directory `/tmp/hello'
~$ ./hello
hello auto-tools!
2.5生成发行包并检测完整性:
~$ make dist && make distcheck
/bin/sh ./config.status --recheck
running CONFIG_SHELL=/bin/sh /bin/sh ./configure --no-create --no-recursion
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... gawk
checking whether make sets $(MAKE)... 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 for style of include used by make... GNU
checking dependency style of gcc... gcc3
configure: creating ./config.status
/bin/sh ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: config.h is unchanged
config.status: executing depfiles commands
{ test ! -d "hello-1.0" || { find "hello-1.0" -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr "hello-1.0"; }; }
test -d "hello-1.0" || mkdir "hello-1.0"
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/sh /tmp/hello/install-sh -c -m a+r {} {} \; \
|| chmod -R a+r "hello-1.0"
tardir=hello-1.0 && /bin/sh /tmp/hello/missing --run tar chof - "$tardir" | GZIP=--best gzip -c >hello-1.0.tar.gz
{ test ! -d "hello-1.0" || { find "hello-1.0" -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr "hello-1.0"; }; }
{ test ! -d "hello-1.0" || { find "hello-1.0" -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr "hello-1.0"; }; }
test -d "hello-1.0" || mkdir "hello-1.0"
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/sh /tmp/hello/install-sh -c -m a+r {} {} \; \
|| chmod -R a+r "hello-1.0"
tardir=hello-1.0 && /bin/sh /tmp/hello/missing --run tar chof - "$tardir" | GZIP=--best gzip -c >hello-1.0.tar.gz
{ test ! -d "hello-1.0" || { find "hello-1.0" -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr "hello-1.0"; }; }
case 'hello-1.0.tar.gz' in \
*.tar.gz*) \
GZIP=--best gzip -dc hello-1.0.tar.gz | /bin/sh /tmp/hello/missing --run tar xf - ;;\
*.tar.bz2*) \
bzip2 -dc hello-1.0.tar.bz2 | /bin/sh /tmp/hello/missing --run tar xf - ;;\
*.tar.lzma*) \
lzma -dc hello-1.0.tar.lzma | /bin/sh /tmp/hello/missing --run tar xf - ;;\
*.tar.xz*) \
xz -dc hello-1.0.tar.xz | /bin/sh /tmp/hello/missing --run tar xf - ;;\
*.tar.Z*) \
uncompress -c hello-1.0.tar.Z | /bin/sh /tmp/hello/missing --run tar xf - ;;\
*.shar.gz*) \
GZIP=--best gzip -dc hello-1.0.shar.gz | unshar ;;\
*.zip*) \
unzip hello-1.0.zip ;;\
esac
chmod -R a-w hello-1.0; chmod a+w hello-1.0
mkdir hello-1.0/_build
mkdir hello-1.0/_inst
chmod a-w hello-1.0
test -d hello-1.0/_build || exit 0; \
dc_install_base=`CDPATH="${ZSH_VERSION+.}:" && cd hello-1.0/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="${TMPDIR-/tmp}/am-dc-$/" \
&& am__cwd=`pwd` \
&& CDPATH="${ZSH_VERSION+.}:" && cd hello-1.0/_build \
&& ../configure --srcdir=.. --prefix="$dc_install_base" \
\
&& make\
&& makedvi \
&& makecheck \
&& makeinstall \
&& makeinstallcheck \
&& makeuninstall \
&& makedistuninstallcheck_dir="$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$dc_install_base" \
&& ({ \
(cd ../.. && umask 077 && mkdir "$dc_destdir") \
&& makeDESTDIR="$dc_destdir" install \
&& makeDESTDIR="$dc_destdir" uninstall \
&& makeDESTDIR="$dc_destdir" \
distuninstallcheck_dir="$dc_destdir" distuninstallcheck; \
} || { rm -rf "$dc_destdir"; exit 1; }) \
&& rm -rf "$dc_destdir" \
&& makedist \
&& rm -rf hello-1.0.tar.gz \
&& makedistcleancheck \
&& cd "$am__cwd" \
|| exit 1
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... gawk
checking whether make sets $(MAKE)... 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 for style of include used by make... GNU
checking dependency style of gcc... gcc3
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: executing depfiles commands
make: Entering directory `/tmp/hello/hello-1.0/_build'
makeall-am
make: Entering directory `/tmp/hello/hello-1.0/_build'
gcc -DHAVE_CONFIG_H -I. -I.. -g -O2 -MT hello.o -MD -MP -MF .deps/hello.Tpo -c -o hello.o ../hello.c
mv -f .deps/hello.Tpo .deps/hello.Po
gcc-g -O2 -o hello hello.o
make: Leaving directory `/tmp/hello/hello-1.0/_build'
make: Leaving directory `/tmp/hello/hello-1.0/_build'
make: Entering directory `/tmp/hello/hello-1.0/_build'
make: Nothing to be done for `dvi'.
make: Leaving directory `/tmp/hello/hello-1.0/_build'
make: Entering directory `/tmp/hello/hello-1.0/_build'
make: Nothing to be done for `check'.
make: Leaving directory `/tmp/hello/hello-1.0/_build'
make: Entering directory `/tmp/hello/hello-1.0/_build'
make: Entering directory `/tmp/hello/hello-1.0/_build'
test -z "/tmp/hello/hello-1.0/_inst/bin" || /bin/mkdir -p "/tmp/hello/hello-1.0/_inst/bin"
/usr/bin/install -c hello '/tmp/hello/hello-1.0/_inst/bin'
make: Nothing to be done for `install-data-am'.
make: Leaving directory `/tmp/hello/hello-1.0/_build'
make: Leaving directory `/tmp/hello/hello-1.0/_build'
make: Entering directory `/tmp/hello/hello-1.0/_build'
make: Nothing to be done for `installcheck'.
make: Leaving directory `/tmp/hello/hello-1.0/_build'
make: Entering directory `/tmp/hello/hello-1.0/_build'
( cd '/tmp/hello/hello-1.0/_inst/bin' && rm -f hello )
make: Leaving directory `/tmp/hello/hello-1.0/_build'
make: Entering directory `/tmp/hello/hello-1.0/_build'
make: Leaving directory `/tmp/hello/hello-1.0/_build'
make: Entering directory `/tmp/hello/hello-1.0/_build'
make: Entering directory `/tmp/hello/hello-1.0/_build'
test -z "/tmp/hello/hello-1.0/_inst/bin" || /bin/mkdir -p "/tmp/am-dc-8010//tmp/hello/hello-1.0/_inst/bin"
/usr/bin/install -c hello '/tmp/am-dc-8010//tmp/hello/hello-1.0/_inst/bin'
make: Nothing to be done for `install-data-am'.
make: Leaving directory `/tmp/hello/hello-1.0/_build'
make: Leaving directory `/tmp/hello/hello-1.0/_build'
make: Entering directory `/tmp/hello/hello-1.0/_build'
( cd '/tmp/am-dc-8010//tmp/hello/hello-1.0/_inst/bin' && rm -f hello )
make: Leaving directory `/tmp/hello/hello-1.0/_build'
make: Entering directory `/tmp/hello/hello-1.0/_build'
make: Leaving directory `/tmp/hello/hello-1.0/_build'
make: Entering directory `/tmp/hello/hello-1.0/_build'
{ test ! -d "hello-1.0" || { find "hello-1.0" -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr "hello-1.0"; }; }
test -d "hello-1.0" || mkdir "hello-1.0"
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/sh /tmp/hello/hello-1.0/install-sh -c -m a+r {} {} \; \
|| chmod -R a+r "hello-1.0"
tardir=hello-1.0 && /bin/sh /tmp/hello/hello-1.0/missing --run tar chof - "$tardir" | GZIP=--best gzip -c >hello-1.0.tar.gz
{ test ! -d "hello-1.0" || { find "hello-1.0" -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr "hello-1.0"; }; }
make: Leaving directory `/tmp/hello/hello-1.0/_build'
make: Entering directory `/tmp/hello/hello-1.0/_build'
test -z "hello" || rm -f hello
rm -f *.o
rm -f *.tab.c
test -z "" || rm -f
test . = ".." || test -z "" || rm -f
rm -f config.h stamp-h1
rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
rm -f config.status config.cache config.log configure.lineno config.status.lineno
rm -rf ./.deps
rm -f Makefile
make: Leaving directory `/tmp/hello/hello-1.0/_build'
{ test ! -d "hello-1.0" || { find "hello-1.0" -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr "hello-1.0"; }; }
===========================================
hello-1.0 archives ready for distribution:
hello-1.0.tar.gz
===========================================
3. 一般项目并不是简单的一个.c文件。通常包括多个(嵌套的)目录。并且需要执行差异化的编译和安装,下一篇文章示范如何在一个实际项目中应用autotools。
作者:cppgp 发表于2012-2-14 17:40:22 原文链接
autotools入门,写个简单的程序,用起来很简单,但想深入还是有些难度的,主要是资料太少,大部分都是讲解单个工程的。
页:
[1]