在 Makefile 中创建静态库具有重要的意义,尤其是在项目管理和软件构建方面。能够使代码模块化,代码重用度高。易于易于维护对某个功能进行修改或优化,只需要在一个地方更改静态库中的代码,而不是在项目的多个位置修改相同的代码。同时可以构建效率,减少编译时间。
创建静态库的步骤
创建一个简单的Makefile来生成静态库通常包括以下几个步骤:
- 定义源文件:
- 列出所有需要编译成库的源文件(.c 文件)。
- 定义头文件(.h 文件)的位置,以便编译器能找到它们。
- 定义目标:
- 定义最终生成的静态库名称。
- 可以定义一个目标来清理旧的编译文件。
- 规则:
- 规则用于描述如何从源文件生成目标文件(.o 文件)。
- 规则用于如何从目标文件生成静态库。
- 编译命令:
- 使用 gcc 或其他编译器来编译源文件。
- 使用 ar 工具来归档生成的目标文件。
ar
归档工具介绍
ar
是 “archiver
” 的缩写, 是一个工具,用于创建、修改和提取归档文件(通常是静态库
)。它是 GNU 工具链的一部分,通常与 gcc 和其他编译工具一起使用。
ar
工具的主要用途:
- 创建归档文件:
- ar 可以用来创建静态库文件,这种文件包含了多个编译后的目标文件(.o 文件),这些文件可以被链接器使用来构建最终的可执行程序。
- 修改归档文件:
- 可以向已存在的归档文件中添加新的目标文件。
- 可以从归档文件中删除目标文件。
- 可以替换归档文件中的现有目标文件。
- 提取归档文件的内容:
ar
可以用来提取归档文件中的单个或多个目标文件。
- 索引归档文件:
ar
可以创建一个索引文件,使链接器能够更快地找到所需的模块。
ar
常用选项:
ar rcs archive file1.o file2.o ...
:r
表示替换或添加文件到归档文件中。c
表示创建归档文件(如果不存在)。s
表示创建符号索引。archive
是归档文件的名称。file1.o
,file2.o
, … 是要添加到归档文件中的目标文件。
ar d archive file.o
:d
表示从归档文件中删除一个文件。
ar t archive
:t
表示列出归档文件的内容。
ar x archive
:x
表示从归档文件中提取所有文件。
实例源码工程
该工程展示了如何将一个加减乘除封装为静态库,其中,math_ops.h
声明了加减乘除的接口,math_ops.c
实现了头文件的这些接口
工程目录结构
.
├── Makefile
├── math_ops.c
└── math_ops.h
源码展示
math_ops.h
#ifndef MATH_OPS_H
#define MATH_OPS_H
int add(int a, int b);
int subtract(int a, int b);
int multiply(int a, int b);
int divide(int a, int b);
#endif // MATH_OPS_H
math_ops.c
#include <stdio.h>
#include "math_ops.h"
// 加法
int add(int a, int b) {
return a + b;
}
// 减法
int subtract(int a, int b) {
return a - b;
}
// 乘法
int multiply(int a, int b) {
return a * b;
}
// 除法
int divide(int a, int b) {
if (b == 0) {
printf("Error: Division by zero.\n");
return 0;
}
return a / b;
}
Makefile
# 定义变量
CC=gcc
CFLAGS=-c -Wall -g -I./
AR=ar
ARFLAGS=rcs
LIBNAME=libmath_ops
# 目标文件列表
OBJS=math_ops.o
# 静态库文件
LIBRARY=$(LIBNAME).a
# 清理目标
.PHONY: clean
# 默认目标
all: $(LIBRARY)
# 规则:从源文件生成目标文件
%.o: %.c
$(CC) $(CFLAGS) $< -o $@
# 规则:从目标文件生成静态库
$(LIBRARY): $(OBJS)
$(AR) $(ARFLAGS) $@ $^
ranlib $@ # 更新索引
# 清理规则
clean:
rm -f $(OBJS) $(LIBRARY)
解释
CC
和CFLAGS
定义了编译器和编译选项。AR
和ARFLAGS
定义了归档工具和选项。LIBNAME
是库的名字。OBJS
列出了所有的目标文件。LIBRARY
是最终生成的静态库文件名。all
是默认的目标,它会构建静态库。%.o: %.c
规则指定了如何从 .c 文件生成 .o 文件。$(LIBRARY): $(OBJS)
规则指定了如何从目标文件生成静态库。clean
目标用于清理编译产生的文件。ranlib
是一个工具,通常与 ar 工具一起使用,用于更新归档文件(静态库)中的符号表。当使用 ar 创建或修改归档文件后,通常会使用 ranlib 来更新归档文件中的索引,以便链接器能够更快地找到所需的模块。