在Linux Alpine环境下编译LLVM 6遇到的问题求助
在Alpine Linux Docker容器中搞定LLVM 6 + Clang + libc++环境的方案
嘿,我来帮你拆解你遇到的问题——本质上是LLVM 6对Alpine默认的musl libc支持不完善,再加上Alpine自带的GCC版本和LLVM 6的编译选项不兼容导致的。下面详细说原因和解决办法:
为啥会报错?
strtoll_l/strtoull_l未声明:这俩是Glibc独有的函数,而Alpine用的musl libc根本没提供它们。LLVM 6的代码里直接调用了这些Glibc专属函数,完全没考虑musl的情况,所以编译肯定炸。-Wno-noexcept-type警告搞砸编译:Alpine的GCC版本一般比LLVM 6发布时的版本新不少,这个警告选项是新GCC才有的,LLVM 6的CMake配置没处理这个,结果警告被当成错误直接终止编译了(大概率是开了-Werror)。
两种解决路径,按需选
路径一:硬改LLVM 6源码适配musl(非要用6的话)
如果必须死守LLVM 6,可以这么操作:
- 替换Glibc特有的函数:
找到报错的locale相关文件(比如llvm/lib/Support/Locale.cpp),把strtoll_l和strtoull_l换成musl支持的标准函数。最简单的是加个兼容宏:// 在文件开头加这个 #ifdef __MUSL__ #define strtoll_l(nptr, endptr, base) strtoll(nptr, endptr, base) #define strtoull_l(nptr, endptr, base) strtoull(nptr, endptr, base) #endif - 调整CMake编译参数:
执行cmake的时候,把那个讨厌的警告关掉,同时关闭-Werror避免警告变错误:cmake -G "Unix Makefiles" \ -DCMAKE_CXX_FLAGS="-Wno-noexcept-type" \ -DCMAKE_C_FLAGS="-Wno-noexcept-type" \ -DLLVM_ENABLE_WERROR=OFF \ ../llvm - 补全依赖:
除了你装的build-base、python、zlib,还得装cmake、libedit-dev、ncurses-dev这些,不然编译到后面还会缺东西:apk add cmake libedit-dev ncurses-dev subversion
路径二:用官方包或更新LLVM版本(强烈推荐)
LLVM 6是2018年的老古董了,Alpine仓库里其实有现成的预编译包,或者换个新点的LLVM版本(比如10+),对musl的支持已经很完善了:
- 直接装官方包:
如果不需要自定义编译,直接装仓库里的包就行。注意:Alpine新版本可能已经移除了LLVM 6,得对应找老版本的仓库,比如Alpine 3.10左右的版本还能装:
要是你的Alpine版本新,找不到LLVM 6,不如直接装更新的版本,比如LLVM 15:apk add llvm6 clang6 libc++6-devapk add llvm15 clang15 libc++15-dev - 编译新版本LLVM:
要是必须自定义编译,选LLVM 10及以上版本就行,这些版本已经修复了musl兼容问题,不用改源码。步骤和你之前差不多:- 从SVN/Git拉对应版本的LLVM、Clang、libcxx
- 装依赖:
apk add build-base python3 zlib-dev cmake libedit-dev ncurses-dev - 正常执行cmake和make就行,不会再遇到之前的错误
验证环境是否能用
不管用哪种方法,搞定之后可以用下面的命令验证:
# 看Clang版本 clang --version # 编译个简单程序试试libc++ echo "#include <iostream> int main() { std::cout << \"LLVM works!\" << std::endl; return 0; }" > test.cpp clang++ -stdlib=libc++ test.cpp -o test ./test
要是输出LLVM works!,说明环境没问题啦。
内容的提问来源于stack exchange,提问作者Matteo Monti




