【问题标题】:How to build LLVM (clang,clang++) for Apple M1?如何为 Apple M1 构建 LLVM(clang、clang++)?
【发布时间】:2020-12-14 17:06:55
【问题描述】:

我正在尝试构建 LLVM 编译器,以便可以在 Apple M1 上启用 OpenMP。 我正在使用 LLVM 开发树,(因为我最近看到一些 OpenMP 运行时为此使用)。

我最终得到了这个脚本来调用 cmake:

# Xcode, Ninja
BUILD_SYSTEM=Ninja
BUILD_TAG=Ninja

cmake ../llvm \
      -G$BUILD_SYSTEM -B ${BUILD_TAG}_build \
      -DCMAKE_OSX_ARCHITECTURES='arm64' \
      -DCMAKE_C_COMPILER=`which clang` \
      -DCMAKE_CXX_COMPILER=`which clang++` \
      -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_BUILD_WITH_INSTALL_RPATH=1 \
      -DCMAKE_INSTALL_PREFIX=$HOME/software/clang-12.0.0/arm64 \
      -DLLVM_ENABLE_WERROR=FALSE \
      -DLLVM_TARGETS_TO_BUILD='AArch64' \
      -DLLVM_ENABLE_PROJECTS='clang;openmp,polly' \
      -DLLVM_DEFAULT_TARGET_TRIPLE='aarch64-apple-darwin20.1.0'

这里使用的编译器是

$ /usr/bin/clang --version
Apple clang version 12.0.0 (clang-1200.0.32.27)
Target: arm64-apple-darwin20.1.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

ninja 然后可以成功构建 clang、clang++ 和 OpenMp 运行时并安装它们。 (很简单,针对 Arms64 的 Arm64 图像)

$ file ~/software/clang-12.0.0/arm64/bin/clang
/Users/jcownie/software/clang-12.0.0/arm64/bin/clang: Mach-O 64-bit executable arm64
$ ~/software/clang-12.0.0/arm64/bin/clang --version
clang version 12.0.0 (https://github.com/llvm/llvm-project.git 879c15e890b4d25d28ea904e92497f091f796019)
Target: aarch64-apple-darwin20.1.0
Thread model: posix
InstalledDir: /Users/jcownie/software/clang-12.0.0/arm64/bin

这一切看起来都很正常,除了当我尝试用它们编译任何东西时,它们缺少获取系统头文件的包含路径。

$ ~/software/clang-12.0.0/arm64/bin/clang hello.c
hello.c:1:10: fatal error: 'stdio.h' file not found
#include <stdio.h>
         ^~~~~~~~~
1 error generated.

所以,毕竟,

  1. 有人知道如何解决包含路径问题吗?
  2. 有谁知道如何为编译器(和库)配置和构建胖二进制文件,以便 x86_64 嵌入式编译器以 x86_64 和 aarch64 二进制文件 aarch64 为目标? (这就是 Xcode clang 和 clang++ 所做的......) 我对此的尝试最终得到了一个编译器胖二进制文件,其中两种架构都针对 x86_64 :-(

谢谢

【问题讨论】:

    标签: clang llvm macos-big-sur apple-silicon


    【解决方案1】:

    您可以在构建时设置-DDEFAULT_SYSROOT=/path/to/MacOSX11.1.sdk 或在运行时设置export SDKROOT=/path/to/MacOSX11.1.sdk

    您需要使用clang -arch arm64 -arch x86_64 编译才能从clang 中获得一个胖二进制文件。您也需要为 Apple clang 执行此操作。

    【讨论】:

    • 感谢您的回答。我已经尝试使用 -DDEFAULT_SYSROOT="$(xcrun --show-sdk-path)" 并且只是尝试构建一个 Arm 目标,但这仍然不能完全工作。我可以使用新编译器编译代码,但编译后的代码不会链接到 OpenMP 运行时,因为新编译器不包含自己的库路径,而只包含系统路径。如果我通过显式使用 -L 强制执行此操作,则代码会链接,但不会运行,因为 RPATH 也未设置。
    • 您可以在github.com/llvm/llvm-project/blob/… 更改默认值,看看会发生什么。
    • 我真的不想更改 LLVM 代码,除非这是必要的,因为这似乎并不需要(至少构建一个单一架构编译器)。这也与 OpenMP 无关;那只是第一个引起问题的库……因此为此破解一个特殊情况似乎是错误的答案。这肯定可以用正确的魔法 CMAKE 标志解决:-)
    【解决方案2】:

    2021 年 2 月 8 日更新 Homebrew 现在支持基于 M1 的 Arm 机器,因此使用它是比下面的更好的答案。 如果您想自己执行此操作,以下信息可能仍然有用,但使用 brew 可能会简单得多。

    预煮答案

    我还没有找到一个干净的解决方案,但如果它对其他人有帮助,我确实有一个可怕的 hack。

    完整的配方,然后是用这个脚本配置,然后构建和安装。

    # Xcode, Ninja
    BUILD_SYSTEM=Ninja
    BUILD_TAG=ninja
    INSTALLDIR=$HOME/software/clang-12.0.0/arm64
    
    cmake ../llvm \
          -G$BUILD_SYSTEM -B ${BUILD_TAG}_build \
          -DCMAKE_OSX_ARCHITECTURES='arm64' \
          -DCMAKE_C_COMPILER=`which clang` \
          -DCMAKE_CXX_COMPILER=`which clang++` \
          -DCMAKE_BUILD_TYPE=Release \
          -DCMAKE_INSTALL_PREFIX=$INSTALLDIR \
          -DLLVM_LOCAL_RPATH=$INSTALLDIR/lib \
          -DLLVM_ENABLE_WERROR=FALSE \
          -DLLVM_TARGETS_TO_BUILD='AArch64' \
          -DLLVM_DEFAULT_TARGET_TRIPLE='aarch64-apple-darwin20.1.0' \
          -DDEFAULT_SYSROOT="$(xcrun --show-sdk-path)" \
          -DLLVM_ENABLE_PROJECTS='clang;openmp;polly;clang-tools-extra;libcxx;libcxxabi' \
    #      -DLLVM_ENABLE_PROJECTS='clang;openmp;polly' 
    

    这使编译器可以找到正确的标头,但如果使用 OpenMP,则不会成功链接,因为它不会传递任何有用的 -L 路径或添加必要的 rpath。

    为了克服这个问题,我在~/bin$PATH 前面创建了一个小的shell 脚本,它添加了那些额外的链接器标志。

    #
    # A truly awful hack, but it seems necessary.
    # Install this with execute permissions as clang and clang++ in
    # a directory early in your path, so that it is executed when clang or
    # clang++ is needed.
    #
    # For brew...
    INSTALLDIR=/usr/local/opt/llvm
    # For a local build.
    INSTALLDIR=${HOME}/software/clang-12.0.0/arm64/
    
    # Find out the name of this file, and then invoke the same file in the
    # compiler installation, adding the necessary linker directives
    CMD=`echo $0 | sed "s/\/.*\///"`
    ${INSTALLDIR}/bin/${CMD} -L${INSTALLDIR}/lib -Wl,-rpath,${INSTALLDIR}/lib $*
    

    我不特别推荐这个;显然应该有更好的方法让它工作,但它现在就可以了,让我回到使用编译器而不是构建它!

    【讨论】:

    • 这可能是一个愚蠢的问题,但是现在在 Linux 和 M1 上进行 交叉编译 是不可能的吗?
    【解决方案3】:

    我能够使用 -DDEFAULT_SYSROOT="$(xcrun --show-sdk-path)" -DCMAKE_INSTALL_PREFIX=/Users/foo/lokal/ 构建并安装到 lokal/bin lokal/lib 路径。完成后,您可以使用 LD_LIBRARY_PATH=/Users/foo/lokal/lib 并且应该找到所有库,而无需与其他任何与 rpath 相关的内容。

    【讨论】:

    • 这组标志是我使用过的,但是(正如我之前所说)它不会自动搜索非系统库路径(在 CMAKE_INSTALL_PREFIX 路径内)所以库,如 libomp。在链接时找不到 dylib(Apple 编译器中不存在)。此外,要求设置 LD_LIBRARY_PATH 是一种不应该被要求的技巧。
    猜你喜欢
    • 1970-01-01
    • 2020-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-17
    • 2020-01-19
    • 2014-03-05
    • 1970-01-01
    相关资源
    最近更新 更多