Clang 如何为苹果M1构建LLVM(叮当、叮当和#x2B;+;)?

Clang 如何为苹果M1构建LLVM(叮当、叮当和#x2B;+;)?,clang,llvm,macos-big-sur,apple-silicon,Clang,Llvm,Macos Big Sur,Apple Silicon,我正在尝试构建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' \

我正在尝试构建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
然后,忍者可以成功地构建clang、clang++和OpenMp运行时并安装它们。(简单来说,针对Arms64的Arm64图像)

这一切看起来都很正常,只是当我试图用它们编译任何东西时,它们缺少获取系统头的include路径

$ ~/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.
$~/software/clang-12.0.0/arm64/bin/clang hello.c
hello.c:1:10:致命错误:“未找到stdio.h”文件
#包括
^~~~~~~~~
生成1个错误。
那么在那之后,

  • 有人知道如何解决包含路径的问题吗
  • 有人知道如何为编译器(和库)配置和构建fat二进制文件,以便x86_64嵌入式编译器以x86_64和aarch64二进制文件aarch64为目标吗?(这就是Xcode铿锵和铿锵++所做的…) 我的尝试以编译器fat二进制文件结束,其中两种体系结构都以x86_64为目标:-(

  • 谢谢

    您可以在构建时设置
    -DDEFAULT\u SYSROOT=/path/to/MacOSX11.1.sdk
    ,或者在运行时导出SDKROOT=/path/to/MacOSX11.1.sdk


    您需要使用
    clang-arch-arm64-arch x86\u 64进行编译,以从clang中获得一个胖二进制文件。您也需要为Apple clang执行此操作。

    我能够使用-DDEFAULT\u SYSROOT=“$(xcrun--show sdk path)”进行编译-DCMAKE_INSTALL_PREFIX=/Users/foo/lokal/并安装到lokal/bin-lokal/lib路径中。完成后,您可以使用LD_-LIBRARY_路径=/Users/foo/lokal/lib,所有库都应该被找到,而不会与任何其他rpath相关。

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

    预酿答案

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

    完整的配方,然后使用此脚本进行配置,然后构建和安装

    # 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

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

    #
    # 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 $*
    

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

    感谢您的回答。我已经尝试了-DDEFAULT\u SYSROOT=“$(xcrun--show sdk path)”我可以用新编译器编译代码,但编译后的代码不会链接到OpenMP运行时,因为新编译器不包含自己的库路径,而只包含系统路径。如果我通过显式使用-L强制执行,代码会链接,但不会运行,因为RPATH也没有设置。您可以在更改默认值,然后看看会发生什么。我真的不想更改LLVM代码,除非这是必需的,因为这似乎不需要(至少在构建单个体系结构编译器时)。此外,这与OpenMP无关;这只是第一个导致问题的库…因此,破解一个特例似乎是错误的答案。这应该可以用正确的神奇CMAKE标志解决:-)这组标志是我使用的,但(如我前面所说)它不会自动搜索非系统库路径(在CMAKE_INSTALL_前缀路径中)这样在链接时就找不到libomp.dylib之类的库(在Apple编译器中不存在)。此外,要求设置LD_LIBRARY_路径是一种不需要的黑客行为。这可能是一个愚蠢的问题,但在Linux和for M1上交叉编译现在不可能了吗?
    #
    # 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 $*