【Linux笔记】【基础系列】 automake基础使用2

这篇博客详细介绍了如何在Linux环境下使用Automake工具处理多目录的C语言项目。从创建目录结构,编写源文件,到配置Automake的configure.ac和Makefile.am文件,再到执行aclocal、autoconf、autoheader、automake等命令,最后成功编译并运行程序。文章通过一个包含src和include目录的实际示例,展示了Automake在复杂项目中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【Linux笔记】【基础系列】 Automake基础使用 2

上一篇笔记Automake基础使用记录了最简单的例子如何实现 Automake 生成 Makefile 的步骤。但是这个示例只适用于文件较少,且在同一个目录下的情况。如果有许多的c文件,放在不同目录下,就需要做一些改变了。

下面还是基于树莓派4B平台进行开发,基于上一篇的示例程序,会将c源文件放在目录 src 和 include 下。

新建一个用于写示例的文件夹:

pi@raspberrypi:~/Desktop $ mkdir automaketest2

在原先的基础上新建2个文件:

pi@raspberrypi:~/Desktop/automaketest2 $ touch isOdd.c isOdd.h

文件内容为:

isOdd.c用于判断数值是否为奇数。

#include <stdio.h>
#include <stdlib.h>

int isOdd(unsigned int num)
{
    if(num & 1)
        return 1;
    
    return 0;
}

isOdd.h对应的头文件:

int isOdd(unsigned int num);

test.c是主程序,增加了打印0到10之间的奇数。

#include <stdio.h>
#include <stdlib.h>

#include "isPrime.h"
#include "isOdd.h"

int main(int argc, char* argv[])
{
    int i;
    
    for(i = 0; i < 100; i++)
    {
        if(isPrime(i))
            printf("%d ", i);
    }
    printf("\n");
    
    for(i = 0; i < 10; i++)
    {
        if(isOdd(i))
            printf("%d ", i);
    }
    printf("\n");
    
    return 0;
}

然后新建两个文件夹 src 和 include

pi@raspberrypi:~/Desktop/automaketest2 $ mkdir src include

将 c 文件放在 src 文件夹内, h 文件文件放在 include 文件夹内。

pi@raspberrypi:~/Desktop/automaketest2 $ ls ./src/
isOdd.c  isPrime.c
pi@raspberrypi:~/Desktop/automaketest2 $ ls ./include/
isOdd.h  isPrime.h

所需的文件就都准备好了,接下来开始生成Makefile。

步骤的顺序还是一样的,主要是修改的部分不同。

  1. 执行 autoscan 命令

    pi@raspberrypi:~/Desktop/automaketest2 $ autoscan
    pi@raspberrypi:~/Desktop/automaketest2 $ ls -l
    总用量 16
    -rw-r--r-- 1 pi pi    0 53 22:50 autoscan.log
    -rw-r--r-- 1 pi pi  495 53 22:50 configure.scan
    drwxr-xr-x 2 pi pi 4096 53 22:39 include
    drwxr-xr-x 2 pi pi 4096 53 22:39 src
    -rw-r--r-- 1 pi pi  379 53 22:37 test.c
    

    执行 autoscan 命令生成了 autoscan.log 和 configure.scan 文件。

  2. 将 configure.scan 重命名为 configure.ac,并修改 configure.ac 文件,这里修改的就会与上一篇有一些区别。

    pi@raspberrypi:~/Desktop/automaketest2 $ mv configure.scan configure.ac
    

    configure.ac 文件修改前内容如下:

    pi@raspberrypi:~/Desktop/automaketest2 $ cat 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([test.c])
    AC_CONFIG_HEADERS([config.h])
    
    # Checks for programs.
    AC_PROG_CC
    
    # Checks for libraries.
    
    # Checks for header files.
    AC_CHECK_HEADERS([stdlib.h])
    
    # 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(automaketest, 2.0.0, test@test.com)
    AM_INIT_AUTOMAKE
    AC_PROG_RANLIB
    AC_CONFIG_SRCDIR([test.c])
    AC_CONFIG_HEADERS([config.h])
    
    # Checks for programs.
    AC_PROG_CC
    
    # Checks for libraries.
    
    # Checks for header files.
    AC_CHECK_HEADERS([stdlib.h])
    
    # Checks for typedefs, structures, and compiler characteristics.
    
    # Checks for library functions.
    
    AC_CONFIG_FILES([
     Makefile
     src/Makefile
    ])
    AC_OUTPUT
    

    可以看到,修改了用于定义软件名称、版本号、联系地址的 AC_INIT,添加了参数 AM_INIT_AUTOMAKEAC_PROG_RANLIBAC_CONFIG_FILES

    AC_PROG_RANLIB表示需要生成静态库,因为不同目录下,需要生成.a文件进行静态链接。

    AC_CONFIG_FILES表示生成相应的Makefile文件,不同文件夹下的Makefile通过空格分隔。

  3. 执行 aclocal 命令

    pi@raspberrypi:~/Desktop/automaketest2 $ aclocal
    pi@raspberrypi:~/Desktop/automaketest2 $ ls -l
    总用量 64
    -rw-r--r-- 1 pi pi 41888 53 23:13 aclocal.m4
    drwxr-xr-x 2 pi pi  4096 53 23:13 autom4te.cache
    -rw-r--r-- 1 pi pi     0 53 22:50 autoscan.log
    -rw-r--r-- 1 pi pi   554 53 23:07 configure.ac
    drwxr-xr-x 2 pi pi  4096 53 22:39 include
    drwxr-xr-x 2 pi pi  4096 53 22:39 src
    -rw-r--r-- 1 pi pi   379 53 22:37 test.c
    

执行完 aclocal 命令后,生成了 aclocal.m4 文件和 autom4te.cache 文件夹。

  1. 执行 autoconf 命令

    pi@raspberrypi:~/Desktop/automaketest2 $ autoconf
    pi@raspberrypi:~/Desktop/automaketest2 $ ls -l
    总用量 232
    -rw-r--r-- 1 pi pi  41888 53 23:13 aclocal.m4
    drwxr-xr-x 2 pi pi   4096 53 23:14 autom4te.cache
    -rw-r--r-- 1 pi pi      0 53 22:50 autoscan.log
    -rwxr-xr-x 1 pi pi 168200 53 23:14 configure
    -rw-r--r-- 1 pi pi    554 53 23:07 configure.ac
    drwxr-xr-x 2 pi pi   4096 53 22:39 include
    drwxr-xr-x 2 pi pi   4096 53 22:39 src
    -rw-r--r-- 1 pi pi    379 53 22:37 test.c
    

    执行完 autoconf 命令后,生成 configure 文件。

  2. 执行 autoheader 命令

    pi@raspberrypi:~/Desktop/automaketest2 $ autoheader
    pi@raspberrypi:~/Desktop/automaketest2 $ ls -l
    总用量 236
    -rw-r--r-- 1 pi pi  41888 53 23:13 aclocal.m4
    drwxr-xr-x 2 pi pi   4096 53 23:14 autom4te.cache
    -rw-r--r-- 1 pi pi      0 53 22:50 autoscan.log
    -rw-r--r-- 1 pi pi   1437 53 23:14 config.h.in
    -rwxr-xr-x 1 pi pi 168200 53 23:14 configure
    -rw-r--r-- 1 pi pi    554 53 23:07 configure.ac
    drwxr-xr-x 2 pi pi   4096 53 22:39 include
    drwxr-xr-x 2 pi pi   4096 53 22:39 src
    -rw-r--r-- 1 pi pi    379 53 22:37 test.c
    

    执行完 autoheader 命令后,生成 config.h.in 文件。

  3. 在每一个需要生成 Makefile 的目录里创建 Makefile.am 文件,这里一共创建两个Makefile.am 文件。

    第一个是当前目录下:

    pi@raspberrypi:~/Desktop/automaketest2 $ touch Makefile.am
    

    文件内容为:

    AUTOMAKE_OPTIONS = foreign
    SUBDIRS = src
    bin_PROGRAMS = test
    test_SOURCES = test.c
    test_LDADD = src/libnumtest.a
    AM_CFLAGS = -I./include
    

AUTOMAKE_OPTIONS用于设置automake的选项,这里的foreign表示的是发布软件的严格等级。

SUBDIRS 在处理本目录前要先调用哪些子目录去生成Makefile。

bin_PROGRAMS表示生成的可执行文件名称。

test_SOURCES用于表示生成的可执行文件 test 所依赖的源文件。注意test是可执行文件名称,如果可执行文件名称换成autotest,那么这个名称就要改成autotest_SOURCES

test_LDADD表示静态连接的文件。

接下来是新建第二个 Makefile.am 文件。

pi@raspberrypi:~/Desktop/automaketest2 $ cd src/
pi@raspberrypi:~/Desktop/automaketest2/src $ touch Makefile.am

文件内容为:

noinst_LIBRARIES = libnumtest.a
libnumtest_a_SOURCES = isOdd.c  isPrime.c 
include_HEADERS = ../include/isOdd.h ../include/isPrime.h

noinst_LIBRARIES表示静态库名,且静态库只编译不会安装到系统中。

libnumtest_a_SOURCES表示静态库依赖的 c 源文件。

include_HEADERS表示依赖的头文件。

  1. 执行 automake --add-missing 命令

    这个命令会让 automake 加入一个标准的软件包所必须的一些文件。

    pi@raspberrypi:~/Desktop/automaketest2 $ automake --add-missing
    configure.ac:12: installing './compile'
    configure.ac:6: installing './install-sh'
    configure.ac:6: 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'
    
    

    执行完后提示,缺少了文件NEWS, README, AUTHORS, ChangeLog,那就需要先创建这四个文件:

    pi@raspberrypi:~/Desktop/automaketest2 $ touch NEWS README AUTHORS ChangeLog
    

    然后再执行一次 automake --add-missing 命令

    pi@raspberrypi:~/Desktop/automaketest2 $ automake --add-missing
    pi@raspberrypi:~/Desktop/automaketest2 $ ^C
    pi@raspberrypi:~/Desktop/automaketest2 $ ls -l
    总用量 268
    -rw-r--r-- 1 pi pi  41888 53 23:13 aclocal.m4
    -rw-r--r-- 1 pi pi      0 53 23:33 AUTHORS
    drwxr-xr-x 2 pi pi   4096 53 23:31 autom4te.cache
    -rw-r--r-- 1 pi pi      0 53 22:50 autoscan.log
    -rw-r--r-- 1 pi pi      0 53 23:33 ChangeLog
    lrwxrwxrwx 1 pi pi     32 53 23:33 compile -> /usr/share/automake-1.16/compile
    -rw-r--r-- 1 pi pi   1437 53 23:14 config.h.in
    -rwxr-xr-x 1 pi pi 168200 53 23:14 configure
    -rw-r--r-- 1 pi pi    554 53 23:07 configure.ac
    lrwxrwxrwx 1 pi pi     32 53 23:33 COPYING -> /usr/share/automake-1.16/COPYING
    lrwxrwxrwx 1 pi pi     32 53 23:33 depcomp -> /usr/share/automake-1.16/depcomp
    drwxr-xr-x 2 pi pi   4096 53 22:39 include
    lrwxrwxrwx 1 pi pi     32 53 23:33 INSTALL -> /usr/share/automake-1.16/INSTALL
    lrwxrwxrwx 1 pi pi     35 53 23:33 install-sh -> /usr/share/automake-1.16/install-sh
    -rw-r--r-- 1 pi pi    113 53 23:25 Makefile.am
    -rw-r--r-- 1 pi pi  28656 53 23:33 Makefile.in
    lrwxrwxrwx 1 pi pi     32 53 23:33 missing -> /usr/share/automake-1.16/missing
    -rw-r--r-- 1 pi pi      0 53 23:33 NEWS
    -rw-r--r-- 1 pi pi      0 53 23:33 README
    drwxr-xr-x 2 pi pi   4096 53 23:33 src
    -rw-r--r-- 1 pi pi    379 53 22:37 test.c
    
  2. 执行 ./configure 命令

    执行 ./configure 命令后,就会把 Makefile.in 转变为 Makefile 文件。

    pi@raspberrypi:~/Desktop/automaketest2 $ ./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... no
    checking for mawk... mawk
    checking whether make sets $(MAKE)... yes
    checking whether make supports nested variables... yes
    checking for ranlib... ranlib
    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 whether make supports the include directive... yes (GNU style)
    checking dependency style of gcc... gcc3
    checking how to run the C preprocessor... gcc -E
    checking for grep that handles long lines and -e... /bin/grep
    checking for egrep... /bin/grep -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 stdlib.h... (cached) yes
    checking that generated files are newer than configure... done
    configure: creating ./config.status
    config.status: creating Makefile
    config.status: creating src/Makefile
    config.status: creating config.h
    config.status: executing depfiles commands
    

    这个时候查看下文件夹下的内容:

    pi@raspberrypi:~/Desktop/automaketest2 $ ls -l
    总用量 356
    -rw-r--r-- 1 pi pi  41888 53 23:13 aclocal.m4
    -rw-r--r-- 1 pi pi      0 53 23:33 AUTHORS
    drwxr-xr-x 2 pi pi   4096 53 23:31 autom4te.cache
    -rw-r--r-- 1 pi pi      0 53 22:50 autoscan.log
    -rw-r--r-- 1 pi pi      0 53 23:33 ChangeLog
    lrwxrwxrwx 1 pi pi     32 53 23:33 compile -> /usr/share/automake-1.16/compile
    -rw-r--r-- 1 pi pi   1635 53 23:34 config.h
    -rw-r--r-- 1 pi pi   1437 53 23:14 config.h.in
    -rw-r--r-- 1 pi pi  13619 53 23:34 config.log
    -rwxr-xr-x 1 pi pi  33015 53 23:34 config.status
    -rwxr-xr-x 1 pi pi 168200 53 23:14 configure
    -rw-r--r-- 1 pi pi    554 53 23:07 configure.ac
    lrwxrwxrwx 1 pi pi     32 53 23:33 COPYING -> /usr/share/automake-1.16/COPYING
    lrwxrwxrwx 1 pi pi     32 53 23:33 depcomp -> /usr/share/automake-1.16/depcomp
    drwxr-xr-x 2 pi pi   4096 53 22:39 include
    lrwxrwxrwx 1 pi pi     32 53 23:33 INSTALL -> /usr/share/automake-1.16/INSTALL
    lrwxrwxrwx 1 pi pi     35 53 23:33 install-sh -> /usr/share/automake-1.16/install-sh
    -rw-r--r-- 1 pi pi  28496 53 23:34 Makefile
    -rw-r--r-- 1 pi pi    113 53 23:25 Makefile.am
    -rw-r--r-- 1 pi pi  28656 53 23:33 Makefile.in
    lrwxrwxrwx 1 pi pi     32 53 23:33 missing -> /usr/share/automake-1.16/missing
    -rw-r--r-- 1 pi pi      0 53 23:33 NEWS
    -rw-r--r-- 1 pi pi      0 53 23:33 README
    drwxr-xr-x 3 pi pi   4096 53 23:34 src
    -rw-r--r-- 1 pi pi     23 53 23:34 stamp-h1
    -rw-r--r-- 1 pi pi    379 53 22:37 test.c
    

    Makefile 文件已经成功生成了。

  3. 执行 make 命令

    执行 make 命令后,就可以生成最终的可执行文件了。

    pi@raspberrypi:~/Desktop/automaketest2 $ make
    make  all-recursive
    make[1]: 进入目录“/home/pi/Desktop/automaketest2”
    Making all in src
    make[2]: 进入目录“/home/pi/Desktop/automaketest2/src”
    gcc -DHAVE_CONFIG_H -I. -I..     -g -O2 -MT isOdd.o -MD -MP -MF .deps/isOdd.Tpo -c -o isOdd.o isOdd.c
    mv -f .deps/isOdd.Tpo .deps/isOdd.Po
    gcc -DHAVE_CONFIG_H -I. -I..     -g -O2 -MT isPrime.o -MD -MP -MF .deps/isPrime.Tpo -c -o isPrime.o isPrime.c
    mv -f .deps/isPrime.Tpo .deps/isPrime.Po
    rm -f libnumtest.a
    ar cru libnumtest.a isOdd.o isPrime.o 
    ar: `u' 修饰符被忽略,因为 `D' 为默认(参见 `U')
    ranlib libnumtest.a
    make[2]: 离开目录“/home/pi/Desktop/automaketest2/src”
    make[2]: 进入目录“/home/pi/Desktop/automaketest2”
    gcc -DHAVE_CONFIG_H -I.    -I./include -g -O2 -MT test.o -MD -MP -MF .deps/test.Tpo -c -o test.o test.c
    mv -f .deps/test.Tpo .deps/test.Po
    gcc -I./include -g -O2   -o test test.o src/libnumtest.a 
    make[2]: 离开目录“/home/pi/Desktop/automaketest2”
    make[1]: 离开目录“/home/pi/Desktop/automaketest2”
    

    编译完成。

  4. 运行 test 程序。

    最后执行测试程序 test 。

    pi@raspberrypi:~/Desktop/automaketest2 $ ./test 
    2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 
    1 3 5 7 9 
    

    运行程序后,第一行打印 0 到 100 之间的素数,第二行打印 0 到 10 之间的奇数。

这样一个稍微复杂一点的文件在不同目录下的示例就完成了。


【参考资料】

Linux c 开发 - Autotools使用详细解读

Autoconf

automake


本文链接:https://blog.youkuaiyun.com/u012028275/article/details/124579381

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值