如何修改Makefile使make找到libevdev库解决编译链接错误
问题根因
该编译错误是GNU链接器的参数顺序规则导致的:-levdev这类动态库链接参数必须放在待解析符号的目标文件(.o文件)之后,链接器才能正确匹配到库中的符号定义。Raspbian 10携带的ld版本对参数顺序要求宽松,所以能正常编译,而Ubuntu 20.04的新版ld执行严格的顺序校验,因此报错。
同时原Makefile存在冗余问题:编译生成.o目标文件的阶段不需要传入链接库参数,仅在最终生成可执行文件的链接阶段需要。
修改方案
调整Makefile中链接参数的位置,把$(LIBRARIES)移到链接命令的末尾,同时清理编译阶段的冗余参数。如果要适配不同发行版的libevdev路径,还可以用pkg-config自动获取编译和链接参数,避免硬编码路径。
修正后的完整Makefile
CC := gcc XFLAGS := -Wall -std=c11 -D_POSIX_C_SOURCE=199309L # 用pkg-config自动获取evdev的编译和链接参数,适配不同发行版路径 INCLUDES := $(shell pkg-config --cflags libevdev) LIBRARIES := $(shell pkg-config --libs libevdev) # 编译阶段不需要传入链接库参数 CFLAGS := $(XFLAGS) $(INCLUDES) OUTDIR := out SOURCES := uinput.c input.c rce.c OBJS := $(SOURCES:%.c=$(OUTDIR)/%.o) TARGET := $(OUTDIR)/evdev-rce .PHONY: all clean $(OUTDIR)/%.o: %.c @mkdir -p $(OUTDIR) $(CC) $(CFLAGS) -c $< -o $@ $(TARGET): $(OBJS) # 链接阶段把库参数放在目标文件之后 $(CC) $(CFLAGS) $^ -o $@ $(LIBRARIES) all: $(TARGET) clean: rm -rf $(OUTDIR)
如果你的系统没有安装pkg-config,也可以保留原来的硬编码路径,仅调整参数顺序即可:
CC := gcc XFLAGS := -Wall -std=c11 -D_POSIX_C_SOURCE=199309L LIBRARIES := -levdev INCLUDES := -I/usr/include/libevdev-1.0 # 移除编译参数中的库链接选项 CFLAGS := $(XFLAGS) $(INCLUDES) OUTDIR := out SOURCES := uinput.c input.c rce.c OBJS := $(SOURCES:%.c=$(OUTDIR)/%.o) TARGET := $(OUTDIR)/evdev-rce .PHONY: all clean $(OUTDIR)/%.o: %.c @mkdir -p $(OUTDIR) $(CC) $(CFLAGS) -c $< -o $@ $(TARGET): $(OBJS) # 链接时把库放在最后 $(CC) $(CFLAGS) $^ -o $@ $(LIBRARIES) all: $(TARGET) clean: rm -rf $(OUTDIR)
修改后重新执行make即可正常编译。
内容的提问来源于stack exchange,提问作者compilebunny
相关产品推荐
相关产品推荐

