GNU make允许将一个软件项目的代码分开放在不同的源文件里,有改动的时候可以只对改动的文件重新编译,然后重新连接,这种编译管理方法提高了生成目标的效率。make要调用一个makefile文件来实现。

Makefile的编写是使用make的关键问题。当工程里面包含的很多源文件,库,文件放在不同的子目录时,手动书写makefile文件不方便且容易出错。一般情况下我们用autoconf和automake自动生成makefile文件。

自动生成makefile流程

如图所示为automake,autoconf生成makefile的过程(简化)。

程序源码
                                           |
                                     autoscan*
                                           |
                                configure.scan
                                           |
                                    编译修改*
                                            | 
             makefile.am   configure.in --aclocal*--> aclocal.m4
                           \  ____  /           \  __________  /
                                 \ /                           \ /
                         automake*             autoconf*
                               |                              |
                            makefile.in       configure
                                          \  ____  /

\  /
                                        ./configure*
                                                |
                                          makefile

为一个项目源文件生成makefile并make的步骤如下:

操作在包含源文件的项目目录下进行。

(1). 运行autoscan,生成文件configure.scan。

(2). 修改configure.scan,改名为configure.in。(现在一般都是改为configure.ac)

(3).运行autoheader,扫描configure.ac(或者configure.in) 生成文件configure.h.in。configure.in里有宏AC_CONFIG_HEADER()时用。

(4).运行libtoolize,生成一些支持文件,ltmain.sh。需要用libtool生成共享库用。

(5).运行allocal,生成aclocal.m4。

(6). 运行autoconf,生成configure。

(7).为源文件编写makefie.am,每一个包含源文件的目录和子目录都有一个makefile.am。

(8).运行automake,生成makefile.in,每个包含makefile.am的子目录都生成makefile.in。

automake -a选项可以补齐文件config.guess,config.sub,install-sh,missing,depcomp。

(9).运行./configure,生成config.status,config.h,makefile。

(10).运行make,生成中间文件对象文件,库文件,最后生成可执行文件。

(11).运行make install,相应的可执行文件,库文件,头文件拷贝到系统相应位置。

自动生成makefile例子

这个例子共有三个C文件,main.c,add/add.c和sub/sub.c。源代码如下:

/*main.c*/
#include
int main(void)
{
printf("%d\n",add(sub(100,5),1));
return 0;
}

/* add/add.c */
int add(int x,int y)
{
return x+y;
}

/* sub/sub.c */
int sub(int x,int y)
{
return x-y;
}

这个例子中add.c和sub.c被编译成动态连接库,然后main.c与这两个库连接生成可执行文件。

1.手动输入configure.in和makefile.am

Q:自动生成makefile需要手动输入什么文件,作用是什么?

按照上面的步骤执行,需要手动输入的文件只有两类configure.in和makefile.am。

(1).手动修改configure.in

autoscan运行后configure.scan文件为(系统不一样可能略有会不同)

# -*- Autoconf -*- 
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.63])
AC_INIT([FULL-PACKAGE-NAME],[VERSION],[BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([main.c])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_OUTPUT

手动修改为configure.in:

# -*- Autoconf -*- 
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.63])
AC_INIT(hellobb,1.0,[])
AM_INIT_AUTOMAKE(hellobb,1.0)

AC_CONFIG_SRCDIR([main.c])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC
AC_PROG_LIBTOOL

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_OUTPUT(Makefile add/Makefile sub/Makefile)

其中宏AC_INIT和AC_OUTPUT是必需的,AC_INIT放在开头,AC_OUTPUT放在结尾。

AC_INIT:说明软件包的名字,版本等。

AC_OUTPUT:说明生成的shell脚本文件configure运行后输出的文件。

AM_INIT_AUTOMAKE:用automake需要的宏。

AC_PROG_CC:决定要使用的C编译器。如果环境变量CC没有值,检查gcc和cc,别的C编译器。设置变量CC的值为找到的编译器名称。

AC_PROG_LIBTOOL:检查LIBTOOL。

AC_CONFIG_SRCDIR([main.c]):./configure检查在给它的目录里是否有main.c文件。

AC_CONFIG_HEADER([config.h]):./configure从config.h.in中生成config.h文件,config.h文件是包含了很多#define宏的c头文件。当编译文件的时候,用一个宏-DHAVE_CONFIG_H代替原来需要用-Dmacro传递的所有预处理宏集合。

例如屏蔽掉这句#AC_CONFIG_HEADER([config.h]),make时编译main.c的命令是

gcc -DPACKAGE_NAME=\"hellobb\" -DPACKAGE_TARNAME=\"hellobb\" -DPACKAGE-VERSION=\"1.0\" -DPACKAGE_STRING=\"hellobb\ 1.0\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"hellobb\" -DVERSION=\"1.0\" -DSTDC_HEADERS=1 _DHAVE_SYS_TYPES_H=1 -DHAVE_UNISTDLIB_H=1 -DHAVE_STING_H=1 -DHAVE_MEMORY_H=1 -dHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\"./libs/\" -I. -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.c main.c

如果启用AC_CONFIG_HEADER([config.h]),make时编译main.c的命令是

gcc -DHAVE_CONFIG_H -I. -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c

上面那些宏-Dmacro都包含在config.h里了,我们只需要给编译器传递-DHAVE_CONFIG_H就行了。

(2). 手动输入makefile.am

每个包含源文件的子目录下都需要一个makefile.am。

add/makefile.am是(sub/makefile.am类似):

lib_LTLIBRARIES = libadd.la //生成共享库libadd.la
libadd_la_SOURCES = add.c //共享库libadd.la依赖的源文件

项目根目录下的makefile.am是:

AUTOMAKE_OPTIONS = foreign
SUBDIRS = add sub //子目录,递归处理子目录的makefile.am
bin_PROGRAMS = main //生成可执行文件main
main_SOURCES = main.c //可执行文件main依赖的源文件
main_LDADD = add/libadd.la sub/libsub.la //可执行文件main连接时需要的库文件

(3).automake时运行automake -a:

automake -a即 automake -add-missing:如果目录下缺少文件config.guess,config.sub,missing,depcomp,install-sh,automake会自动从系统中获取这些文件,这里是创建这些文件,让它们是指向系统中对应文件的连接文件。

2.过程中的输入输出文件

Q:./configure需要什么输入文件,生成什么文件?

Q:make需要什么输入文件,中间生成的文件放哪?

为了更清楚整个处理过程autoscan,autoheader,automake,autoconf做了什么事情,观察每一步执行过程中需要的输入文件和产生的输出文件。

输入源文件:main.c add/add.c sub/sub.c

输入makefile.am :makefile.am add/makefile.am sub/makefile.am

autoscan :configure.scan

autoscan.log

手动修改:(入:configure.scan)

configure.in //指出生成的包名字和版本号,./configure输出文件,配置预处理头文件,
指出需要检查的程序、头文件、类型和结构、库函数等。

autoheader :config.h.in

libtoolize :ltmain.sh

aclocal :aclocal.m4 //autoconf相关的宏,在本地m4中定义好的。

autom4te.cache

autoconf : (入:configure.in, aclocal.m4)

configure

automake -a :(入:configure.in makefile.am add/makefile.am sub/makefile.am)

config.guess //猜测出一个规范的系统名字。

config.sub //把平台和系统别名映射成规范形式: 
CPU_TYPE_MANUFACTORER-KERNEL-OPERATING-SYSTEM。

install-sh //安装程序,脚本或数据文件。

missing // Common stub for a few missing GNU program while installing.

depcomp //Compile a program generating depedencies as side-effects.

makefile.in add/makefile.in sub/makefile.in

./configure :(入:configure makefile.in add/makefile.in sub/makefile.in config.h.in )

(入:config.guess config.sub install-sh missing depcomp ltmainsh)

config.status //configure运行时找到的系统相关变量都存放在这里,
./configure的最后就是运行shell脚本config.status

config.h //包含编译时要传给编译器的所有预处理宏

config.log //包含了./configure运行时生成的所有信息,供调试时查看

makefile add/makefile sub/makefile

./deps/main.Po add/.deps/add.Plo sub/.deps.sub.Plo //空的dummy依赖文件

stamp-h1

make :(入:config.status config.h makefile add/makefile sub/makefile)

libtool

add.lo add.o libadd.la

add/.libs下add.o libadd.a libadd.la libsub.lai libadd.so libadd.so.0 libadd.so.0.0.0

sub.lo sub.o libsub.la

sub/.libs下sub.o libsub.a libsub.la libsub.lai libsub.so libsub.so.0 libsub.so.0.0.0

./deps/main.Po add/.deps/add.Plo sub/.deps.sub.Plo //更新依赖文件,由于gcc有-MT,-MD,-MP,-MF选项

main.o

main

3.configure和make执行过程

Q:./configure都作了些什么事情,输入的文件都用来做什么,config.status的作用?

Q:make的运行过程,生成的文件放在哪里有谁来指定?

configure运行

configure是一个shell脚本文件,由autoconf生成,它自动为源码包配置编译连接选项,适应不同的硬件平台和POSIX操作系统,输出所需要的Makefile。

上面的例子中./configure运行期间输出如下图。

configure.in中宏对configure的影响:

宏AC_INIT,AM_INIT_AUTOMAKE,AC_PROG_CC对应图中的白色部分。

宏AC_PROG_LIBTOOL对应图中的灰色部分。

宏AC_OUTPUT在图中的桃红色部分。

桃红色部分为最后configure生成config.status文件,并执行它。configure主管检查你的系统,把结果存放到config.status中,config.status根据它的检查结果实际执行正确的动作。

configure检查与系统相关的一系列变量,这些变量存储到文件config.status中,供makefile调用。这些变量包括编译连接时需要的程序,这些程序在系统中的位置(目录),调用这些程序的选项,比如编译器的目录,编译器的选项-g是否支持等。

configure能猜出它运行的系统的规范名字cpu-vendor-os,它通过运行脚本文件config.guess输出变量uname来猜出。

configure能识别很多系统名字的别名,它通过运行脚本文件config.sub把系统名字变成规范名字。

# ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables... 
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking how to print strings... printf
checking for a sed that does not truncate output... /bin/sed
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for fgrep... /bin/grep -F
checking for ld used by gcc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1966080
checking whether the shell understands some XSI constructs... yes
checking whether the shell understands "+="... yes
checking for /usr/bin/ld option to reload object files... -r
checking for objdump... objdump
checking how to recognize dependent libraries... pass_all
checking for ar... ar
checking for strip... strip
checking for ranlib... ranlib
checking command to parse /usr/bin/nm -B output from gcc object... ok
checking how to run the C preprocessor... gcc -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for dlfcn.h... yes
checking for objdir... .libs
checking if gcc supports -fno-rtti -fno-exceptions... no
checking for gcc option to produce PIC... -fPIC -DPIC
checking if gcc PIC flag -fPIC -DPIC works... yes
checking if gcc static flag -static works... no
checking if gcc supports -c -o file.o... yes
checking if gcc supports -c -o file.o... (cached) yes
checking whether the gcc linker (/usr/bin/ld) supports shared libraries... yes
checking whether -lc should be explicitly linked in... no
checking dynamic linker characteristics... GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating add/Makefile
config.status: creating sub/Makefile
config.status: creating config.h
config.status: executing depfiles commands
config.status: executing libtool commands

make运行

make运行期间输出如下图。

makefile.am对makefile的影响:

它根据SUBDIRS = add sub让make递归进入每个子目录处理子目录的Makefile。

根据main_LDADD = add/libadd.la sub/libsub.la为main连接libadd.la和libsub.la库。

configure.in对makefile的影响:

根据AC_PROG_LIBTOOL让libtool完成编译连接工作。

根据AC_CONFIG_HEADERS([config.h])只需传递预处理宏-DHAVE_CONFIG_H给编译器。

makefile中很多与系统相关的信息都是通过变量获取的,这些变量之前已经由configure检查好存放在config.status里面,预处理宏存放在config.h里面。比如我们要用到的编译器CC,编译器选项CFLAGS等。makefile中的变量完成替换后,开始实际执行命令,它会递归执行每一个子目录下的makefile,生成对象文件,连接库文件,最后连接成可执行文件。

# make
make all-recursive
make[1]: Entering directory `/root/program/hello_autoconf2'
Making all in add
make[2]: Entering directory `/root/program/hello_autoconf2/add'
/bin/sh ../libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -g -O2 -MT add.lo -MD -MP -MF .deps/add.Tpo -c -o add.lo add.c
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -g -O2 -MT add.lo -MD -MP -MF .deps/add.Tpo -c add.c -fPIC -DPIC -o .libs/add.o
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -g -O2 -MT add.lo -MD -MP -MF .deps/add.Tpo -c add.c -o add.o >/dev/null 2>&1
mv -f .deps/add.Tpo .deps/add.Plo
/bin/sh ../libtool --tag=CC --mode=link gcc -g -O2 -o libadd.la -rpath /usr/local/lib add.lo 
libtool: link: gcc -shared .libs/add.o -Wl,-soname -Wl,libadd.so.0 -o .libs/libadd.so.0.0.0
libtool: link: (cd ".libs" && rm -f "libadd.so.0" && ln -s "libadd.so.0.0.0" "libadd.so.0")
libtool: link: (cd ".libs" && rm -f "libadd.so" && ln -s "libadd.so.0.0.0" "libadd.so")
libtool: link: ar cru .libs/libadd.a add.o
libtool: link: ranlib .libs/libadd.a
libtool: link: ( cd ".libs" && rm -f "libadd.la" && ln -s "../libadd.la" "libadd.la" )
make[2]: Leaving directory `/root/program/hello_autoconf2/add'
Making all in sub
make[2]: Entering directory `/root/program/hello_autoconf2/sub'
/bin/sh ../libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -g -O2 -MT sub.lo -MD -MP -MF .deps/sub.Tpo -c -o sub.lo sub.c
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -g -O2 -MT sub.lo -MD -MP -MF .deps/sub.Tpo -c sub.c -fPIC -DPIC -o .libs/sub.o
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -g -O2 -MT sub.lo -MD -MP -MF .deps/sub.Tpo -c sub.c -o sub.o >/dev/null 2>&1
mv -f .deps/sub.Tpo .deps/sub.Plo
/bin/sh ../libtool --tag=CC --mode=link gcc -g -O2 -o libsub.la -rpath /usr/local/lib sub.lo 
libtool: link: gcc -shared .libs/sub.o -Wl,-soname -Wl,libsub.so.0 -o .libs/libsub.so.0.0.0
libtool: link: (cd ".libs" && rm -f "libsub.so.0" && ln -s "libsub.so.0.0.0" "libsub.so.0")
libtool: link: (cd ".libs" && rm -f "libsub.so" && ln -s "libsub.so.0.0.0" "libsub.so")
libtool: link: ar cru .libs/libsub.a sub.o
libtool: link: ranlib .libs/libsub.a
libtool: link: ( cd ".libs" && rm -f "libsub.la" && ln -s "../libsub.la" "libsub.la" )
make[2]: Leaving directory `/root/program/hello_autoconf2/sub'
make[2]: Entering directory `/root/program/hello_autoconf2'
gcc -DHAVE_CONFIG_H -I. -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
mv -f .deps/main.Tpo .deps/main.Po
/bin/sh ./libtool --tag=CC --mode=link gcc -g -O2 -o main main.o add/libadd.la sub/libsub.la 
libtool: link: gcc -g -O2 -o .libs/main main.o add/.libs/libadd.so sub/.libs/libsub.so -Wl,-rpath -Wl,/usr/local/lib
make[2]: Leaving directory `/root/program/hello_autoconf2'
make[1]: Leaving directory `/root/program/hello_autoconf2'

Q: 编译main.c的命令:gcc -DHAVE_CONFIG_H -I. -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c 中,选项-MT,-MD,-MP,-MF什么意思?

选项-MT,-MD,-MP,-MF是跟依赖关系文件相关的,相当于往文件里加makefile格式的rule,简化形式:
targets : dependency。
-MF .deps/main.Tpo 指定把依赖关系的rule写到文件.deps/main.Tpo 里,跟-MD一起用,如果跟-M一起用将在预处理后结束不编译。
-MT 指定target。
-MP 在依赖关系文件中加入每个依赖文件的phony target。如
test.o:test.c test.h
test.h: #phony target

这里生成的依赖文件main.Po,add.Plo如图。

main.Po:

main.o: main.c /usr/include/stdio.h /usr/include/features.h \
/usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \
/usr/include/gnu/stubs.h /usr/include/gnu/stubs-32.h \
/usr/lib/gcc/i686-redhat-linux/4.5.1/include/stddef.h \
/usr/include/bits/types.h /usr/include/bits/typesizes.h \
/usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \
/usr/lib/gcc/i686-redhat-linux/4.5.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h

/usr/include/stdio.h:
/usr/include/features.h:
/usr/include/sys/cdefs.h:
/usr/include/bits/wordsize.h:
/usr/include/gnu/stubs.h:
/usr/include/gnu/stubs-32.h:
/usr/lib/gcc/i686-redhat-linux/4.5.1/include/stddef.h:
/usr/include/bits/types.h:
/usr/include/bits/typesizes.h:
/usr/include/libio.h:
/usr/include/_G_config.h:
/usr/include/wchar.h:
/usr/lib/gcc/i686-redhat-linux/4.5.1/include/stdarg.h:
/usr/include/bits/stdio_lim.h:
/usr/include/bits/sys_errlist.h:
/usr/include/bits/stdio.h:

add.Plo:

add.lo: add.c

交叉编译 Cross-compiling

Q:为别的平台编译可执行程序怎么做?

交叉编译就是在目前的平台上为别的目标平台生成可执行程序或库。可以在运行configure时通过--build,--host,--target参数实现交叉编译。默认情况下 target<=host<=build<=config.guess给出的平台名称。

例如./configure --build=i686-pc-linux-gnu --host=m68k-coff。

--build=build-type :configure和compile软件包的系统类型。默认情况等于config.guess给出的系统类型。

--host=host-type :运行软件包的系统类型。默认情况等于build类型

--target=target-type :很少用,默认情况等于host类型。

交叉编译时,如果编译器,连接器,汇编器名字不是以host_type为前缀,configure都会发出警告。

要搭建交叉变异环境,如交叉编译用的编译器,连接器,汇编器跟本地的不一样,一般以host_type为前缀,如arm-pc-linux-gcc。

安装目录

Q:make install时,文件都安装到哪里去了?

prefix:安装目录的前缀。默认情况下/usr/local 。

bindir:安装时拷贝可执行文件到此目录。默认情况下/usr/local/bin 。

includir:安装时拷贝头文件到此目录。默认情况下/usr/local/include 。

libdir:安装时拷贝库文件到此目录。默认情况下/usr/local/libs 。

定制自己的安装目录,可以--prefix 和 --exec-prefix 给configure。

例如:./configure --prefix=/usr 。

GUN build system

autoconf

automake

libtool

autoheader

检查你的系统安装了以下软件:(whereis ,which)

GNU gcc 
GNU make 
GNU automake 
GNU Autoconf 
GNU m4 
perl 
GNU tar 
GNU zip ( gzip )

GNU Libtool ( 如果你需要產生 shared library )

补充:因项目需要我需要讲一个大型项目重新编译并增加一部分自己的代码,步骤如下:

1、在工程的某个路径下新建一个文件夹(根据自己实际情况),把相应的代码文件(包括源文件和头文件)放到此文件夹下,新建一个Makefile.am文件,格式如下:

表一列出了可执行文件、静态库、头文件和数据文件,四种书写Makefile.am文件个一般格式。

表 1Makefile.am一般格式

对于可执行文件和静态库类型,如果只想编译,不想安装到系统中,可以用noinst_PROGRAMS代替bin_PROGRAMS,noinst_LIBRARIES代替lib_LIBRARIES。

Makefile.am还提供了一些全局变量供所有的目标体使用:

表 2 Makefile.am中可用的全局变量

在Makefile.am中尽量使用相对路径,系统预定义了两个基本路径:

表 3Makefile.am中可用的路径变量

2、父目录中的Makefile.am 要包含子目录的Makefile.am,即在父目录中的Makefile.am 中SUBDIRS增加子目录名称 。(生成的共享库如果被引用也要修改相应的Makefile.am文件)。

3、修改configure.ac文件

3.1、AC_CONFIG_FILES宏,这个宏的作用是在执行autoconf命令之后输出的文件,一般是Makefile文件,例如:

AC_CONFIG_FILES(
  Makefile
  doxygen.cfg

_CUSTOM_ASN1_AC_OUTPUT_

plugins/stats_tree/Makefile

plugins/transum/Makefile

plugins/unistim/Makefile
  plugins/wimax/Makefile
  plugins/wimaxasncp/Makefile
  plugins/wimaxmacphy/Makefile
  randpkt_core/doxygen.cfg
  randpkt_core/Makefile
  tools/Makefile
  tools/lemon/Makefile
  wiretap/Makefile
  writecap/Makefile
  writecap/doxygen.cfg
  wsutil/Makefile
  _CUSTOM_AC_OUTPUT_
)

4、执行automake -a 命令。然后查看是否生成相应的Makefile.in文件。

5、调用autoconf,利用M4解析configure.ac,生成configure。

6、然后./configure生成Makefile文件。

7、最后执行make命令即可。

编译安装时常见错误:

1.error

configure.in:7: version mismatch.  This is Automake 1.9.6,
configure.in:7: but the definition used by this AM_INIT_AUTOMAKE
configure.in:7: comes from Automake 1.9.5.  You should recreate
configure.in:7: aclocal.m4 with aclocal and run automake again.

解决方法

$aclocal

$automake

将重新生成makefile文件

2.[root@localhost src]# ./configure
-bash: ./configure: No such file or directory

[root@localhost src]# aclocal
aclocal: `configure.ac' and `configure.in' both present.
aclocal: proceeding with `configure.ac'.

[root@localhost src]# autoconf
autoconf: warning: both `configure.ac' and `configure.in' are present.
autoconf: warning: proceeding with `configure.ac'.

root@localhost src]# ./configure
checking which defines needed for makedepend... 
checking for a BSD-compatible install... /usr/bin/install -c

aclocal, autoconf, 之后可以正常运行./configure了

3.

+ autoreconf --install
configure.ac:32: warning: macro 'AM_PROG_LIBTOOL' not found in library
configure.ac:32: error: possibly undefined macro: AM_PROG_LIBTOOLIf this token and others are legitimate, please use m4_pattern_allow.See the Autoconf documentation.
autoreconf: /usr/bin/autoconf failed with exit status: 1

autoreconf -fvi to make sure everything is updated.

4.

configure.ac:10: error: possibly undefined macro: AC_PROG_LIBTOOL
      If this token and others are legitimate, please use m4_pattern_allow.See the Autoconf documentation.
autoreconf: /usr/bin/autoconf failed with exit status: 1
apt-get install libtool

5.

$ sudo pacman -S pkg-config xorg-server-devel libtool automake
$ libtoolize --forceConsider adding AC_CONFIG_MACRO_DIR([m4]) to configure.ac
and re-run libtoolize --force.$ vim configure.ac
$ libtoolize --force
$ aclocal
$ autoheader
$ automake --force-missing --add-missing
$ autoconf

6. ./configure: line 17661: syntax error near unexpected token `HARFBUZZ,'

slove: aclocal /usr/pkg-config-0.25/share/aclocal --install

7.[root@localhost src]# ./autogen.sh
which: no gtkdocize in (/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin)
*** No GTK-Doc found, please install it ***

8.[root@localhost src]# libtoolize
-bash: libtoolize: command not found

export PATH='/path/to/libtool/bin'

makefile是如何自动生成的相关推荐

  1. 自动生成Makefile的全过程详解

    automake/autoconf入门 作为Linux下的程序开发人员,大家一定都遇到过Makefile,用make命令来编译自己写的程序确实是很方便.一般情况下,大家都是手工写一个简单Makefil ...

  2. 自动生成 Makefile 的全过程详解

    2019独角兽企业重金招聘Python工程师标准>>> automake/autoconf  入门 作为 Linux  下的程序开发人员,大家一定都遇到过 Makefile  ,用 ...

  3. ./configure 自动生成makefile

    新建helloworld目录,里边有一个源码文件helloworld.c. $ autoscan  $ ls  configure.scan helloworld.c 新生成的文件configure. ...

  4. vi下Makefile的自动生成

    首先来说一个比较简单的编译Linux下C++的方法. 我们在文本编辑器里写一个C的简单的程序(好像所有学习C或者C++的书都会出现) 代码: #include <stdio.h> int ...

  5. 使用Linux auto Makefile自动生成的运行步骤

    首先创建一个 Linux Makefile.am.这一步是创建Linux Makefile很重要的一步,automake要用的脚本配置文件是Linux Makefile.am,用户需要自己创建相应的文 ...

  6. Makefile 7——自动生成依赖关系 三颗星

    后面会介绍gcc获得源文件依赖的方法,gcc这个功能就是为make而存在的.我们采用gcc的-MM选项结合sed命令.使用sed进行替换的目的是为了在目标名前加上"objs/"前缀 ...

  7. linux清除configure文件_在Linux操作系统下自动生成Makefile的方法

    在Linux操作系统下进行开发,编写Makefile似乎是不可缺少的事情.但是对于一个比较大的工程,编写一个符合规范的Makefile并非易事.而且由于Makefile的各种显式,隐式规则,加之平时并 ...

  8. Makefile之自动生成依赖(8)

    Makefile自动生成头文件依赖是很常用的功能,本文的目的是想尽量详细说明其中的原理和过程. Makefile模板 首先给出一个本人在小项目中常用的Makefile模板,支持自动生成头文件依赖. C ...

  9. linux系统中自动生成snap文件_在Linux操作系统下自动生成Makefile的方法

    在Linux操作系统下进行开发,编写Makefile似乎是不可缺少的事情.但是对于一个比较大的工程,编写一个符合规范的Makefile并非易事.而且由于Makefile的各种显式,隐式规则,加之平时并 ...

  10. Linux Makefile自动生成--config.h

    2019独角兽企业重金招聘Python工程师标准>>> Linux Makefile自动生成--总体流程 Linux Makefile自动生成--实例 Linux Makefile自 ...

最新文章

  1. pip经常的使用技巧
  2. mysql delete in死锁_mysql 执行delete引发死锁问题
  3. flex 下对齐_flex布局
  4. 【利用存储过程和三层架构完成新闻发布】
  5. 454. 四数相加 ||
  6. Java 8 Stream.distinct() 列表去重示例
  7. (转)LIB和DLL的区别与使用
  8. paip.程序设计--扫号器跑号器结果分类设计
  9. html图片加载慢的问题
  10. SpringBoot的yml配置文件(三)
  11. 如何在Mac上释放内存?Mac清除RAM教程
  12. shell之数学运算
  13. gradle系列-1-gradle -x test clean build
  14. 【文件包含漏洞-03】文件包含漏洞的利用及如何利用本地文件包含漏洞GetShell
  15. c++OntheWay-debug
  16. 图片处理-图片在计算机的显示
  17. 用SQL语句查看Oracle数据表的结构信息
  18. 鼠标点计算机里面文件有声音怎么办,如何消除鼠标点击的声音
  19. error: VNDK library: liblog‘s ABI has EXTENDING CHANGES Please check compatiblity report at
  20. Python+Django毕业设计学校旧书交易网站(程序+LW+部署)

热门文章

  1. 使用Python实现一个简单的聊天室
  2. 论文相关-MATHTYPE字体对应
  3. 【GitHub前端练手项目--50天50个项目---商品加载效果-----day08】
  4. DruidDataSource
  5. 语音服务器搭建,教你自建团队语音服务器
  6. 部分主流视频网站下载方法
  7. 《大秦帝国之裂变》感悟与经典语录
  8. 好扑科技技术副总裁戎朋:从海豚浏览器服务器端研发主管到区块链,揭秘区块链技术之路...
  9. Python 简单的爬虫爬取网页框架(爬取网页框架+实例)
  10. HP台式机安装WIN10