Alpine容器中使用Clang动态链接so文件失败求助
问题:Alpine容器中Clang链接jansson共享库失败,Arch/Ubuntu环境正常
在Alpine容器中使用Clang构建调用jansson共享库的C程序时,出现undefined reference to 'json_object'的链接错误,但相同代码和操作在Archlinux或Ubuntu容器中可正常完成构建。
测试C代码
#include <jansson.h> #include <stdio.h> int main(void) { printf("Hello, world!\n"); // 调用共享库中的函数 json_object(); return 0; }
使用的Makefile
CC = clang CFLAGS = -Wall -Wextra -O2 DEPS = $(wildcard *.h) SRC = $(wildcard *.c) OBJ = $(SRC:.c=.o) TARGET = app %.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) $(TARGET): $(OBJ) $(CC) -v -L /usr/lib -ljansson -o app $^ $(CFLAGS) .PHONY: clean clean: rm -f $(OBJ) $(TARGET)
操作步骤
- 启动Alpine容器:
docker run --rm -it -v $PWD:/work -w /work alpine - 安装依赖:
apk update apk add clang make jansson-dev - 执行
make构建时出现链接错误:
/work # make clang -c -o main.o main.c -Wall -Wextra -O2 clang -v -L /usr/lib -ljansson -o app main.o -Wall -Wextra -O2 Alpine clang version 17.0.5 Target: x86_64-alpine-linux-musl Thread model: posix InstalledDir: /usr/bin Configuration file: /etc/clang17/x86_64-alpine-linux-musl.cfg System configuration file directory: /etc/clang17 Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-alpine-linux-musl/13.2.1 Selected GCC installation: /usr/bin/../lib/gcc/x86_64-alpine-linux-musl/13.2.1 Candidate multilib: .;@m64 Selected multilib: .;@m64 "/usr/bin/ld" -pie -z now -z relro --hash-style=gnu --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib/ld-musl-x86_64.so.1 -o app /usr/lib/Scrt1.o /usr/lib/crti.o /usr/bin/../lib/gcc/x86_64-alpine-linux-musl/13.2.1/crtbeginS.o -L/usr/lib -L/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/13.2.1 -L/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/13.2.1/../../../../x86_64-alpine-linux-musl/lib -L/lib -L/usr/lib --as-needed -ljansson main.o -lssp_nonshared -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/bin/../lib/gcc/x86_64-alpine-linux-musl/13.2.1/crtendS.o /usr/lib/crtn.o /usr/bin/ld: main.o: in function `main': main.c:(.text+0xe): undefined reference to `json_object' clang: error: linker command failed with exit code 1 (use -v to see invocation) make: *** [Makefile:12: app] Error 1
确认库文件存在:
/work # ls /usr/lib/libjansson* /usr/lib/libjansson.so /usr/lib/libjansson.so.4 /usr/lib/libjansson.so.4.14.0
问题原因与解决方法
核心问题:链接库的顺序错误
Alpine使用的musl链接器对链接顺序的要求比glibc(Arch/Ubuntu使用的C库)更严格:当你把-ljansson放在main.o前面时,链接器处理libjansson.so时还没看到需要引用它的目标文件,会直接跳过这个库;而glibc的链接器会做额外的扫描,允许库在目标文件之前。
修改Makefile
将链接命令中的库移到目标文件之后:
$(TARGET): $(OBJ) $(CC) -v -L /usr/lib -o app $^ -ljansson $(CFLAGS)
验证修改
重新执行make即可完成构建,运行./app会输出Hello, world!,且能正确调用jansson库的函数。
内容的提问来源于stack exchange,提问作者Tue Henriksen
相关产品推荐
相关产品推荐

