嵌入式开发之configure

news2024/9/23 13:19:29

1 前述

在Linux的应用或者驱动开发过程中,编写makefile是无法避免的问题,但是由于makefile的各种规则,或显式,或隐式,非常多,不经常写的话,很难写出一个可用的makefile文件。为了“偷懒”,社区上出现了一些可以自动生成makefile的工具,比如cmake,比如autotools,cmake在其他地方了解,这里先了解下autotools工具。

2 详细过程

通过autotools生成makefile文件的流程图如下:
在这里插入图片描述

2.1 安装autotools工具

sudo apt install automake

2.2 准备源文件

源文件随便准备了两个,一个主程序文件,一个封装接口文件,目录结构如下:

configure-learn/
├── hello.c
├── hello.h
└── main.c

0 directories, 3 files

测试文件的内容不列出来了,就是简单的调用hello.c里面的接口。

2.3 生成configure.ac文件

源文件创建后,我们就可以通过autoscan命令对该目录进行扫描,生成configure.scan文件。首先切换到该目录,然后执行命令如下:

autoscan

执行成功后可以看出多了两个文件,一个是autoscan.log,这个是日志文件;另外一个是configure.scan文件,这个是扫描的结果文件。
在这里插入图片描述

这里configure.scan其实是一个模板文件,我们需要手动修改其内容,并将其改名为configure.ac。具体需要做:

1) AC_INIT里面的参数: AC_INIT(main, 1.0.0, 2222222222@163.com);

2) 添加宏AM_INIT_AUTOMAKE;

3) 在AC_OUTPUT后添加输出文件Makefile。

修改前:

#                                               -*- 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([main.c])
AC_CONFIG_HEADERS([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

完成修改后的文件内容如下:

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

AC_PREREQ([2.69])
AC_INIT(main, 1.0.0, 2222222222@163.com)
AC_CONFIG_SRCDIR([main.c])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE(main, 1.0.0)

# 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)

下面给出本文件的简要说明(所有以”#”号开始的行为注释):
(1)AC_PREREQ

声明本文件要求的autoconf版本,本例使用的版本为2.69。

(2)AC_INIT

用来定义软件的名称和版本等信息,”FULL-PACKAGE-NAME”为软件包名称,”VERSION”为软件版本号,”BUG-REPORT-ADDRESS”为BUG报告地址(一般为软件作者邮件地址)。

(3)AC_CONFIG_SRCDIR

用来侦测所指定的源码文件是否存在,来确定源码目录的有效性。此处为当前目录下的hello.c。

(4)AC_CONFIG_HEADER

用于生成config.h文件,以便autoheader使用。

(5)AM_INIT_AUTOMAKE

检查automake尝试Makefile时的必要的工具。 例如:AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects]) , 一些可选的选项:

选项解释
-Wall打开全部警告
-Werror将警告当错误处理
-foreign放宽一些GNU标准需求
-1.11.1需要automake的最低版本
-dist-bzip2在使用make dist和make distcheck期间同时创建tar.bz2存档
-tar-ustar使用ustar格式创建tar存档

(6)AC_PROG_CC

用来指定编译器,如果不指定,选用默认gcc。
(7)AC_OUTPUT

用来设定 configure 所要产生的文件,如果是makefile,configure会把它检查出来的结果带入makefile.in文件产生合适的makefile。使用Automake时,还需要一些其他的参数,这些额外的宏用aclocal工具产生。

更详细的说明表:

说明
AC_PREREQ声明autoconf要求的版本号。
AC_INIT定义软件包全名称,版本号,联系方式。
AC_CONFIG_SCRDIR用来侦测所指定的源码文件是否存在,来确定源码有效性。
AC_CONFIG_HEADERAC_CONFIG_HEADERS([config.h])告诉autoheader应当生成config.h.in的路径,由autoconf自动生成config.h文件。在实际的编译阶段,生成的编译命令会加上-DHAVE_CONFIG_H定义宏,于是在代码中,就可以安全的引用config.h。 config.h包含了大量的宏定义,其中包括软件包的名字等信息,程序可以直接使用这些宏;更重要的是,程序可以根据其中的对目标平台的可移植性相关的宏,通过条件编译,动态的调整编译行为。 每当configure.ac有所变化,都可以通过再次执行autoheader更新config.h.in。
AC_CONFIG_AUX_DIR当我们以–install参数运行时,libtoolize --copy被调用,这将使得ltmain.sh被copy进来;接下来分别执行autoconf和autoheader;automake的参数为–add-missing --copy --no-force,这将使得几个辅助脚本和文件被安装到目录下。 这些辅助文件默认安装在configure.ac同一个目录下,如果你希望用另一个目录来存放他们,可以配置AC_CONFIG_AUX_DIR,例如AC_CONFIG_AUX_DIR([build-aux])将使用build-aux目录来存放辅助文件。 如果不使用–install参数,辅助文件要么不copy,要么以软链的形式创建。推荐使用–install,因为这样,其他软件维护可以避免由于构建工具版本不一致造成问题。
AC_CONFIG_MACRO_DIRAC_CONFIG_MACRO_DIR([m4])指定使用m4目录存放第三方宏;然后在最外层的Makefile.am中加入ACLOCAL_AMFLAGS = -I m4。
AM_INIT_AUTOMAKEautomake的出现晚于autoconf,所以automake是作为autoconf的扩展来实现的。通过在configure.ac中声明AM_INIT_AUTOMAKE告诉autoconf需要配置和调用automake。 在AC_INIT 宏之后添加AM_INIT_AUTOMAKE([foreign -Wall -Werror]),括号里面的选项可以根据需要来修改,具体请看automake手册关于这个宏的说明。 NEWS README AUTHORS ChangeLog:这些文件是GNU软件的标配,不过在项目中不一定需要加入。如果项目中没有这些文件,每次autoreconf会提示缺少文件,不过这并不影响。如果不想看到这些错误提示,可以用AM_INIT_AUTOMAKE([foreign])来配置automake,或者在顶层Makefile.am中使用AUTOMAKE_OPTIONS = foreign;foreign参数就是告诉automake不要这么较真。
AM_PROG_AR指定压缩工具,构建静态库时需要。
AC_MSG_ERRORAC_MSG_XXX这些宏都是echo shell命令的包装器。configure时它们将输出定向到适当的文件描述符。配置脚本很少需要直接运行echo为用户打印消息。使用这些宏可以很容易地更改打印每种消息的方式和时间。
AC_DISABLE_SHARED更改LT_INIT的默认行为以禁用共享库。用户仍然可以通过指定“ --enable-shared”来覆盖此默认设置。 LT_INIT的"disable-shared"选项是该功能的简写。 AM_DISABLE_SHARED是AC_DISABLE_SHARED的已弃用别名;此选项必须在LT_INIT之前才能生效。
LT_INIT如果要使用libtool编译,需要在configure.ac中添加LT_INIT宏,同时去掉AC_PROG_RANLIB。 启用libtool后,该宏会添加对–enable-shared,–disable-shared,–enable-static,–disable-static,–with-pic和–without-pic配置标志的支持,查阅LT_INIT说明。
AC_PROG_CC指定C编译器,默认GCC。
AC_PROG_LIBTOOLAC_PROG_LIBTOOL和AM_PROG_LIBTOOL是不推荐使用的旧版本,建议使用LT_INIT替代之。
AC_PROG_RANLIB构建静态库时需要,具体请看automake手册,建议使用LT_INIT替代之。
AC_CANONICAL_HOST该宏调用后,可以在通过host_cpu,host_vendor和host_os这三个变量获得系统相关信息。
AC_CHECK_HEADERS检查一批头文件。
AC_DEFINE使用本宏进行符号定义,但要为其定义模板。如果缺少模板,autoheader将报错。
AH_TEMPLATE配合AC_DEFINE使用。
AC_DEFINE_UNQUOTED类似于AC_DEFINE,但还要对variable和value进行三种shell替换(每种替换只进行一次): 变量扩展(‘$’),命令替换(‘`’),以及反斜线转义符(‘’)。值中的单引号和双引号 没有特殊的意义。在variable或者value是一个shell变量的时候用本宏代替AC_DEFINE。
AM_CONDITIONAL用于定义条件,生成一个automake宏,可以在Makefile.am中使用这个条件宏进行判断控制。
AC_ARG_ENABLE本宏用来增加编译时选项,该选项使用户可以选择要构建和安装的可选功能,若选项为软件包,类似于nginx中的引入第三方功能包时,参考AC_ARG_WITH。最终可以在./configure --help的Optional Packages选项中看到该项。
AS_HELP_STRING格式化帮助字符串。
AC_SUBST创建或者重新赋值一个automake变量。
AC_CONFIG_FILES生成相应的Makefile文件,不同目录下通过空格分隔。
AC_OUTPUT建议使用AC_CONFIG_FILES替代之。

(8)AC_DEFINE

格式: AC_DEFINE(VARIABLE, VALUE, DESCRIPTION)

输出宏定义到config.h中。

(9)AC_CHECK_HEADERS

格式:AC_CHECK_HEADERS(HEADERS…)

检查头HEADERS并且给每一个发现的头文件定义#define HAVE_HEADER_H

例如:

AC_CHECK_HEADERS([unistd.h windows.h])

这个宏将在当前建造环境下检查unistd.h,windows.h是否存在。并将两个参数写入到配置头文件中。一般是config.h,你可以使用AC_CONFIG_HEADERS([headers])来指定。

AC_CONFIG_HEADERS([config.h])

如果存在就会出现在config.h中例如下面:

/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1

/* Define to 1 if you have the <windows.h> header file. */
#define HAVE_WINDOWS_H 1

(10) AC_CONFIG_FILES

格式:AC_CONFIG_FILES([Makefile sub/Makefile])

写入Makefile.am和sub/Makefile.am文件

(11) AC_CHECK_FUNC

格式: AC_CHECK_FUNCS (function…, [action-if-found], [action-if-not-found])

检查函数是否存在,如果存在执行动作action-if-found,没有发现执行动作action-if-not-found。
如果你没给出action-if-found和action-if-not-found,在发现函数的时候会定义对应的变量,以HAVE_开头,函数的名称都转换成大写。例如:

AC_CHECK_FUNCS(perror gettimeofday clock_gettime memset socket getifaddrs freeifaddrs fork)

如果发现clock_gettime将会定义变量 #define HAVE_CLOCK_GETTIME 1 在对应的配置头文件中。
如果没发现将不会定义。但是也会有一个注释行 /* #undef HAVE_CLOCK_GETTIME*/

(12)AC_ARG_WITH

格式: AC_ARG_WITH (package, help-string, [action-if-given], [action-if-not-given])

这个宏可以给configure增加 –with-package 这样模式的参数。很多软件都有可选项用来打开扩展功能,AC_ARG_WITH就是干这个的。它的第一参数给出扩展包的名称,出现在–with-后面。第二个参数给出一个参数说明,用在./configure –help中。[action-if-given]如果有该选项就被执行,[action-if-not-given]如果没有加这个选项就执行。
例如:

AC_ARG_WITH([militant],
    [AS_HELP_STRING([--with-militant],
        [Enable militant API assertions])],
    [zmq_militant="yes"],
    [])

if test "x$zmq_militant" = "xyes"; then
    AC_DEFINE(ZMQ_ACT_MILITANT, 1, [Enable militant API assertions])
fi

AS_HELP_STRING([–with-militant],
[Enable militant API assertions])
定义一个帮助字串,将在configure –help中被显示出来。
它可以这么使用configure –with-militant,这导致zmq_militant=”yes”被执行,随后通过下面的if语句在config.h中定义一个宏 #define ZMQ_ACT_MILITANT 1。

(13) AC_ARG_ENABLE

格式:AC_ARG_ENABLE (feature, help-string, [action-if-given], [action-if-not-given])

这个宏可以为configure增加–enable-feature 或者 –disable-feature这样的选项。如果configure中加了给定的选项,就执行action-if-given,否则执行action-if-not-given。
例如:

AC_ARG_ENABLE([eventfd],
    [AS_HELP_STRING([--disable-eventfd], [disable eventfd [default=no]])],
    [zmq_enable_eventfd=$enableval],
    [zmq_enable_eventfd=yes])

if test "x$zmq_enable_eventfd" = "xyes"; then
    # Check if we have eventfd.h header file.
    AC_CHECK_HEADERS(sys/eventfd.h,
        [AC_DEFINE(ZMQ_HAVE_EVENTFD, 1, [Have eventfd extension.])])
fi

(14) 共享库和静态库

编译动态库或者静态库,你需要在你的configure.ac中加入下面的宏:

LT_PREREQ([2.4.0])
LT_INIT([disable-static win32-dll dlopen])
AC_PROG_LIBTOOL

LT_PREREQ给出一个版本需求检查。LT_INIT可以实现一些配置,例如win32-dll允许建造动态库,disable-static默认关闭静态库的建造。默认动态库和静态库是同时打开的。
AC_PROG_LIBTOOL检查libtool脚本。做完这些在你的configure中会增加一些选项–enable-static , –enable-shared。
细节参数可以看: libtool 官方文档

2.4 生成aclocal.m4文件

直接执行aclocal命令即可生成该文件:

aclocal

aclocal.m4是一个宏定义文件,该文件内容的生成依赖于configure.ac文件。aclocal会根据confgure.ac文件的内容,搜索本地的m4文件(通常在类似目录下面/usr/share/aclocal-1.15/),然后生成一个在本目录下面使用的aclocal.m4文件。

2.5 生成config.h.in文件

该文件的生成比较简单,直接在命令行执行如下命令即可:

autoheader

这个文件是一个模板文件,后面会利用该文件生成config.h文件。该文件包含一些宏定义。

2.6 生成Makefile.in文件

生成Makefile.in文件之前需要手动创建一个 Makefile.am 文件,该文件用于描述源文件与目标文件的关系。本文对应的Makefile.am文件如下所示:

#AUTOMAKE_OPTIONS=foreign
bin_PROGRAMS=main
main_SOURCES=main.c hello.c hello.h

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

可以看出该文件非常简单,这比写一个Makefile要简单的多。

运行下面命令生成Makefile.in:

automake --add-missing

加上–add-missing参数后,会补全缺少的脚本。

(1)错误:

zl@zl-Lenovo:~/vstdio-workspace/configure-project/configure-learn$ automake --add-missing
configure.ac:8: warning: AM_INIT_AUTOMAKE: two- and three-arguments forms are deprecated.  For more info, see:
configure.ac:8: http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_005fINIT_005fAUTOMAKE-invocation
configure.ac:11: installing './compile'
configure.ac:8: installing './install-sh'
configure.ac:8: installing './missing'
Makefile.am: installing './INSTALL'
Makefile.am: error: required file './NEWS' not found
Makefile.am: error: required file './README' not found
Makefile.am: error: required file './AUTHORS' not found
Makefile.am: error: required file './ChangeLog' not found
Makefile.am: installing './COPYING' using GNU General Public License v3 file
Makefile.am:     Consider adding the COPYING file to the version control system
Makefile.am:     for your code, to avoid questions about which license your project uses
Makefile.am: installing './depcomp'
zl@zl-Lenovo:~/vstdio-workspace/configure-project/configure-learn$ 

(1)分析修改

因为上面Makefile.am文件里面将第一行AUTOMAKE_OPTIONS的设置屏蔽了,默认是gnu,而gnu有标准的软件发布规范,所以需要相应的文件,这里我们可以打开第一行的设置,更换规范检测配置,或者手动暂时创建需要的文件也行,下面是手动创建的方式,手动创建需要的文件,需要这几个文件,是正规软件发布需要的:

touch NEWS README AUTHORS ChangeLog

再次执行automake就可以成功生成Makefile.in文件了。如果要生成多个目标文件,需要在这里写多个源文件与目标文件的对应关系。这种情况是非常常见的,比如一些复杂的项目中通常会包含主程序,测试程序,动态库等等。

2.7 生成configure文件

上述文件都生成后就可以生成configure文件了。该文件是用于生成Makefile的一个脚本。我们在很多开源项目中肯定都遇到过。在开源项目中通常都有一个生成好的configure文件,我们只需要执行该文件就可以生成Makefile。

生成configure文件的方法很简单,我们执行如下命令即可:

autoconf

至此我们完成了生成Makefile的所有准备工作。

2.8 生成Makefile文件

在该目录下面运行configure脚本,即可生成Makefile文件。

./configure

log:

zl@zl-Lenovo:~/vstdio-workspace/configure-project/configure-learn$ ./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 whether make supports nested variables... yes
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
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 whether gcc understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: executing depfiles commands

2.9 编译和测试

直接执行make即可:

zl@zl-Lenovo:~/vstdio-workspace/configure-project/configure-learn$ make
make  all-am
make[1]: Entering directory '/home/zl/vstdio-workspace/configure-project/configure-learn'
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
gcc -DHAVE_CONFIG_H -I.     -g -O2 -MT hello.o -MD -MP -MF .deps/hello.Tpo -c -o hello.o hello.c
mv -f .deps/hello.Tpo .deps/hello.Po
gcc  -g -O2   -o main main.o hello.o
make[1]: Leaving directory '/home/zl/vstdio-workspace/configure-project/configure-learn'

测试log:

zl@zl-Lenovo:~/vstdio-workspace/configure-project/configure-learn$ ./main
paramters not enough
zl@zl-Lenovo:~/vstdio-workspace/configure-project/configure-learn$ ./main 1
hello world!
zl@zl-Lenovo:~/vstdio-workspace/configure-project/configure-learn$ ./main 5
no hello

2.10 最终工程目录结构

zl@zl-Lenovo:~/vstdio-workspace/configure-project$ tree configure-learn/
configure-learn/
├── aclocal.m4
├── AUTHORS
├── autom4te.cache
│   ├── output.0
│   ├── output.1
│   ├── requests
│   ├── traces.0
│   └── traces.1
├── autoscan.log
├── ChangeLog
├── compile -> /usr/share/automake-1.15/compile
├── config.h
├── config.h.in
├── config.log
├── config.status
├── configure
├── configure.ac
├── COPYING -> /usr/share/automake-1.15/COPYING
├── depcomp -> /usr/share/automake-1.15/depcomp
├── hello.c
├── hello.h
├── hello.o
├── INSTALL -> /usr/share/automake-1.15/INSTALL
├── install-sh -> /usr/share/automake-1.15/install-sh
├── main
├── main.c
├── main.o
├── Makefile
├── Makefile.am
├── Makefile.in
├── missing -> /usr/share/automake-1.15/missing
├── NEWS
├── README
└── stamp-h1

1 directory, 33 files

2.11 打包

make dist

运行make dist命令,当前目录下会出现 main-1.0.0.tar.gz,这个文件名跟configure.ac里面的配置有关,里面的文件也跟 Makefile.am 文件有关,如果打包之后,到别的目录解压编译出现问题,少文件的话,多是 Makefile.am 没有正确设置 xxxx_SOURCES。

打包之后,到别的目录重新解压,目录结构如下:

main-1.0.0
├── aclocal.m4
├── AUTHORS
├── ChangeLog
├── compile
├── config.h.in
├── configure
├── configure.ac
├── COPYING
├── depcomp
├── hello.c
├── hello.h
├── INSTALL
├── install-sh
├── main.c
├── Makefile.am
├── Makefile.in
├── missing
├── NEWS
└── README

0 directories, 19 files

3 扩展

3.1 config.h中定义一个宏

比如:在config.h中定义一个宏 HAVE_TEST为1

(1)修改configure.ac,添加如下代码:

AC_DEFINE([HAVE_TEST], [1],
        [Define to 1 if you have the test function.])

(2)运行autoheader,重新生成config.h.in文件

(3)运行autoconf,重新生成configure文件

(4)重新运行 ./configure,更新config.h文件
在这里插入图片描述

3.2 autoreconf生成Makefile

3.2.1图析

在这里插入图片描述

3.2.2详解

源文件创建之后,configure.ac修改完,并创建Makefile.am文件,以及正规发布需要的README文件等,目录结构如下:

configure-learn
├── AUTHORS
├── autoscan.log
├── ChangeLog
├── configure.ac
├── hello.c
├── hello.h
├── main.c
├── Makefile.am
├── NEWS
└── README

0 directories, 10 files

1.运行autoreconf命令

autoreconf -if
zl@zl-Lenovo:~/vstdio-workspace/configure-project/configure-learn$ ls
AUTHORS  autoscan.log  ChangeLog  configure.ac  hello.c  hello.h  main.c  Makefile.am  NEWS  README
zl@zl-Lenovo:~/vstdio-workspace/configure-project/configure-learn$ autoreconf -if
configure.ac:8: warning: AM_INIT_AUTOMAKE: two- and three-arguments forms are deprecated.  For more info, see:
configure.ac:8: http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_005fINIT_005fAUTOMAKE-invocation
configure.ac:17: installing './compile'
configure.ac:8: installing './install-sh'
configure.ac:8: installing './missing'
Makefile.am: installing './INSTALL'
Makefile.am: installing './COPYING' using GNU General Public License v3 file
Makefile.am:     Consider adding the COPYING file to the version control system
Makefile.am:     for your code, to avoid questions about which license your project uses
Makefile.am: installing './depcomp'
zl@zl-Lenovo:~/vstdio-workspace/configure-project/configure-learn$ ls
aclocal.m4  autom4te.cache  ChangeLog  config.h.in  configure.ac  depcomp  hello.h  install-sh  Makefile.am  missing  README
AUTHORS     autoscan.log    compile    configure    COPYING       hello.c  INSTALL  main.c      Makefile.in  NEWS
zl@zl-Lenovo:~/vstdio-workspace/configure-project/configure-learn$

项目目录下会多出m4文件,config.h.in文件,Makefile.in文件,configure脚本,compile脚本,depcomp脚本等文件。

2.运行configure命令

./configure

直接在Ubuntu上运行的话,这样是可以的,但是实际开发中会涉及一些arm系统之类的,这个时候我们可能就需要设置一些参数。譬如enbale/disbale一些特性,设置交叉编译平台(例如–host=linux-mips),设置编译安装目录(例如–prefix=path_to_your_build_directory)具体可以查看help信息 。

3.运行make

生成可执行文件,运行文件测试即可。

3.3 工程发布

结合 “3.2 autoreconf生成Makefile” 的方法,其实3.2操作前的工程就是可供发布的工程,其他人拿到之后,按照3.2的步骤即可。发布工程参考目录如下:

configure-learn
├── AUTHORS
├── autoscan.log
├── ChangeLog
├── configure.ac
├── hello.c
├── hello.h
├── main.c
├── Makefile.am
├── NEWS
└── README

0 directories, 10 files

源文件:

├── hello.c
├── hello.h
├── main.c

3.4 文件生成分解图

source files --> [autoscan] --> configure.scan --> configure.ac
[acinclude.m4] --.
                 |
[local macros] --+--> [aclocal] --> aclocal.m4
                 |
configure.ac ----'
configure.ac --.
               |   .------> autoconf -----> configure
[aclocal.m4] --+---+
               |   `-----> [autoheader] --> [config.h.in]
[acsite.m4] ---'
config.h.in ---.
               +--> automake --> Makefile.in
Makefile.am ---'
                         .-------------> [config.cache]
configure* --------------+------------> config.log                                                       
                         |
[config.h.in] -.         v          .-> [config.h] -.
               +--> config.status --+               +--> make
Makefile.in ---'                    `-> Makefile ---'

总结:需要项目维护者手动修改的文件除了可选的NEWS README AUTHORS ChangeLog文件之外,就是configure.ac文件和每个源码文件夹下的Makefile.am文件了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/901201.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

07_缓存预热缓存雪崩缓存击穿缓存穿透

缓存预热&缓存雪崩&缓存击穿&缓存穿透 一、缓存预热 提前将数据从数据库同步到redis。 在程序启动的时候&#xff0c;直接将数据刷新到redis懒加载&#xff0c;用户访问的时候&#xff0c;第一次查询数据库&#xff0c;然后将数据写入redis 二、缓存雪崩 发生情…

Python 的下一代 HTTP 客户端

迷途小书童 读完需要 9分钟 速读仅需 3 分钟 1 环境 windows 10 64bitpython 3.8httpx 0.23.0 2 简介 之前我们介绍过使用 requests ( https://xugaoxiang.com/2020/11/28/python-module-requests/ ) 来进行 http 操作&#xff0c;本篇介绍另一个功能非常类似的第三方库 httpx&…

深入探索JavaScript中的5种经典算法

在本文中&#xff0c;您将了解到&#xff1a; 冒泡排序、快速排序等常见排序算法原理及其在 JavaScript 中的实现&#xff1b; 经典算法示例 1. 冒泡排序算法 冒泡排序算法&#xff1a;冒泡排序是一种简单但效率较低的排序算法。它通过多次遍历数组&#xff0c;比较相邻元素并…

JVM前世今生之JVM内存模型

JVM内存模型所指的是JVM运行时区域&#xff0c;该区域分为两大块 线程共享区域 堆内存、方法区&#xff0c;即所有线程都能访问该区域&#xff0c;随着虚拟机和GC创建和销毁 线程独占区域 虚拟机栈、本地方法栈、程序计数器&#xff0c;即每个线程都有自己独立的区域&#…

生成式AI系列 —— DCGAN生成手写数字

1、模型构建 1.1 构建生成器 # 导入软件包 import torch import torch.nn as nnclass Generator(nn.Module):def __init__(self, z_dim20, image_size256):super(Generator, self).__init__()self.layer1 nn.Sequential(nn.ConvTranspose2d(z_dim, image_size * 32,kernel_s…

基于web的停车场收费管理系统/基于springboot的停车场管理系统

摘 要 随着汽车工业的迅猛发展&#xff0c;我国汽车拥有量急剧增加。停车场作为交通设施的组成部分,随着交通运输的繁忙和不断发展&#xff0c;人们对其管理的要求也不断提高&#xff0c;都希望管理能够达到方便、快捷以及安全的效果。停车场的规模各不相同,对其进行管理的模…

深入理解ASP.NET Core中的Program类和Startup类

一、背景介绍 本文以ASP.NET Core 6以前版本API程序来说明。 在我们新建ASP.NET Core项目时&#xff0c;项目根目录下会自动建立Program.cs和Startup.cs两个类文件。 Program.cs 作为 Web 应用程序的默认入口&#xff0c;不做任何修改的情况下&#xff0c;会调用同目录下 Star…

Dubbo 融合 Nacos 成为注册中心

快速上手 Dubbo 融合 Nacos 成为注册中心的操作步骤非常简单&#xff0c;大致步骤可分为“增加 Maven 依赖”以及“配置注册中心“。 增加 Maven 依赖 只需要依赖Dubbo客户端即可&#xff0c;关于推荐的使用版本&#xff0c;请参考Dubbo官方文档或者咨询Dubbo开发人员&#…

Vue 2 组件基础

一个简单的组件示例&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</titl…

暴力模拟入门+简单:零件组装、塔子的签到题、塔子哥考试、平均像素值、换座位

暴力模拟入门 P1038 小红书-2022.9.23-零件组装 #include <bits/stdc.h> #include <cstdint> using namespace std;typedef long long LL; const int N 100001; int num[4]; LL d; vector<vector<LL>> v(4, vector<LL>(N));int main() {for(in…

python中的__name__是个啥?

pycharm中随便打开一个文件&#xff0c;在special variables中能看到一个__name__的变量 在很多python脚本中&#xff0c;也经常能看到if name "main"这样一行 所以_name_到底是个啥&#xff1f; 首先&#xff0c;我们可以确定这是一个str字符变量 “在 Python 中&…

06_布隆过滤器BloomFilter

06——布隆过滤器BloomFilter 一、是什么 由一个初始值都为零的bit数组和多个哈希函数构成&#xff0c;用来快速判断集合中是否存在某个元素 设计思想&#xff1a; 1. 目的&#xff1a;减少内存占用 1. 方式&#xff1a;不保存数据信息&#xff0c;只是在内存中做一个是否存…

【框架类】—MVVM框架

一、MVVM框架有哪些 Vue.jsReact.jsAngular.js 二、对MVVM的认识 1. MVC是什么 全称 Model View Controller, 它采用模型(Model)-视图(View)-控制器(controller)的方法把业务逻辑、数据与界面显示分离 2. MVVM的定义 MVVM是一种软件架构模式&#xff0c;它代表了模型 --视…

智慧工地监管一体化云平台源码 PC端、 手机端、 现场端

智慧工地管理平台是以物联网、移动互联网技术为基础&#xff0c;充分应用大数据、人工智能、移动通讯、云计算等信息技术&#xff0c;利用前端信息采通过人机交互、感知、决策、执行和反馈等&#xff0c;实现对工程项目內人员、车辆、安全、设备、材料等的智能化管理&#xff0…

Python 潮流周刊#16:优雅重要么?如何写出 Pythonic 的代码?

你好&#xff0c;我是猫哥。这里每周分享优质的 Python、AI 及通用技术内容&#xff0c;大部分为英文。标题取自其中两则分享&#xff0c;不代表全部内容都是该主题&#xff0c;特此声明。 本周刊由 Python猫 出品&#xff0c;精心筛选国内外的 250 信息源&#xff0c;为你挑选…

Linux(入门篇)

Linux&#xff08;入门篇&#xff09; Linux概述Linux是什么Linux的诞生Linux和Unix的渊源GNU/LinuxLinux的发行版Linux VS Windows Linux概述 Linux是什么 Linux是一个操作系统(OS) Linux的诞生 作者&#xff1a;李纳斯托瓦兹&#xff08;git也是他开发的&#x1f602;&am…

11. 实现业务功能--获取用户信息

目录 1. 实现 Controller 2. 单体测试 3. 修复返回值存在的缺陷 3.1 用户的隐私数据&#xff1a;密码的密文和盐不能显示 3.2 将值为 null 的字段可以进行过滤 3.3 时间的格式需要进行处理&#xff0c;如 yyyy-mmmm-ddd HH:mm:ss 3.4 data 属性没有返回 4. 实现前端页…

低代码平台全套源码,支持二次开发

低代码开发平台&#xff1a;只需要编写简单的配置文件即可构建企业级应用程序。 一、低代码PaaS平台可以在云端开发、部署、运行低代码应用程序。使用独立数据库模型&#xff0c;基于Kubernetes云原生技术&#xff0c;每个租户均可拥有一套独立的存储、数据库、代码和命名空间&…

光栅化之扫描填充三角形

重心坐标计算 重心坐标比较简单&#xff0c;取最大包围合再计算点是否在三角形内就行&#xff0c;再根据重心坐标返回的alpha,beta,gamma三个权重值计算 uv映射和depth深度缓冲值&#xff0c;因为是求的重心坐标&#xff0c;感觉效果比插值的要好一点。 求重心坐标 barycentr…