预知:
我对此有同样的错觉:“如果 llvm 的目标是包括 riscv 在内的所有后端,我们应该能够编译我们的代码,只需给出一个像 --target=riscv32、-target riscv64 等的 clang 标志,而不需要做额外的操作”和我有similar question,但不是那样的。虽然 LLVM 支持 riscv 目标,但您需要指定 sysroot 和 gcc toolchain 才能使用 riscv 头文件和库,换句话说,您需要 cross compilation。 (因为您当前运行的系统像 x86-64 与 riscv 不同,并且您的默认库不同)这就是为什么您需要链接您的 riscv-gnu-toolchain 路径。在这里,我假设您从 github 克隆构建了您的 riscv-gnu-toolchain。
注意: 有些人第一个选项(1)有问题,请先尝试使用其他选项(2)(3)(4)。 (查看 cmets。)
解决方案:
1-)您可以在构建 llvm 库之前将这些行添加为您的 cmake 配置标志:
对于 32 位 riscv:
-DDEFAULT_SYSROOT="{your-riscv-gnu-toolchain-install-or-build-path}/riscv32-unknown-elf"
-DGCC_INSTALL_PREFIX="{your-riscv-gnu-toolchain-install-or-build-path}"
对于 64 位 riscv:
-DDEFAULT_SYSROOT="{your-riscv-gnu-toolchain-install-or-build-path}/riscv64-unknown-elf"
-DGCC_INSTALL_PREFIX="{your-riscv-gnu-toolchain-install-or-build-path}"
然后再次构建 llvm 库。可能如您所知,在您的 llvm 构建目录中:
cmake --build .
根据您的 cmake 配置,这是我的示例:
cmake -G "Unix Makefiles" \
-DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;libcxx;libcxxabi;libunwind;lldb;compiler-rt;lld;polly;debuginfo-tests" \
-DCMAKE_BUILD_TYPE=Debug \
-DLLVM_ENABLE_ASSERTIONS=On \
-DDEFAULT_SYSROOT="/home/shc/riscv/install/riscv64-unknown-elf" \
-DGCC_INSTALL_PREFIX="/home/shc/riscv/install" \
../llvm
cmake --build .
您还可以使用另一个 cmake 配置标志将默认目标三元组设置为 riscv:
对于 32 位 riscv:
-DLLVM_DEFAULT_TARGET_TRIPLE="riscv32-unknown-elf"
对于 64 位 riscv:
-DLLVM_DEFAULT_TARGET_TRIPLE="riscv64-unknown-elf"
在此之后,您应该能够像以下示例一样编译您的代码:
对于 C:
/home/shc/llvm/llvm-project/build/bin/clang -march=rv64gc hello_world.c -o hello_world
对于 C++:
/home/shc/llvm/llvm-project/build/bin/clang++ -march=rv64gc hello_world.cpp -o hello_world
如果您没有使用 cmake 标志设置默认目标三元组,则应保留 target 选项:
对于 C:
/home/shc/llvm/llvm-project/build/bin/clang --target=riscv64 -march=rv64gc hello_world.c -o hello_world
对于 C++:
/home/shc/llvm/llvm-project/build/bin/clang++ --target=riscv64 -march=rv64gc hello_world.cpp -o hello_world
2-) 您可以在编译代码时将sysroot 和gcc toolchain 作为标志传递(如上面的cmake 配置),而无需再次构建库。但是,如果您要使用它,则需要在每次编译中提供这些标志:
对于 32 位 riscv:
--sysroot="{your-riscv-gnu-toolchain-install-or-build-path}/riscv32-unknown-elf"
--gcc-toolchain="{your-riscv-gnu-toolchain-install-or-build-path}"
对于 64 位 riscv:
--sysroot="{your-riscv-gnu-toolchain-install-or-build-path}/riscv64-unknown-elf"
--gcc-toolchain="{your-riscv-gnu-toolchain-install-or-build-path}"
C 的标志用法:
/home/shc/llvm/llvm-project/build/bin/clang --sysroot=/home/shc/riscv/install/riscv64-unknown-elf --gcc-toolchain=/home/shc/riscv/install --target=riscv64 -march=rv64gc hello_world.c -o hello_world
C++ 中标志的使用:
/home/shc/llvm/llvm-project/build/bin/clang++ --sysroot=/home/shc/riscv/install/riscv64-unknown-elf --gcc-toolchain=/home/shc/riscv/install --target=riscv64 -march=rv64gc hello_world.cpp -o hello_world
3-) 您可以尝试在编译时传递这些标志(而不是您的--target=riscv64 标志),尽管它并不比上述选项更健康。 (注意:区别只是linux关键字,一般是-target riscv32-unknown-elf):
对于 32 位 riscv:
-target riscv32-unknown-linux-elf
对于 64 位 riscv:
-target riscv64-unknown-linux-elf
4-)您可以按照给定的说明使用riscv-llvm repo,尽管它已经过时了。
注意:我根据您的示例调整了我的文件位置,以便更好地理解。
您可以在这里查看更多信息:https://github.com/lowRISC/riscv-llvm#how-can-i-build-upstream-llvmclang-and-use-it-to-cross-compile-for-a-riscv32-target