版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Acoolbest/article/details/52413725
用autoconf和automake自动生成Makefile
本文是以下面的目录结构阐述Makefile生成及其中遇到的问题,并讲述解决问题的方法
生成Makefile主要需要经历以下几个步骤:
- 运行autoscan命令
- 将configure.scan 文件重命名为configure.ac,并修改configure.ac文件
- 在charge_automake目录下新建Makefile.am文件,并在android_mgr和public_func目录下也新建makefile.am文件
- 在charge_automake目录下新建NEWS、 README、 ChangeLog 、AUTHORS文件
- 运行aclocal命令
- 运行autoconf命令
- 运行autoheader命令
- 运行libtoolize –automake –copy –debug –force命令
- 运行automake –add-missing命令(参数要加,自动加载所需要而缺失的包)
- 运行./confiugre脚本
最主要的工作内容是编写configure.ac和Makefile.am
编写configure.ac
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([android_mgr/src/android_shm_mgr.h])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
AC_CHECK_HEADERS([stdlib.h string.h unistd.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_CHECK_HEADER_STDBOOL
AC_TYPE_INT8_T
AC_TYPE_SIZE_T
AC_TYPE_UINT32_T
AC_TYPE_UINT8_T
# Checks for library functions.
AC_FUNC_MALLOC
AC_CHECK_FUNCS([getcwd memset mkdir strcasecmp strrchr])
AC_OUTPUT
根据实际情况,需要修改几个地方,修改如下:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT(charge, 1.0, acoolbest@163.com)
AC_CONFIG_SRCDIR([android_mgr/src/main.cpp])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([foreign])
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
AC_CHECK_HEADERS([stdlib.h string.h unistd.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_CHECK_HEADER_STDBOOL
AC_TYPE_INT8_T
AC_TYPE_SIZE_T
AC_TYPE_UINT32_T
AC_TYPE_UINT8_T
# Checks for library functions.
#AC_FUNC_MALLOC
AC_CHECK_FUNCS([getcwd memset mkdir strcasecmp strrchr])
AC_PROG_LIBTOOL
AC_CONFIG_FILES([Makefile
android_mgr/Makefile
public_func/Makefile])
AC_OUTPUT
顶层目录的Makefile.am:
AUTOMAKE_OPTIONS = subdir-objects
SUBDIRS=public_func android_mgr
AM_CPPFLAGS=-I$(top_srcdir)
android_mgr目录的Makefile.am:
AM_CFLAGS = $(GLOBAL_CFLAGS) -I$(top_srcdir) -I./src `pkg-config --cflags glib-2.0`
AM_CXXFLAGS = -Wall -g -Wno-write-strings -fpermissive -std=c++11
AUTOMAKE_OPTIONS = subdir-objects
noinst_PROGRAMS=android_control
android_control_SOURCES = \
src/adb_ctrl.cpp \
src/android_mgr.cpp \
src/android_shm_mgr.cpp \
src/main.cpp
android_control_LDADD=$(LIBOBJS) $(ALLOCA) $(top_srcdir)/public_func/libpublic.la $(top_srcdir)/bin/libjson.so
android_control_CFLAGS=$(AM_CFLAGS)
android_control_LDFLAGS=-D_GNU_SOURCE
DEFS+=-D_GNU_SOURCE
LIBS=-lpthread -ldl -lcurl -lsqlite3 -lglib-2.0 -lgthread-2.0 -lssl -lusb-1.0 -lcrypto
public_func目录的Makefile.am
AM_CFLAGS = $(GLOBAL_CFLAGS) -I$(top_srcdir) -I./src `pkg-config --cflags glib-2.0`
AM_CXXFLAGS = -Wall -g -Wno-write-strings -fpermissive -std=c++11
AUTOMAKE_OPTIONS = subdir-objects
noinst_LTLIBRARIES = libpublic.la
libpublic_la_SOURCES = \
src/json_read.cpp \
src/public_function.cpp
libpublic_la_LIBADD=$(LIBOBJS) $(top_srcdir)/bin/libjson.so
libpublic_la_CFLAGS=$(AM_CFLAGS)
LIBS=-lpthread -ldl -lcurl -lsqlite3 -lglib-2.0 -lgthread-2.0 -lssl -lusb-1.0 -lcrypto -shared
在制作Makefile过程中需要注意的问题:
文件介绍:
- README文件,介绍软件包
- INSTALL文件,解释怎样编译、安装软件包
- configure脚本,能使程序自动适应特定平台的特征(或者该平台所缺乏的特性)。configure可以带一个参数–prefix,指定要安装的软件包的位置。标准的make目标,比如clean等等
- COPYING文件,包含软件包的版权信息
- ChangeLog文件,记录了软件的变化
bug1:fatal error: glib.h: 没有那个文件或目录
出现这个问题原因是:编译没有找到glib这个库
解决方案:在对应的Makefile.am文件中AM_CXXFLAGS项增加如下配置
`pkg-config --cflags glib-2.0`
详细解决过程请看:链接
bug2:configure.ac:36: error: required file ‘android_mgr/malloc.c’ not found
出现这个问题的原因是:
在执行autoscan后生成的configure.scan里面配置了AC_FUNC_MALLOC,
配置这项的原因是在android_mgr/src的源码里用到了malloc函数,
解决方案:
AC_FUNC_MALLOC这项东西其实除了会引起报错之外是没有用的(注释掉不会影响编译及运行),只需注释掉即可(在此项前加#即可)
bug3:ltmain.sh’ not found
在linux下编译c/c++程序出错:
$ automake --add-missing
...
configure.in:18: required file `build/ltmain.sh' not found
...
解决方案(libtoolize配置即可):
$libtoolize --automake --copy --debug --force
bug4:public_func/Makefile.am:7: error: ‘libpublic.so’ is not a standard libtool library name did you mean ‘libpublic.la’?
出现这个问题的原因是:
编写public库中Makefile.am文件中有写到noinst_LTLIBRARIES = libpublic.so(动态库习惯用.so作为扩展名)
解决方案:
根据错误提示已经得知,.so不是一个用libtool生成的库的标准名字,需要用.la为扩展名,并且configure.ac里需加上宏AC_PROG_LIBTOOL,表示利用libtool 来自动生成动态库。
详细解决过程请看:链接
bug5:public_func/Makefile.am:8: warning: source file ‘src/json_read.cpp’ is in a subdirectory, but option ‘subdir-objects’ is disabled
出现这个问题的原因是:
编写public库中Makefile.am文件中有写到libpublic_so_SOURCES = \
src/json_read.cpp \
src/public_function.cpp
其中src是子文件夹,但并没有在此Makefile.am中开启子文件选项,所以增加子文件的这个选项即可
解决方案:
在Makefile.am中增加如下语句
AUTOMAKE_OPTIONS = subdir-objects
bug6:/usr/include/c++/5/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
出现这个问题的原因是:
根据错误提示,编译时需要加入-std=c++11或者-std=gnu++11
解决方案:
在Makefile.am中增加如下语句
AM_CXXFLAGS = -std=c++11
————————————————2016-9-2 18:00:36未完待续————————————————
autotool.pdf
automake
autoconf