makefile是如何自动生成的

2023-11-17

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/Makefil
e
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一般格式
表 1Makefile.am一般格式

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

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

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

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

表 3Makefile.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_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

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 --force

Consider 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'


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

makefile是如何自动生成的 的相关文章

  • [NOI 2015复习][BZOJ 1509][NOI 2003]逃学的小孩(树的直径)

    题目链接 http www lydsy com JudgeOnline problem php id 1509 题目大意 要从一棵树中找出三个点 X Y Z X Y Z 使得 min dis A C dis B C dis A B min
  • STM32超声波模块测距串口输出/通用定时器中断并输出PWM控制舵机/系统定时器延时

    参考 stm32 超声波模块 原理 实现测距 舵机使用 作者 点灯小哥 发布时间 2021 03 10 19 37 16 网址 https blog csdn net weixin 46016743 article details 1146
  • 利用Albumentations工具包进行图像的数据增强(以yolo数据标注格式为例)

    最近在看数据增强方法时 看到了这个有趣的工具包 研究了下并以yolo数据标注格式为例写了一个示例脚本 该工具最大的好处是会根据你使用的数据增强方法自动修改标注框信息 import albumentations as A import cv2
  • MySQL 数据类型

    整数类型 分类 类型 字节 范围 整数类型 TINYINT 1 128 127 SMALLINT 2 32768 32767 MEDIUMINT 3 8388608 8388607 INT INTEGER 4 2 31 2 31 1 BIG
  • JAVA数据库连接总结

    1 Oracle8 8i 9i数据库 thin模式 Class forName oracle jdbc driver OracleDriver newInstance String url jdbc oracle thin localhos
  • libuv异步文件读写

    libuv 异步文件读写 一 libuv编译环境 1 可查看另一篇 libuv 介绍与编译 http mp blog csdn net postedit 79193274 程序代码 include
  • 2022-04-30 Unity核心2——Sprite

    文章目录 一 Single 图片编辑 二 Multiple 图片编辑 三 Polygon 多边形编辑 四 Sprite Renderer 精灵渲染器 五 Sprite Creator 精灵创造者 六 Sprite Mask 精灵遮罩 七 S
  • Python语言基础—注释的作用及分类

    系列文章目录 Python语言基础 注释的作用及分类 Python语言基础 常用运算符总结 Python语言基础 定义变量与数据类型 Python语言基础 if判断和循环总结 Python语言基础 理解面向对象 Python语言基础 集合的
  • 学习之-Spring Cache缓存框架应用本地缓存

    此文章用于个人学习记录 原文地址 https zhuanlan zhihu com p 452315531 如果想了解springCache与redis的交互请看其他文章 缓存是web项目不可或缺的一部分 通过缓存能够降低服务器数据库压力
  • AIX logging

    复杂度2 5 机密度3 5 最后更新2021 05 15 AIX有很多log 不同的东西 程序 会log到不同的地方 这是有历史的操作系统无法避免的问题 太杂 太乱 有了新机制又要学 旧log又没法简单放弃或者改变 经由alog管理 查看
  • 假设在一个32位little endian的机器上运行下面的程序,结果是多少?

    假设在一个32位little endian的机器上运行下面的程序 结果是多少 假设在一个 32 位 little endian 的机器上运行下面的程序 结果是多少 include
  • 【每日进步一点点】C语言刷题技巧及训练1

    恭喜你发现宝藏 这里是刹那芳间 很高兴为您服务 C语言编程题 相信很多同学学校的C语言考试是上机做编程题叭 不要慌 这里将带你进行一个初步的入门 进行一些简单的编程题练习 Anyway 请一定要去多多实践 上机操作 还有 望具备空杯心态 这
  • React(五)- React组件的组合使用

    React 五 React组件的组合使用 一 Todo案例 1 1 组件的具体实现 1 1 1 Header 1 1 2 List 1 1 3 Item 1 1 4 Footer 1 2 父类App组件的实现 二 Todo案例的总结 Rea
  • opencv形态学操作

    连通性 在图像中 最 的单位是像素 每个像素周围有8个邻接像素 常 的邻接关系有3 种 4邻接 8邻接和D邻接 分别如下图所示 4邻接 像素p x y 的4邻域是 x 1 y x 1 y x y 1 x y 1 N p 表示像素p的4邻接
  • GRE隧道实验

    AR1 interface GigabitEthernet0 0 0 进入接口 ip address 10 1 12 1 255 255 255 0 ospf enable 200 area 0 0 0 200 AR2 interface
  • vue中使用百度webgl地图以及踩坑记录

    前言 在公司项目中 之前使用的是vue baidu map库 功能上使用暂无太大问题 最近需要在项目基础上添加一个大屏数据页面 并涉及到换肤功能 就是在换肤这里遇到了一些坑 使用个性化主题之后 出现 地图加载卡顿 白色方块 图层缩放最大等级
  • Windows使用模拟器启动AOSP源码编译的镜像

    正常情况下 源码编译后可直接执行emulator 启动编译好的镜像 但是如果使用的是server版的ubuntu系统 没有图形界面 或者WSL编译的源码 以及我当前情况 AMD CPU Hyper V ubuntu intel CPU好像没
  • 多线程之创建工作者线程和用户界面线程区别

    转帖 部分原创 1 工作者线程倾向于琐碎的处理 与它不同的是 用户界面线程具有自己的界面而且实际上类似于运行其他应用程序 创建线程而不是其他应用程序的好处是线程可与应用程序共享程序空间 这样可以简化线程与应用程序共享数据的功能 2 典型情况
  • 房产小程序需要加入哪些功能才能让用户喜欢?

    对于我们中国人来说 买房子可是一件大事 在以前大家购买房子需要到楼盘所在地了解 而现在互联网高速发展 人们足不出户通过微信小程序就可以了解各个地区的楼盘信息 这样确实节省下来不少时间 不过不是所有房产小程序都会让用户们喜欢 小程序需要加入合
  • Linux配置了环境变量JAVA仍然是openjdk

    问题描述 不使用openjdk 使用jdk 下载完后 也配置了环境变量 反复检查 etc profile bashrc 均没有错误 但是java version仍旧是openjdk 解决方案 需要删除 usr bin下的java文件

随机推荐

  • 趣图:太真实,程序员调 Bug 的写照

    点击上方公众号快速关注 不错过趣图 程序员调 Bug 的样子 非常真实 动图原作者是 我的邻居全是猫 网友评论 中国有圣人 哈哈哈 太形象了 最后干脆撂挑子不干了 破罐破摔了 她叫小明 所以发明回溯这个超能力的这个公司应该每年花一天专门纪念
  • GPT时代,是否还愿意将你的代码开源呢?

    日常 只是偶发的想法 仅供讨论 GPT是生成式AI 生成式的前提也是基于大量的学习资源 如果你的代码开源或者进入到大模型的学习库 GPT的能力可以迅速学习并掌握你的代码 GPT可以将你的代码提供给其他人 这个过程基本没有任何成本 也无需遵循
  • 安卓实现登录与注册界面

    使用Intent与Bundle传递数据 登录界面login xml 1 使用Relativelayout相对布局
  • canvas绘制随机颜色的柱形图

  • mysql修改表的编码为utf-8,解决插入中文乱码

    在创建mysql的表中如果没有指定编码默认为Iatin1 这个时候插入中文就会报错 需要修改表的编码为utf 8 修改表的编码的sql语句为在Alter table emp convert to character set utf8 这样就
  • Error: Rpmdb checksum is invalid: pkg checksums

    从字面意思判断是rpm库校验失败或者损坏 yum clean all yum makecache 搞定 经查询 RUN rpm rebuilddb命令可以一条条修复rpm 还是我的方法好
  • 数据软件分析(一)——静态分析

    基于恶意科学的数据软件分析 将学习本书的过程作记录分享 数据科学是一个不断增长的算法工具集合 可以让我们通过使用统计学 数学和巧妙的统计数据可视化技术来理解和预测数据 一般来说 数据科学有三个组成部分 机器学习 数据挖掘和数据可视化 第一章
  • 从零开始实现基于go-zero框架的微服务电商项目(二)——User服务的基础搭建

    从零开始实现基于go zero框架的微服务电商项目 二 User服务的基础搭建 项目地址 liuxianloveqiqi XianShop 使用go zero搭建的电商项目 github com API 首先在api包下新建user api
  • SQL中字符串截取、连接、替换等函数的用法

    一 SQL中SUBSTRING函数的用法 1 功能 返回字符 二进制 文本或图像表达式的一部分 2 语法 SUBSTRING expression start length 3 QL 中的 substring 函数是用来抓出一个栏位数据中的
  • OpenVSwitch简介

    本文主要介绍Open VSwitch 虚拟交换机的概述内容 阅读本文可以对OVS Open VSwitch 有一个大致的了解 那么本文主要回答了这样几个问题 1 虚拟交换机是什么 干什么 2 虚拟网络和OVS 3 OVS的组件有哪些 4 使
  • 华为OD德科面试+机试记录

    一 机试 6 25 三道编程题 难度偏中 由于时间久远 只记得其中两道题目 1 找车位 动态规划 2 题目不记得了 后面如果找到会补充 双指针 3 高效的任务规划 动态规划 第一题和第二题是做出来了 第三题做出来一点点 当时时间不够 没想出
  • ATT&CK - 入门

    20200922 0 引言 这篇文章记录ATT CK的一些材料阅读 不过题目没有非常明确 因为这部分仅仅是记录了一篇文章 不过这篇文章是一系列文章的第一小节 大题目就是Getting Started的部分 所以 这篇文章就命名为入门 1 A
  • matlab运行代码计时

    tic 此处写的是你自己的代码 times toc disp times
  • 链表查重(递归实现)

    链表查重 递归实现 最开始想到的递归方法 初步估计效率不会太高 但是代码比较容易理解 思路 现在有一个无序的链表 在不清楚元素个数的情况下 无法常规的迭代实现查重 迭代也可以做 且效率较高 我首先想到是否可用递归实现 递归的思路是 从表头元
  • 对数损失和交叉熵损失

    从上述的表达式中看 两者的损失函数本质是一样的 但是这里需要注意的是通常情况下 这两种损失函数所对应的上一层结构不同 log loss经常对应的是Sigmoid函数的输出 用于二分类问题 而cross entropy loss经常对应的是S
  • Linux c获取任意路径的硬盘使用情况

    没有什么好说的 其实就是获取硬盘的statfs信息结构 代码如下 include
  • 利用opencv检测移动的物体----mog2()

    检测移动的物体 opencv具有一个函数是mog2 参考链接 https www jb51 net article 143527 htm
  • ​TinyLlama-1.1B:从零开始训练一个精悍的语言模型

    PaperWeekly 原创 作者 StatNLP 单位 新加坡科技设计大学 TinyLlama 项目旨在在 3 万亿 tokens 上进行预训练 构建一个拥有 11 亿参数的 Llama 模型 经过精心优化 我们 仅 需 16 块 A10
  • java-性能&故障分析工具

    java 性能 故障分析工具 突然想起了 对HR小姐姐的承诺 你要是问我是不是为了福利 我是打死不会承认的 我们公司的技术栈以java居多 那就介绍一下之前自己写的一个性能 故障分析工具吧 也希望能对公司的java开发者有一点点帮助吧 居然
  • makefile是如何自动生成的

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