通常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目录下。