一直听说自动生成Makefile很好用,也很简单,没有实际使用过心里一直没底,而且期间看过几次自动生成过程,网上文章都是只有一个hello.c的实例,而工作中大多都是以多层目录存在的多个源程序的项目,这该如何去自动生产Makefile呢?
由于最近工作需要,编一个静态库,涉及到多层目录,多个源程序,自己手动编写太复杂了,而且需要把源程序与头文件放在相同目录下,这很不便于管理,所以专门花了一上午时间来钻研自动生成Makefile过程,然后也实际实行生成过程,发现多个源程序也和一个大体相同,只是在写Makefile.am的时候需要点考究。废话不多说下面是我根据项目自动生成的过程。
目录结构如下:
--Libs
--google.c
--google_map.c
--baidu
--baidu.c
--baidu_map.c
………………
--Include(存放所有头文件)
自动生成Makefile的软件一般linux系统都自带着有,如果没有用yum或者apt-get安装一下就行了。
(1)在Libs目录下运行autoscan,会在该目录下生成configure.scan,将configure.scan 修改为configure.in,编辑configure.in
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.63])
AC_INIT()//此处根据实验可以不填
AM_INIT_AUTOMAKE(xxx, 1.0)//xxx代表随便命名
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
AC_PROG_RANLIB
# Checks for header files.
AC_HEADER_RESOLV
AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h mntent.h netdb.h netinet/in.h nlist.h stdint.h stdlib.h string.h strings.h sys/file.h sys/mount.h sys/param.h sys/socket.h sys/statvfs.h sys/time.h sys/timeb.h sys/vfs.h syslog.h unistd.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_TYPE_UINT32_T
# Checks for library functions.
AC_FUNC_FORK
AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_CHECK_FUNCS([alarm atexit clock_gettime dup2 gethostbyaddr gethostbyname gettimeofday inet_ntoa memmove memset mkdir putenv select socket strchr strdup strerror strrchr strstr])
AC_OUTPUT(Makefile)
(2)运行aclocal
(3)autoconf会生成configure,此用于生成Makefile
(4)此时还不能生成Makefile,还需要编写一个很重要的Makefile.am,生成Makefile全靠他了,不要害怕,这个编写很简单的。
## Process this file with automake to produce Makefile.in
noinst_LIBRARIES = libproject.a //noinst_LIBRARIES 貌似就是静态库目标文件别名,lib为前缀必须要有
libproject_a_SOURCES = \ //libproject_a_xxx也是必须的
Libs/google/google.c \
Libs/google/google_map.c \
Libs/baidu/baidu.c \
Libs/baidu/baidu_map.c \
libproject_a_CFLAGS = -Wall
INCLUDES=-I$(top_builddir)/include
AUTOMAKE_OPTIONS=foreign
(5)执行automake --add-missing
如果遇到library used but `RANLIB' is undefined,在configure.in必须要有AC_PROG_RANLIB
(6)执行./configure,就生成了Makefile了。
(7)还是make一下看下效果,注意:编译后,使用clean命令,可能会删除不干净.o文件,这需要小小的修改一下clean,删除没有清楚干净的.o文件