通常linux下编译文件默认会使用内部编译方式,即编译的中间文件与源码放在一起,这样会使代码阅读带来很大的不便。如果使用外部编译将会很好的解决这个问题,下面我们以一个实例来讲解外部编译:
gqw@debian:~/workspace$ tree ./test_hello/
./test_hello/
|-- build
| |-- configure.ac
| `-- Makefile.am
|-- include
|-- lib
`-- src
|-- hello
| |-- hello.cpp
| `-- hello.h
|-- main.cpp
`-- test
|-- hello.cpp
`-- hello.h
6 directories, 7 files
通过上面的结构,可以看到src目录是源代码存放目录,我们希望在编译过程中保持此目录的干净,即不要将编译生成的中间文件放入此目录下。
build目录是我们手工添加的,其中的configure.ac可通过autoscan得到configure.scan文件修改而得。下面我们看下里面的内容:
gqw@debian:~/workspace$ cat ./test_hello/build/configure.ac
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.67])
AC_INIT([test_hello], [0.0.1], [gqwmail@gmail.com])
AM_INIT_AUTOMAKE
LT_INIT([disable-static])
AC_CONFIG_SRCDIR([../src/main.cpp])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
# Checks for programs.
#AC_PROG_LIBTOOL
AC_PROG_CXX
AC_PROG_CC
# Checks for libr aries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
再看一下Makefile.am内容
gqw@debian:~/workspace$ cat ./test_hello/build/Makefile.am
ACLOCAL_AMFLAGS=-I m4
AUTOMAKE_OPTIONS = foreign subdir-objects
nobase_include_HEADERS= \
../src/hello/hello.h \
../src/test/hello.h
lib_LTLIBRARIES=hello_test/libhello_test.la
hello_test_libhello_test_la_SOURCES= \
../src/main.cpp \
../src/hello/hello.cpp \
../src/test/hello.cpp
值得注意的是选项
AUTOMAKE_OPTIONS = foreign subdir-objects
这个选项中的subdir-objects会为生成的中间文件自动创建与源码一致的目录结构,而不是统一放在同一目录,从而可以解决中间文件名冲突问题,例如上面的hello/hello.cpp与test/hello.cpp。
下面开始我们的工作,先生成编译文件:
gqw@debian:~/workspace$ cd test_hello/build/
gqw@debian:~/workspace/test_hello/build$ libtoolize --automake
gqw@debian:~/workspace/test_hello/build$ aclocal
gqw@debian:~/workspace/test_hello/build$ autoheader
gqw@debian:~/workspace/test_hello/build$ autoconf
gqw@debian:~/workspace/test_hello/build$ automake -a
configure.ac:7: installing `./config.guess'
configure.ac:7: installing `./config.sub'
configure.ac:6: installing `./install-sh'
configure.ac:6: installing `./missing'
Makefile.am: installing `./depcomp'
gqw@debian:~/workspace/test_hello/build$ ls
aclocal.m4 config.h.in configure.ac ltmain.sh Makefile.in
autom4te.cache config.sub depcomp m4 missing
config.guess configure install-sh Makefile.am
好了,到现在为此我们已经得到了configure文件了,下面让我们使用./configure、make、make install来编译与安装我们的文件吧:
gqw@debian:~/workspace/test_hello/build$ mkdir install
gqw@debian:~/workspace/test_hello/build$ cd install
gqw@debian:~/workspace/test_hello/build/install$ ../configure --prefix=$(pwd)/../../; make;make install
这里创建目录install是必须的,但目录名随意,否则中间文件还是会生成到src下去。configure加上--prefix选项是为了安装时能够安装到工程目录下,下面让我们看下最终和文件结构:
gqw@debian:~/workspace$ tree test_hello/
test_hello/
|-- build
| |-- aclocal.m4
| |-- autom4te.cache
| | |-- output.0
| | |-- output.1
| | |-- requests
| | |-- traces.0
| | `-- traces.1
| |-- config.guess -> /usr/share/automake-1.11/config.guess
| |-- config.h.in
| |-- config.sub -> /usr/share/automake-1.11/config.sub
| |-- configure
| |-- configure.ac
| |-- depcomp -> /usr/share/automake-1.11/depcomp
| |-- install
| | |-- config.h
| | |-- config.log
| | |-- config.status
| | |-- hello_test
| | | `-- libhello_test.la
| | |-- libtool
| | |-- Makefile
| | `-- stamp-h1
| |-- install-sh -> /usr/share/automake-1.11/install-sh
| |-- ltmain.sh -> /usr/share/libtool/config/ltmain.sh
| |-- m4
| | |-- libtool.m4 -> /usr/share/aclocal/libtool.m4
| | |-- lt~obsolete.m4 -> /usr/share/aclocal/lt~obsolete.m4
| | |-- ltoptions.m4 -> /usr/share/aclocal/ltoptions.m4
| | |-- ltsugar.m4 -> /usr/share/aclocal/ltsugar.m4
| | `-- ltversion.m4 -> /usr/share/aclocal/ltversion.m4
| |-- Makefile.am
| |-- Makefile.in
| |-- missing -> /usr/share/automake-1.11/missing
| `-- src
| |-- hello
| | `-- hello.lo
| |-- main.lo
| `-- test
| `-- hello.lo
|-- include
| `-- src
| |-- hello
| | `-- hello.h
| `-- test
| `-- hello.h
|-- lib
| |-- libhello_test.la
| |-- libhello_test.so -> libhello_test.so.0.0.0
| |-- libhello_test.so.0 -> libhello_test.so.0.0.0
| `-- libhello_test.so.0.0.0
`-- src
|-- hello
| |-- hello.cpp
| `-- hello.h
|-- main.cpp
`-- test
|-- hello.cpp
`-- hello.h
16 directories, 43 files
看到了吗,src目录下是不是很干净?所有的中间文件都在build目录下。