AutoTools使用小记
壮族小伙看代码喜欢运行起来看,什么源代码都先想办法跑起来再仔细研究。最近遇到困难:网上流出的天龙代码是VS2010的工程,编译没问题但运行的时候缺少FoxScriptEngine.dll的动态库,翻了一下工程发现只有FoxScript.h的头文件,没有对应的实现。lua脚本这块的载入运行需要这个动态库,没有这个动态库程序没法运行。静态的看代码那个苦呀,于是在网上一通乱找,找到linux可运行的版本以及资源。接下来要做的就是把VS2010的工程换成Makefile。
平时都是手工写Makefile,用的都是最简单的功能,电脑上的《GNU make中文手册》也没看,浑浑噩噩,每次Makefile有问题都不知道怎么解决。无数次羡慕开源项目的编译安装方法:./configure make && make install。痛定思痛学习了一下如何使用GNU autotools工具。
本文主要参考《例解autoconf和automake生成Makefile文件》,使用autotool工具制作Makefile的基本流程如下图:
图 1-1
automake支持三种目录层次[1]:flat、shallow和deep
(1) flat指的是所有文件都位于同一个目录中。
(2) shallow指的是主要的源代码都储存在顶层目录,其他各个部分则储存在子目录中。
(3) deep指的是所有源代码都被储存在子目录中;顶层目录主要包含配置信息。
一、简单例子
下面写一个helloworld来练练手:
1. helloworld.cpp
1: #include <stdio.h>
2: int main()
3: {
4: printf(“Hello World!\n”);
5: return 0;
6: }
2. 创建Makefile.am文件,写入以下内容:
1: bin_PROGRAMS = hello
2: hello_SOURCES = helloworld.cpp
3.使用autoscan扫描目录,将生成的configure.scan文件更名为configure.in或者configure.ac,主要内容可以简略为:
1: AC_INIT(helloworld.cpp)
2: AM_INIT_AUTOMAKE(helloworld, 1.0)
3: AC_PROG_CXX
4: AC_OUTPUT(Makefile)
4. 执行aclocal命令,aclocal会根据configure.in的内容(主要是其中用到的m4宏)到指定的路径下的m4宏定义文件中提取用到的宏定义,写到aclocal.m4文件中,供automake使用。AC_PROG_CXX就定义在m4文件中。
5. 执行autoconf命令,生成configure脚本
6. 执行automake --add-missing --foreign,命令会根据Makefile.am及m4文件生成对应的Makefile.in。
7. 执行./configure,生成Makefile
8. make(make install安装,make dist生成安装包)
八个主要步骤清晰明确,写Makefile变成一件愉快的事情。
二、创建天龙linux下的工程
天龙的目录结构如下,Common目录放置一些公用代码和协议处理的cpp,Server目录下五个工程对应五个可执行文件都是服务器端运行时需要启动的。可以看到这样的目录结构适合使用automake的deep层次模式。
在linux下创建天龙代码的工程时,一度想把Common目录下所有cpp文件编成一个统一的静态库,做着做着发现这事不靠谱,五百多个cpp文件混在一堆,但功能并不是完全独立的,一些文件需要用到Server目录下的文件(这个Common目录不是真正意义上的common)。
接下来只能从原有的VS2010工程文件入手为Server下的目录每个工程做一个Makefile,需要用到Common目录下文件时,用相对路径指向Common即可。以BillingServer为例查看virtualstudio的工程文件Billing.vcproj
1: <Files>
2: <Filter
3: Name="Base"
4: >
5: <File
6: RelativePath="..\..\..\Common\ServerBase\Config.cpp"
7: >
8: </File>
9: <File
10: RelativePath="..\..\..\Common\ServerBase\Config.h"
11: >
12: </File>
13: <File
14: RelativePath="..\..\..\Common\ServerBase\File.cpp"
15: >
16: </File>
17: <File
18: RelativePath="..\..\..\Common\ServerBase\File.h"
19: >
20: </File>
21: <File
22: RelativePath="..\..\..\Common\ServerBase\Ini.cpp"
23: >
24: </File>
25:
26: ...............
27:
28: </Files>
.vcproj文件的可读性还是很强的,可以很快提取出工程中所以依赖的文件(感谢万能的vim)。在编写Makefile.am文件的时候注意下面几项:
1: bin_PROGRAMS = billing
2: INCLUDES = -Ihttp://www.cnblogs.com/../Common/ ........
3: billing_CPPFLAGS = -D__LINUX__ -D__linux
4: billing_LDADD = -lodbc
5: billing_LDFLAGS = -L/home/project/tlbb/unixODBC/lib
6:
7: billing_SOURCES = ./stdafx.cpp http://www.cnblogs.com/../Common/ServerBase/Config.cpp ...........
在billing_SOURCES项把所有依赖的cpp都添加好后,使用automake生成Makefile.in,然后./configure, make就可以编译。(odbc的sqltypes.h文件由于typedef冲突,注释掉好几行才编译通过的)
编译完成后如果没错会在本地目录生成可执行文件billing,运行之,发现晚上找到的资源里的ini配置文件好多项都已经变化了,只好挨个添加修改,最后总算运行起来。(数据库的版本也对不上,现在只能跑起来玩玩,没有数据)
References:
[1] http://www.ibm.com/developerworks/cn/linux/l-makefile/
声明:本文所使用(涉及)的代码均从互联网上获得,本人没有传播及利用其获取任何商业利益。