动态库的makefile且链接静态库

文章目录

概要

编写一个Makefile来编译一个动态库,并链接第三方静态库

demo实例流程

一. 测试实例

当你需要编写一个Makefile来编译一个动态库,并链接第三方静态库时,可以按照以下步骤进行。
假设有一个动态库需要编译,同时依赖一个名为 libthirdparty.a 的第三方静态库。

首先,确保你的项目目录结构大致如下:

project/
├── src/
│   ├── your_dynamic_lib.c       # 你的动态库源文件
│   └── your_dynamic_lib.h       # 你的动态库头文件
├── lib/
│   └── libthirdparty.a          # 第三方静态库
└── Makefile                     # Makefile 文件
# 编译器设置
CC = gcc
# 动态库输出文件名
LIBNAME = libyour_dynamic_lib.so
# 源文件路径
SRC_DIR = src
# 静态库路径
LIB_DIR = lib
# 静态库文件名
LIB = thirdparty

# 头文件路径,如果有其他头文件需要包含,可以加在这里
INC = -I$(SRC_DIR)

# 源文件列表,将源文件夹内的所有.c文件列出
SRCS = $(wildcard $(SRC_DIR)/*.c)

# 目标文件列表,替换.c文件为.o文件
OBJS = $(SRCS:.c=.o)

# 链接第三方静态库的路径和库名
LDFLAGS = -L$(LIB_DIR) -l$(LIB)

# 默认目标
all: $(LIBNAME)

# 生成动态库
$(LIBNAME): $(OBJS)
    $(CC) -shared -o $@ $^ $(LDFLAGS)

# 编译每个源文件为目标文件
%.o: %.c
    $(CC) -fPIC -c $< -o $@ $(INC)

# 清理生成的文件
clean:
    rm -f $(SRC_DIR)/*.o $(LIBNAME)

# 伪目标,防止目录下有clean时clean不被执行
.PHONY: all clean


解释:
变量定义:

CC:编译器使用 gcc。
LIBNAME:生成的动态库文件名。
SRC_DIR:源文件目录。
LIB_DIR:第三方静态库所在目录。
LIB:第三方静态库的名称(不包括前缀 lib 和后缀 .a)。
路径和文件:

INC:包含 -I 标志指定的头文件目录。
SRCS:使用 wildcard 函数获取源文件目录中所有的 .c 文件列表。
OBJS:将每个 .c 文件编译为对应的 .o 目标文件列表。
链接和编译规则:

$(LIBNAME):生成动态库的规则,依赖于所有的 .o 目标文件。
%.o: %.c:编译每个源文件为目标文件的规则。
清理规则:

clean:删除所有生成的 .o 文件和动态库文件。

使用方法:
在项目目录中创建以上结构的文件和目录。
将上述 Makefile 的内容复制到 Makefile 文件中。
在命令行中,进入项目目录并运行 make 命令,即可编译生成动态库并链接第三方静态库。

二. 测试实例

project/
├── src/
│   ├── your_dynamic_lib.c     # 你的动态库源文件
│   └── your_dynamic_lib.h     # 你的动态库头文件
├── lib/
│   └── libstatic.a            # 静态库文件
└── Makefile                   # Makefile 文件
# 编译器设置
CC = gcc
# 动态库输出文件名
LIBNAME = libyour_dynamic_lib.so
# 源文件路径
SRC_DIR = src
# 静态库路径
LIB_DIR = lib
# 静态库文件名
STATIC_LIB = static

# 头文件路径
INC = -I$(SRC_DIR)

# 源文件列表
SRCS = $(wildcard $(SRC_DIR)/*.c)

# 目标文件列表
OBJS = $(SRCS:.c=.o)

# 链接静态库的路径和库名
LDFLAGS = -L$(LIB_DIR) -l$(STATIC_LIB)

# 默认目标
all: $(LIBNAME)

# 生成动态库
$(LIBNAME): $(OBJS)
    $(CC) -shared -o $@ $^ $(LDFLAGS)

# 编译每个源文件为目标文件
%.o: %.c
    $(CC) -fPIC -c $< -o $@ $(INC)

# 清理生成的文件
clean:
    rm -f $(SRC_DIR)/*.o $(LIBNAME)

# 伪目标,防止目录下有clean时clean不被执行
.PHONY: all clean
解释:
变量定义:

CC:编译器使用 gcc。
LIBNAME:生成的动态库文件名。
SRC_DIR:源文件目录。
LIB_DIR:静态库所在目录。
STATIC_LIB:静态库的名称(不包括前缀 lib 和后缀 .a)。
路径和文件:

INC:包含 -I 标志指定的头文件目录。
SRCS:使用 wildcard 函数获取源文件目录中所有的 .c 文件列表。
OBJS:将每个 .c 文件编译为对应的 .o 目标文件列表。
链接和编译规则:

$(LIBNAME):生成动态库的规则,依赖于所有的 .o 目标文件。
%.o: %.c:编译每个源文件为目标文件的规则。
清理规则:

clean:删除所有生成的 .o 文件和动态库文件。
使用方法:
在项目目录中创建以上结构的文件和目录。
将上述 Makefile 的内容复制到 Makefile 文件中。
在命令行中,进入项目目录并运行 make 命令,即可编译生成动态库并链接静态库 libstatic.a。
这个 Makefile 会将 src 目录下的所有 .c 文件编译为动态库 libyour_dynamic_lib.so,并链接静态库 libstatic.a。

三. 测试实例

一个能够生成动态库并链接静态库的 Makefile 需要考虑几个关键点:编译源文件、生成动态库、链接静态库、清理操作等。以下是一个简单的示例 Makefile,假设有一个名为 libstatic.a 的静态库,以及需要编译成动态库的源文件 libdynamic.c

# 编译器设置
CC = gcc
# 静态库路径
LIB_DIR = ./lib

# 动态库生成目标
TARGET = libdynamic.so

# 静态库名称
STATIC_LIB = static

# 编译参数
CFLAGS = -Wall -fPIC
LDFLAGS = -L$(LIB_DIR) -l$(STATIC_LIB)

# 源文件和对象文件
SRCS = libdynamic.c
OBJS = $(SRCS:.c=.o)

# 默认目标
all: $(TARGET)

# 生成动态库
$(TARGET): $(OBJS)
	$(CC) -shared -o $@ $^ $(LDFLAGS)

# 编译每个源文件为对象文件
%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@

# 清理操作
clean:
	rm -f $(OBJS) $(TARGET)

# 伪目标,避免和同名文件冲突
.PHONY: all clean
解释说明:
变量设置:

CC:编译器选择为 gcc。
LIB_DIR:静态库所在目录,可以根据实际情况修改。
TARGET:生成的动态库文件名。
STATIC_LIB:静态库的名称,假设为 libstatic.a 中的 lib 和 static 部分。
编译参数:

CFLAGS:编译参数,包括 -Wall(显示警告)和 -fPIC(生成位置独立的代码)。
LDFLAGS:链接参数,指定静态库的路径和名称。
目标规则:

all:默认目标,依赖于 $(TARGET),即生成动态库。
$(TARGET):生成动态库的规则,使用 -shared 参数生成动态库,链接静态库 $(STATIC_LIB)。
编译每个源文件:

%.o: %.c:将每个 .c 源文件编译为 .o 对象文件,使用 $< 表示依赖的源文件,$@ 表示目标文件。
清理操作:

clean:删除生成的对象文件 .o 和动态库文件 $(TARGET)。
伪目标:

.PHONY:声明 all 和 clean 是伪目标,避免与同名文件发生冲突。
使用方法:
在同一目录下创建 Makefile,将上述内容复制进去。
确保静态库 libstatic.a 放置在 ./lib 目录下(或者根据需要修改 LIB_DIR 变量)。
执行 make 命令即可生成动态库文件 libdynamic.so。
这个 Makefile 简单地展示了如何编译动态库并链接静态库,可以根据实际需求进行调整和扩展。

四. 测试实例

##假设动态库名为libdynamic.so,静态库名为libstatic.a

CC := gcc
CFLAGS := -Wall -I./include

# 动态库相关
LIB_SRC := src/lib.c
LIB_OBJ := lib.o
LIB_NAME := dynamic
LIB_SO := lib$(LIB_NAME).so

# 主程序相关
MAIN_SRC := src/main.c
MAIN_OBJ := main.o
MAIN_EXEC := main

# 静态库相关
STATIC_LIB := static_lib/libstatic.a

.PHONY: all clean

all: $(LIB_SO) $(MAIN_EXEC)

# 编译动态库
$(LIB_SO): $(LIB_OBJ)
	$(CC) -shared -o $@ $^

$(LIB_OBJ): $(LIB_SRC)
	$(CC) $(CFLAGS) -fPIC -c $< -o $@

# 编译主程序
$(MAIN_EXEC): $(MAIN_OBJ)
	$(CC) $(CFLAGS) -o $@ $^ -L./static_lib -lstatic

$(MAIN_OBJ): $(MAIN_SRC)
	$(CC) $(CFLAGS) -c $< -o $@

clean:
	rm -f $(LIB_OBJ) $(MAIN_OBJ) $(LIB_SO) $(MAIN_EXEC)
解释一下这个Makefile的关键部分:

CC 和 CFLAGS 分别是编译器和编译选项。-I./include 用于指定头文件目录。
LIB_SRC 和 MAIN_SRC 分别定义了动态库和主程序的源文件路径。
LIB_OBJ 和 MAIN_OBJ 是对应的目标文件。
LIB_NAME 定义了动态库的名称。
LIB_SO 是生成的动态库文件名。
STATIC_LIB 定义了静态库文件的路径。
all 是默认目标,依赖于 $(LIB_SO) 和 $(MAIN_EXEC),即生成动态库和主程序。
$(LIB_SO) 的生成规则使用 -shared 选项生成动态库。
$(LIB_OBJ) 的生成规则使用 -fPIC 选项生成位置无关代码。
$(MAIN_EXEC) 的链接规则中使用了 -L./static_lib 指定静态库的搜索路径,-lstatic 指定链接静态库 libstatic.a。
使用这个Makefile,你可以在项目目录下执行 make 命令来生成动态库和主程序,执行 make clean 来清理生成的目标文件和库文件。

五. 测试实例

CC := gcc
CFLAGS := -Wall -I./include

# 动态库相关
LIB_SRC := src/lib.c
LIB_OBJ := lib.o
LIB_NAME := dynamic
LIB_SO := lib$(LIB_NAME).so

# 主程序相关
MAIN_SRC := src/main.c
MAIN_OBJ := main.o
MAIN_EXEC := main

# 静态库相关
STATIC_LIB := static_lib/libstatic.a

.PHONY: all clean

all: $(LIB_SO) $(MAIN_EXEC)

# 编译动态库
$(LIB_SO): $(LIB_OBJ)
	$(CC) -shared -o $@ $^

$(LIB_OBJ): $(LIB_SRC)
	$(CC) $(CFLAGS) -fPIC -c $< -o $@

# 编译主程序
$(MAIN_EXEC): $(MAIN_OBJ)
	$(CC) $(CFLAGS) -o $@ $^ -L./static_lib -lstatic

$(MAIN_OBJ): $(MAIN_SRC)
	$(CC) $(CFLAGS) -c $< -o $@

clean:
	rm -f $(LIB_OBJ) $(MAIN_OBJ) $(LIB_SO) $(MAIN_EXEC)
解释:

变量定义:

CC:编译器
CFLAGS:编译选项,包括 -Wall (显示警告)和 -I./include (头文件搜索路径)
文件路径定义:

LIB_SRC:动态库源文件路径
MAIN_SRC:主程序源文件路径
STATIC_LIB:静态库文件路径
目标和依赖关系:

all:默认目标,依赖于 $(LIB_SO) 和 $(MAIN_EXEC),生成动态库和主程序
$(LIB_SO):生成动态库的规则,使用 -shared 选项生成动态库
$(LIB_OBJ):生成动态库的目标文件规则,使用 -fPIC 生成位置无关的代码
$(MAIN_EXEC):生成主程序的规则,链接动态库和静态库
clean:清理生成的目标文件和库文件
编译过程:

编译动态库的源文件 lib.c 到目标文件 lib.o,然后链接为动态库 libdynamic.so
编译主程序的源文件 main.c 到目标文件 main.o,然后链接动态库 libdynamic.so 和静态库 libstatic.a
使用方法:

在项目目录下直接执行 make 命令将会编译生成动态库和主程序。
执行 make clean 将会清理生成的目标文件和库文件。

小结

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值