在Alpine Docker镜像中编译http_load时Make无法找到unistd.h的问题排查与解决
解决Alpine Docker镜像中编译http_load时的
unistd.h缺失问题 问题场景
我尝试在Alpine 3.5镜像中编译http_load工具,使用的Dockerfile内容如下:
FROM alpine:3.5 RUN apk update && apk add wget make gcc linux-headers WORKDIR /home RUN wget http://acme.com/software/http_load/http_load-12mar2006.tar.gz && tar xzf http_load-12mar2006.tar.gz WORKDIR /home/http_load-12mar2006 RUN make
执行编译后出现了如下错误:
http_load.c:28:20: fatal error: unistd.h: No such file or directory #include <unistd.h> ^ compilation terminated. make: *** [Makefile:32: http_load.o] Error 1
我原本以为linux-headers包应该包含该依赖文件,并且确实在路径/usr/include/linux/unistd.h下找到了该文件,但编译还是报错。
问题成因
这里的核心坑点是Alpine Linux使用的是musl libc,而非传统发行版的GNU libc,两者的头文件定位逻辑完全不同:
- 你找到的
/usr/include/linux/unistd.h是内核层面的头文件,属于linux-headers包,它是给编译内核模块用的,根本不是用户态程序编译需要的标准库头文件。 - 用户态C程序编译依赖的
unistd.h是C标准库提供的,在Alpine里这个文件属于musl-dev包,路径是/usr/include/unistd.h。你之前只装了linux-headers,没安装标准库的开发包,所以编译器找不到正确的unistd.h。
解决方法
修改Dockerfile中的apk add命令,把linux-headers替换成musl-dev(如果之后没有内核模块编译需求的话),或者两者都保留也没问题,但编译http_load只需要musl-dev:
修改后的Dockerfile:
FROM alpine:3.5 RUN apk update && apk add wget make gcc musl-dev WORKDIR /home RUN wget http://acme.com/software/http_load/http_load-12mar2006.tar.gz && tar xzf http_load-12mar2006.tar.gz WORKDIR /home/http_load-12mar2006 RUN make && make install # 可以加上make install把工具安装到系统路径,方便直接调用
重新构建镜像并执行编译,就能顺利完成了——musl-dev会提供编译器需要的所有标准库头文件,包括咱们缺的unistd.h。
内容的提问来源于stack exchange,提问作者BiAiB
相关产品推荐
相关产品推荐

