automake/autoconf入门
作为Linux下的程序开发人员,大家一定都遇到过Makefile,用make命令来编译自己写的程序确实是很方便。一般情况下,大家都是手工写一个简单Makefile,如果要想写出一个符合自由软件惯例的Makefile就不那么容易了。

在本文中,将给大家介绍如何使用autoconf和automake两个工具来帮助我们自动地生成符合自由软件惯例的Makefile,这样就可以象常 见的GNU程序一样,只要使用“./configure”,“make”,“make instal”就可以把程序安装到Linux系统中去了。这将特别适合想做开放源代码软件的程序开发人员,又或如果你只是自己写些小的Toy程序,那么这 个文章对你也会有很大的帮助。

一、Makefile介绍

Makefile是用于自动编译和链接的,一个工程有很多文件组成,每一个文件的改变都会导致工程的重新链接,但是不是所有的文件都需要重新编译,Makefile中纪录有文件的信息,在make时会决定在链接的时候需要重新编译哪些文件。

Makefile的宗旨就是:让编译器知道要编译一个文件需要依赖其他的哪些文件。当那些依赖文件有了改变,编译器会自动的发现最终的生成文件已经过时,而重新编译相应的模块。

Makefile的基本结构不是很复杂,但当一个程序开发人员开始写Makefile时,经常会怀疑自己写的是否符合惯例,而且自己写的 Makefile经常和自己的开发环境相关联,当系统环境变量或路径发生了变化后,Makefile可能还要跟着修改。这样就造成了手工书写 Makefile的诸多问题,automake恰好能很好地帮助我们解决这些问题。

使用automake,程序开发人员只需要写一些 简单的含有预定义宏的文件,由autoconf根据一个宏文件生成configure,由automake根据另一个宏文件生成Makefile.in, 再使用configure依据Makefile.in来生成一个符合惯例的Makefile。下面我们将详细介绍Makefile的automake生成 方法。

二、使用的环境

本文所提到的程序是基于Linux发行版本:redhat,它包含了我们要用到的autoconf,automake。

三、应用

假设源文件按如下目录存放,如图1所示,运用autoconf和automake生成makefile文件:

假设src是我们源文件目录,include目录存放其他库的头文件,lib目录存放用到的库文件,然后开始按模块存放,每个模块都有一个对应的目录,模块下再分子模块,如apple、orange。每个子目录下又分core,include,shell三个目录,其中core和shell目录存放.c文件,include的存放.h文件,其他类似。

首先进入 project 目录,在该目录下运行一系列命令,创建和修改几个文件,就可以生成符合该平台的Makefile文件,操作过程如下:

1) 运行autoscan命令

2) 将configure.scan 文件重命名为configure.in,并修改configure.in文件

3) 在project目录下新建Makefile.am文件,并在core和shell目录下也新建makefile.am文件

4) 在project目录下新建NEWS、 README、 ChangeLog 、AUTHORS文件

5) 运行aclocal命令

6) 运行autoconf命令

7) 运行automake -a命令

8) 运行./confiugre脚本

可以通过图2看出产生Makefile的流程,如图所示:

现在开始介绍详细的过程:

1、建目录

在你的工作目录下建一个testproj目录,在testproj目录下面建立dir1目录:

[root@vm ~]# mkdir testproj testproj/dir1

然后在dir1目录中分别建立code1.c, code1.h, code2.c, code2.h,下面源代码都只由几个简单的语句组成,以便说明问题。

下面是code1.h:

#include <stdio.h>
extern void foo_a();

下面是code1.c:

#include "code1.h"
void foo_a()
{
printf("This is code1.\n");
}

下面是code2.h:

#include <stdio.h>
extern void foo_b();

下面是code2.c,这里让code.c作为prog1的入口点:

#include "code1.h"
#include "code2.h"
void foo_b()
{
printf("This is code2.\n");
}
int main()
{
foo_a();
foo_b();
}

2、生成configure

我们使用autoscan命令来帮助我们根据目录下的源代码生成一个configure.in的模板文件。

[root@vm testproj]# pwd
/root/testproj
[root@vm testproj]# autoscan
[root@vm testproj]# ls
autom4te.cache autoscan.log configure.scan dir1
[root@vm testproj]#

执行后在testproj目录下会生成一个文件:configure.scan,我们可以拿它作为configure.in的蓝本。

现在将configure.scan改名为configure.in,并且编辑它,按下面的内容修改,去掉无关的语句:

[root@vm testproj]# cat configure.scan
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script. AC_PREREQ(2.59)
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AC_CONFIG_SRCDIR([dir1/code1.h])
AC_CONFIG_HEADER([config.h]) # Checks for programs.
AC_PROG_CC # Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions.
AC_OUTPUT
[root@vm testproj]#

configure.in文件为:

[root@vm testproj]# cat configure.in
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script. AC_PREREQ(2.59)
#AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
#AC_CONFIG_SRCDIR([dir1/code1.h])
#AC_CONFIG_HEADER([config.h])
AC_INIT(dir1/code2.c)
AM_INIT_AUTOMAKE(huangcheng, 0.0.1)
# Checks for programs.
AC_PROG_CC # Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions.
AC_OUTPUT([Makefile
dir1/Makefile])
[root@vm testproj]#

#指定项目的一个源文件路径

AC_INIT(dir1/code2.c)

#指定项目名称和版本号

AM_INIT_AUTOMAKE(huangcheng, 0.0.1)

#检查编译器

AC_PROG_CC

#输出Makefile文件

AC_OUTPUT([Makefile     dir1/Makefile])

然后执行命令aclocal和autoconf,分别会产生aclocal.m4及configure两个文件:

[root@vm testproj]# ls
aclocal.m4 autom4te.cache autoscan.log configure.in dir1
[root@vm testproj]# autoconf
[root@vm testproj]# ls
aclocal.m4 autom4te.cache autoscan.log configure configure.in dir1

大家可以看到configure.in内容是一些宏定义,这些宏经autoconf处理后会变成检查系统特性、环境变量、软件必须的参数的shell脚本。

autoconf 是用来生成自动配置软件源代码脚本(configure)的工具。configure脚本能独立于autoconf运行,且在运行的过程中,不需要用户的干预。

要生成configure文件,你必须告诉autoconf如何找到你所用的宏。方式是使用aclocal程序来生成你的aclocal.m4。

aclocal根据configure.in文件的内容,自动生成aclocal.m4文件。aclocal是一个perl 脚本程序,它的定义是:“aclocal - create aclocal.m4 by scanning configure.ac”。

autoconf从configure.in这个列举编译软件时所需要各种参数的模板文件中创建configure。

autoconf需要GNU m4宏处理器来处理aclocal.m4,生成configure脚本。

m4是一个宏处理器。将输入拷贝到输出,同时将宏展开。宏可以是内嵌的,也可以是用户定义的。除了可以展开宏,m4还有一些内建的函数,用来引用文件,执行命令,整数运算,文本操作,循环等。m4既可以作为编译器的前端,也可以单独作为一个宏处理器。

3、新建Makefile.am

在testproj目录下面建立Makefile.am文件:

[root@vm testproj]# cat Makefile.am
SUBDIRS=dir1

在testproj/dir1目录下面建立Makefile.am文件:

[root@vm dir1]# cat Makefile.am
AUTOMAKE_OPTIONS=foreign
bin_PROGRAMS=hc
hc_SOURCES=code1.c code1.h code2.c code2.h

其中:
(1)AUTOMAKE_OPTIONS为设置Automake的选项。由于GNU对自己发布的软件有严格的规范,比如必须附带许可证声明文件COPYING等,否则Automake执行时会报错。Automake提供了3种软件等级:foreign、gnu和gnits,供用户选择,默认等级为gnu。本例使需用foreign等级,它只检测必须的文件。
(2)bin_PROGRAMS定义要产生的执行文件名。如果要产生多个执行文件,每个文件名用空格隔开。
(3)hc_SOURCES定义”hc”这个执行程序所需要的原始文件。如果”hc”这个程序是由多个原始文件所产生的,则必须把它所用到的所有原始文件都列出来,并用空格隔开。例如:若目标体”hc”需要”code1.c”、”code1.h”、”code2.c”、”code2.h”两个依赖文件,则定义hc_SOURCES=code1.c code1.h code2.c code2.h。

automake会根据你写的Makefile.am来自动生成Makefile.in。

Makefile.am中定义的宏和目标,会指导automake生成指定的代码。例如,宏bin_PROGRAMS将导致编译和连接的目标被生成。

4、运行automake

命令:

[root@vm testproj]# automake --add-missing
configure.in: installing `./install-sh'
configure.in: installing `./missing'
dir1/Makefile.am: installing `./depcomp'
Makefile.am: installing `./INSTALL'
Makefile.am: required file `./NEWS' not found
Makefile.am: required file `./README' not found
Makefile.am: required file `./AUTHORS' not found
Makefile.am: required file `./ChangeLog' not found
Makefile.am: installing `./COPYING'

提示没有:NEWS README AUTHORS ChangeLog文件,则:

[root@vm testproj]# touch NEWS README AUTHORS ChangeLog
[root@vm testproj]# automake
[root@vm testproj]# ls
aclocal.m4 autoscan.log configure.in dir1 Makefile.am NEWS
AUTHORS ChangeLog COPYING INSTALL Makefile.in README
autom4te.cache configure depcomp install-sh missing
[root@vm testproj]#

automake会根据Makefile.am文件产生一些文件,包含最重要的Makefile.in。其中testproj和testproj/dir1目录下面都生成Makefile.in。

5、执行configure生成Makefile

[root@vm testproj]# ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
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 ANSI C... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
configure: creating ./config.status
config.status: creating Makefile
config.status: creating dir1/Makefile
config.status: executing depfiles commands

其中testproj和testproj/dir1目录下面都生成Makefile。

6、使用Makefile编译代码

[root@vm testproj]# make
Making all in dir1
make[1]: Entering directory `/root/testproj/dir1'
if gcc -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"huangcheng\" -DVERSION=\"0.0.1\" -I. -I. -g -O2 -MT code1.o -MD -MP -MF ".deps/code1.Tpo" -c -o code1.o code1.c; \
then mv -f ".deps/code1.Tpo" ".deps/code1.Po"; else rm -f ".deps/code1.Tpo"; exit 1; fi
if gcc -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"huangcheng\" -DVERSION=\"0.0.1\" -I. -I. -g -O2 -MT code2.o -MD -MP -MF ".deps/code2.Tpo" -c -o code2.o code2.c; \
then mv -f ".deps/code2.Tpo" ".deps/code2.Po"; else rm -f ".deps/code2.Tpo"; exit 1; fi
gcc -g -O2 -o hc code1.o code2.o
make[1]: Leaving directory `/root/testproj/dir1'
make[1]: Entering directory `/root/testproj'
make[1]: Nothing to be done for `all-am'.
make[1]: Leaving directory `/root/testproj'
[root@vm testproj]#

在/testproj/dir1生成可执行文件:hc,运行hc:

[root@vm dir1]# ./hc
This is code1.
This is code2.

你还可以试着使用一些其 他的make命令,如make clean,make install,make dist等。

(1)在上面的基础上面,如果同时实现code1.c, code2.c生成 prog1, 而 code3.c生成prog2。由于code1.c,code2.c,code3.c都在同一个目录,只要改写dir1目录下的Makefile.am就可以了。

为了便于说明问题,首先要在dir1目录下增加一个code3.h 和code3.c文件。

下面是code3.h:

#include <stdio.h>
void foo_c();

下面是code3.c:

#include "code3.h"
void foo_c()
{
printf("This is code3.\n");
}
int main()
{
foo_c();
return 0;
}

然后修改dir1目录下的Makefile.am文件:

AUTOMAKE_OPTIONS=foreign
bin_PROGRAMS=prog1 prog2
prog1_SOURCES=code1.c code2.c
prog2_SOURCES=code3.c

在testproj目录下面新建一个autogen.sh:

[root@vm testproj]# cat autogen.sh
#!/bin/sh
aclocal
autoconf
automake --add-missing
./configure

然后执行:

[root@vm testproj]# sh autogen.sh
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
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 ANSI C... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
configure: creating ./config.status
config.status: creating Makefile
config.status: creating dir1/Makefile
config.status: executing depfiles commands
[root@vm testproj]#

make之后,在dir1目录下就会同时存在prog1和prog2两个程序。

(2)那么,两个处在不同子目录下的文件如何共同生成一可执行文件呢?一般互相引用的源程序都是放在同一个目录下的,如果要放在不同的目录,可以把要引用的源文件编译成静态库文件。为便于说明问题,准备了如下文件:

在testproj目录下新建dir2目录,保存code4.h和code4.c文件。

下面是code4.h:

#include <stdio.h>
void foo_d();

下面是code4.c:

#include "code1.h"
#include "code4.h"
void foo_d()
{
printf("This is code4.\n");
}
int main()
{
foo_a();
foo_d();
}

修改testproj目录下的configure.in文件。

[root@vm testproj]# cat configure.in
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script. AC_PREREQ(2.59)
#AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
#AC_CONFIG_SRCDIR([dir1/code1.h])
#AC_CONFIG_HEADER([config.h])
AC_INIT(dir2/code4.c)
AM_INIT_AUTOMAKE(huangcheng, 0.0.1)
# Checks for programs.
AC_PROG_CC
AC_PROG_RANLIB
# Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions.
AC_OUTPUT(Makefile dir1/Makefile dir2/Makefile)

#指定项目的一个源文件

AC_INIT(dir2/code4.c)

#指定项目名称和版本号

AM_INIT_AUTOMAKE(huangcheng, 0.0.1)

#检查编译器

AC_PROG_CC

#检查ranlib

AC_PROG_RANLIB

#输出Makefile文件

AC_OUTPUT(Makefile dir1/Makefile dir2/Makefile)

同时修改testproj目录下的Makefile.am文件:

SUBDIRS = dir1 dir2

在dir1目录下修改Makefile.am文件。这时是将code1.c编译成一个不安装(noinst)的静态库文件:

noinst_LIBRARIES=libcode1.a
libcode1_a_SOURCES=code1.c

在dir2目录下添加一个Makefile.am文件:

INCLUDES= -I../dir1
bin_PROGRAMS=prog4
prog4_SOURCES=code4.c
prog4_LDADD=../dir1/libcode1.a

然后执行:autogen.sh

[root@vm testproj]# sh autogen.sh
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
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 ANSI C... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking for ranlib... ranlib
configure: creating ./config.status
config.status: creating Makefile
config.status: creating dir1/Makefile
config.status: creating dir2/Makefile
config.status: executing depfiles commands
[root@vm testproj]#

在testproj、testproj/dir1和testproj/dir2都会生成Makefile.in和Makefile。

在testproj目录下面执行make:

[root@vm testproj]# make
Making all in dir1
make[1]: Entering directory `/root/testproj/dir1'
if gcc -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"huangcheng\" -DVERSION=\"0.0.1\" -I. -I. -g -O2 -MT code1.o -MD -MP -MF ".deps/code1.Tpo" -c -o code1.o code1.c; \
then mv -f ".deps/code1.Tpo" ".deps/code1.Po"; else rm -f ".deps/code1.Tpo"; exit 1; fi
rm -f libcode1.a
ar cru libcode1.a code1.o
ranlib libcode1.a
make[1]: Leaving directory `/root/testproj/dir1'
Making all in dir2
make[1]: Entering directory `/root/testproj/dir2'
if gcc -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"huangcheng\" -DVERSION=\"0.0.1\" -I. -I. -I../dir1 -g -O2 -MT code4.o -MD -MP -MF ".deps/code4.Tpo" -c -o code4.o code4.c; \
then mv -f ".deps/code4.Tpo" ".deps/code4.Po"; else rm -f ".deps/code4.Tpo"; exit 1; fi
gcc -g -O2 -o prog4 code4.o ../dir1/libcode1.a
make[1]: Leaving directory `/root/testproj/dir2'
make[1]: Entering directory `/root/testproj'
make[1]: Nothing to be done for `all-am'.
make[1]: Leaving directory `/root/testproj'
[root@vm testproj]#

testproj/dir1生成code1.o和libcode1.a    testproj/dir2目录下面生成:code4.o和prog4

四、深入浅出

针对上面提到的各个命令,我们再做些详细的介绍。

1、 autoscan

autoscan是用来扫描源代码目录生成configure.scan文件的。autoscan可以用目录名做为参数,但如果你不使用参数的话,那么 autoscan将认为使用的是当前目录。autoscan将扫描你所指定目录中的源文件,并创建configure.scan文件。

2、 configure.scan

configure.scan包含了系统配置的基本选项,里面都是一些宏定义。我们需要将它改名为configure.in

3、 aclocal

aclocal是一个perl 脚本程序。aclocal根据configure.in文件的内容,自动生成aclocal.m4文件。aclocal的定义是:“aclocal - create aclocal.m4 by scanning configure.ac”。

4、 autoconf

autoconf是用来产生configure文件的。configure是一个脚本,它能设置源程序来适应各种不同的操作系统平台,并且根据不同的系统来产生合适的Makefile,从而可以使你的源代码能在不同的操作系统平台上被编译出来。

configure.in文件的内容是一些宏,这些宏经过autoconf 处理后会变成检查系统特性、环境变量、软件必须的参数的shell脚本。configure.in文件中的宏的顺序并没有规定,但是你必须在所有宏的最前 面和最后面分别加上AC_INIT宏和AC_OUTPUT宏。

在configure.ini中:

#号表示注释,这个宏后面的内容将被忽略。

AC_INIT(FILE)

这个宏用来检查源代码所在的路径。

AM_INIT_AUTOMAKE(PACKAGE, VERSION)

这个宏是必须的,它描述了我们将要生成的软件包的名字及其版本号:PACKAGE是软件包的名字,VERSION是版本号。当你使用make dist命令时,它会给你生成一个类似helloworld-1.0.tar.gz的软件发行包,其中就有对应的软件包的名字和版本号。

AC_PROG_CC

这个宏将检查系统所用的C编译器。

AC_OUTPUT(FILE)

这个宏是我们要输出的Makefile的名字。

我们在使用automake时,实际上还需要用到其他的一些宏,但我们可以用aclocal 来帮我们自动产生。执行aclocal后我们会得到aclocal.m4文件。

产生了configure.in和aclocal.m4 两个宏文件后,我们就可以使用autoconf来产生configure文件了。

5、 Makefile.am

Makefile.am是用来生成Makefile.in的,需要你手工书写。Makefile.am中定义了一些内容:

AUTOMAKE_OPTIONS

这个是automake的选项。在执行automake时,它会检查目录下是否存在标准GNU软件包中应具备的各种文件,例如AUTHORS、ChangeLog、NEWS等文件。我们将其设置成foreign时,automake会改用一般软件包的标准来检查。

bin_PROGRAMS

这个是指定我们所要产生的可执行文件的文件名。如果你要产生多个可执行文件,那么在各个名字间用空格隔开。

helloworld_SOURCES

这个是指定产生“helloworld”时所需要的源代码。如果它用到了多个源文件,那么请使用空格符号将它们隔开。比如需要 helloworld.h,helloworld.c那么请写成helloworld_SOURCES= helloworld.h helloworld.c。

如果你在bin_PROGRAMS定义了多个可执行文件,则对应每个可执行文件都要定义相对的filename_SOURCES。

6、 automake

我们使用automake --add-missing来产生Makefile.in。

选项--add-missing的定义是“add missing standard files to package”,它会让automake加入一个标准的软件包所必须的一些文件。

我们用automake产生出来的Makefile.in文件是符合GNU Makefile惯例的,接下来我们只要执行configure这个shell 脚本就可以产生合适的 Makefile 文件了。

7、 Makefile

在符合GNU Makefiel惯例的Makefile中,包含了一些基本的预先定义的操作:

make

根据Makefile编译源代码,连接,生成目标文件,可执行文件。

make clean

清除上次的make命令所产生的object文件(后缀为“.o”的文件)及可执行文件。

make install

将编译成功的可执行文件安装到系统目录中,一般为/usr/local/bin目录。

make dist

产生发布软件包文件(即distribution package)。这个命令将会将可执行文件及相关文件打包成一个tar.gz压缩的文件用来作为发布软件的软件包。

它会在当前目录下生成一个名字类似“PACKAGE-VERSION.tar.gz”的文件。PACKAGE和VERSION,是我们在configure.in中定义的AM_INIT_AUTOMAKE(PACKAGE, VERSION)。

make distcheck

生成发布软件包并对其进行测试检查,以确定发布包的正确性。这个操作将自动把压缩包文件解开,然后执行configure命令,并且执行make,来确认编译不出现错误,最后提示你软件包已经准备好,可以发布了。

==================================================
huangcheng-0.0.1 archives ready for distribution:
huangcheng-0.0.1.tar.gz
==================================================
make distclean

类似make clean,但同时也将configure生成的文件全部删除掉,包括Makefile。

五、结束语

通过上面的介绍,你应该可以很容易地生成一个你自己的符合GNU惯例的Makefile文件及对应的项目文件。

如果你想写出更复杂的且符合惯例的Makefile,你可以参考一些开放代码的项目中的configure.in和Makefile.am文件,比如:嵌入式数据库sqlite,单元测试cppunit。

参考文档:

http://blog.csdn.net/21aspnet/article/details/6724477

http://www.2cto.com/kf/201206/137604.html

http://os.chinaunix.net/a2009/0206/991/000000991405.shtml

http://blog.chinaunix.net/uid-261392-id-2138944.html

http://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/C-Compiler.html

Makefile自动生成的更多相关文章

  1. Makefile自动生成头文件依赖

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

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

    Linux Makefile自动生成--config.h http://blog.csdn.net/spch2008/article/details/12510805

  3. C/C++ makefile自动生成工具(comake2,autotools,linux),希望能为开源做点微薄的贡献!

      序     在linux下C或C++项目开发,Makefile是必备的力气,但是发现手写很麻烦. 在百度有个comake2工具,用于自动生成Makefile工具,而在外边本想找一个同类工具,但发现 ...

  4. makefile自动生成依赖关系

    手工编写依赖关系不仅工作量大而且极易出现遗漏,更新也很难及时,修改源或头文件后makefile可能忘记修改.为了解决这个问题,可以用gcc的-M选项自动生成目标文件和源文件的依赖关系.-M选项会把包含 ...

  5. Makefile 自动生成依赖

    虽然以前对Makefile有个基本概念,但是真正到自己去写一个哪怕是简单的Makefile时也会遇到不少的麻烦.    现在我有如下文件 dList.h dList.c memory.c debug. ...

  6. Makefile自动生成工具-----autotools的使用(详细)

    相信每个学习Linux的人都知道Makefile,这是一个很有用的东西,但是编写它是比较复杂,今天介绍一个它的自动生成工具,autotools的使用.很多GNULinux的的软件都是用它生成Makef ...

  7. Makefile自动生成:cmake

    http://blog.csdn.net/pipisorry/article/details/51647073 编辑makefile文件CMakeLists.txt,使用cmake命令自动生成make ...

  8. makefile自动生成学习

    https://www.cnblogs.com/jrglinux/p/6964169.html 关键是如何写Makefile.am  其他的交给 自动工具完成 添加一个 很好的博客 学习下 https ...

  9. makefile自动生成目标与依赖的关系

    有main.c: #include <stdio.h> #include "command.h" int main(int argc, const char *argv ...

随机推荐

  1. [ Java学习基础 ] 浅析Java方法调用

     先看一个示例,读者可先自行阅读判断输出结果: public class TestClass { private static void testMethod(){ System.out.printl ...

  2. Uva 11400 照明系统

    有一个照明系统需要用到n种灯,每种灯的电压为V,电源费用K,每个灯泡费用为C,需要该灯的数量为L.注意到,电压相同的灯泡只需要共享一个对应的电源即可,还有电压低的灯泡可以被电压高的灯泡替代.为了节约成 ...

  3. SPOJ PHRASES 每个字符串至少出现两次且不重叠的最长子串

    Description You are the King of Byteland. Your agents have just intercepted a batch of encrypted ene ...

  4. Go实现海量日志收集系统(三)

    再次整理了一下这个日志收集系统的框,如下图 这次要实现的代码的整体逻辑为: 完整代码地址为: https://github.com/pythonsite/logagent etcd介绍 高可用的分布式 ...

  5. Thinkphp中的U函数(Thinkphp3.2.3版本)

    U函数的作用是根据当前的URL设置生成对应的URL地址,使用U函数可以确保项目在移植过程中不受环境的影响. U方法的定义规则如下(方括号内参数根据实际应用决定): U('地址表达式',['参数'],[ ...

  6. python中的赋值操作和复制操作

    之前一直写C#,变量之间赋值相当于拷贝,修改拷贝变量不会改变原来的值.但是在python中发现赋值操作本质是和C++中的引用类似,即指向同一块内存空间.下面通过一个例子说明: p=[0,1,2,3,4 ...

  7. C语言程序设计第二次作业1

    (一)改错题 1.输出带框文字:在屏幕上输出以下3行信息. ************* Welcome ************* 源程序 include int mian() { printf(&q ...

  8. Serpent.AI – 游戏代理框架(Python)

    Serpent.AI - 游戏代理框架(Python) Serpent.AI是一个简单而强大的新颖框架,可帮助开发人员创建游戏代理.将您拥有的任何视频游戏变成一个成熟的实验的沙箱环境,所有这些都是熟悉 ...

  9. 用 ConfigMap 管理配置 - 每天5分钟玩转 Docker 容器技术(159)

    Secret 可以为 Pod 提供密码.Token.私钥等敏感数据:对于一些非敏感数据,比如应用的配置信息,则可以用 ConfigMap. ConfigMap 的创建和使用方式与 Secret 非常类 ...

  10. 一口一口吃掉Hibernate(五)——一对多单向关联映射

    版权声明:本文为博主原创文章,未经博主允许不得转载.如需转载请声明:[转自 http://blog.csdn.net/xiaoxian8023 ] 在上一篇博客<一口一口吃掉Hibernate( ...