You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

在Linux Alpine环境下编译LLVM 6遇到的问题求助

在Alpine Linux Docker容器中搞定LLVM 6 + Clang + libc++环境的方案

嘿,我来帮你拆解你遇到的问题——本质上是LLVM 6对Alpine默认的musl libc支持不完善,再加上Alpine自带的GCC版本和LLVM 6的编译选项不兼容导致的。下面详细说原因和解决办法:

为啥会报错?

  1. strtoll_l/strtoull_l未声明:这俩是Glibc独有的函数,而Alpine用的musl libc根本没提供它们。LLVM 6的代码里直接调用了这些Glibc专属函数,完全没考虑musl的情况,所以编译肯定炸。
  2. -Wno-noexcept-type警告搞砸编译:Alpine的GCC版本一般比LLVM 6发布时的版本新不少,这个警告选项是新GCC才有的,LLVM 6的CMake配置没处理这个,结果警告被当成错误直接终止编译了(大概率是开了-Werror)。

两种解决路径,按需选

路径一:硬改LLVM 6源码适配musl(非要用6的话)

如果必须死守LLVM 6,可以这么操作:

  1. 替换Glibc特有的函数
    找到报错的locale相关文件(比如llvm/lib/Support/Locale.cpp),把strtoll_lstrtoull_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
    
  2. 调整CMake编译参数
    执行cmake的时候,把那个讨厌的警告关掉,同时关闭-Werror避免警告变错误:
    cmake -G "Unix Makefiles" \
      -DCMAKE_CXX_FLAGS="-Wno-noexcept-type" \
      -DCMAKE_C_FLAGS="-Wno-noexcept-type" \
      -DLLVM_ENABLE_WERROR=OFF \
      ../llvm
    
  3. 补全依赖
    除了你装的build-basepythonzlib,还得装cmakelibedit-devncurses-dev这些,不然编译到后面还会缺东西:
    apk add cmake libedit-dev ncurses-dev subversion
    

路径二:用官方包或更新LLVM版本(强烈推荐)

LLVM 6是2018年的老古董了,Alpine仓库里其实有现成的预编译包,或者换个新点的LLVM版本(比如10+),对musl的支持已经很完善了:

  1. 直接装官方包
    如果不需要自定义编译,直接装仓库里的包就行。注意:Alpine新版本可能已经移除了LLVM 6,得对应找老版本的仓库,比如Alpine 3.10左右的版本还能装:
    apk add llvm6 clang6 libc++6-dev
    
    要是你的Alpine版本新,找不到LLVM 6,不如直接装更新的版本,比如LLVM 15:
    apk add llvm15 clang15 libc++15-dev
    
  2. 编译新版本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

火山引擎 最新活动