3. 静态库的构建与使用

静态库的构建与使用 学习卡片

任务说明

本案例要求使用 Autotools 构建一个静态库,并在同一工程内的可执行程序中链接并使用该库。你将创建两个源码文件(库源码与主程序源码),通过 configure.ac 与 Makefile.am 描述构建规则,最终生成 libmymath.a 静态库及可执行文件 demo,并验证库函数被正确调用。

工程文件结构


math_demo/
├── configure.ac
├── Makefile.am
├── src/
│   ├── Makefile.am
│   ├── mymath.c
│   ├── mymath.h
│   └── main.c

源码实现

src/mymath.h — 库的公开接口声明:


#ifndef MYMATH_H
#define MYMATH_H

int add(int a, int b);
int multiply(int a, int b);

#endif

src/mymath.c — 静态库的函数实现:


#include "mymath.h"

int add(int a, int b) {
    return a + b;
}

int multiply(int a, int b) {
    return a * b;
}

src/main.c — 调用静态库的主程序:


#include <stdio.h>
#include "mymath.h"

int main(void) {
    int x = 7;
    int y = 5;

    printf("add(%d, %d) = %d\n", x, y, add(x, y));
    printf("multiply(%d, %d) = %d\n", x, y, multiply(x, y));

    return 0;
}

Autotools 构建脚本

configure.ac — 顶层 Autoconf 配置:


AC_INIT([math_demo], [1.0])
AM_INIT_AUTOMAKE([foreign])
AC_PROG_CC
AC_PROG_RANLIB
AC_CONFIG_FILES([Makefile src/Makefile])
AC_OUTPUT

Makefile.am — 顶层 Automake 规则:


SUBDIRS = src

src/Makefile.am — 库与程序的构建规则:


lib_LIBRARIES = libmymath.a
libmymath_a_SOURCES = mymath.c mymath.h

bin_PROGRAMS = demo
demo_SOURCES = main.c
demo_LDADD = libmymath.a

构建与运行步骤


# 在 math_demo/ 目录下依次执行:
autoreconf -i
./configure
make
./src/demo

预期输出

程序执行后,终端应显示以下两行(数值由代码中的 x=7, y=5 直接决定):


add(7, 5) = 12
multiply(7, 5) = 35

验证方法

  1. 构建验证:执行 make 后,检查 src/ 目录下是否生成 libmymath.a 与 demo 两个文件。若文件存在,说明静态库与程序均编译链接成功。
  2. 功能验证:运行 ./src/demo,观察输出是否与上述预期输出一致。若两行数值完全匹配,则证明静态库中的 add 与 multiply 函数被正确链接并调用。
  3. 静态链接确认:执行 ldd ./src/demo,输出中不应包含 libmymath 相关动态库依赖,表明该库是以静态方式链接进可执行文件的。

关键点说明

本案例中 AC_PROG_RANLIB 用于生成静态库索引,是 Autotools 构建 .a 库的必要配置。lib_LIBRARIES 告诉 Automake 这是一个需要安装的静态库,而 demo_LDADD 指定了链接时需附加的库文件。整个工程通过 SUBDIRS 实现递归构建,无需额外手写 Makefile 规则。

Autotools 静态库构建与链接流程 mymath.c mymath.h main.c configure.ac Makefile.am src/Makefile.am autoreconf -i ./configure make libmymath.a demo(可执行) 静态链接 ./src/demo add=12, multiply=35