预知:
我对此也有同样的错觉:“如果 llvm 的目标是包括 riscv 在内的所有后端,我们应该能够编译我们的代码,只需给出一个 clang 标志,例如--target=riscv32
, -target riscv64
等等,无需进行额外的操作”,我有类似的问题 https://stackoverflow.com/questions/66285885/clang-compiler-couldnt-find-c-c-standard-libraries-when-i-gave-a-spesific-tar,但事实并非如此。虽然LLVM支持riscv目标,但您需要指定sysroot https://stackoverflow.com/questions/39920712/what-is-a-sysroot-exactly-and-how-do-i-create-one and 海湾合作委员会工具链 https://stackoverflow.com/questions/50307733/what-is-a-gcc-toolchain要使用 riscv 标头和库,换句话说,您需要cross compilation
。 (因为你当前运行的是 x86-64 等与 riscv 不同的系统,并且你的默认库也不同)这就是为什么你需要链接你的riscv-gnu-toolchain
路径。在这里我假设你建立了你的riscv-gnu-工具链 https://github.com/riscv/riscv-gnu-toolchain来自 github 克隆。
Note: 有些人对第一个选项 (1) 有问题,请首先尝试使用其他选项 (2) (3) (4)。 (看看评论。)
解决方案:
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"
之后,您应该能够像以下示例一样编译代码:
For C:
/home/shc/llvm/llvm-project/build/bin/clang -march=rv64gc hello_world.c -o hello_world
For C++:
/home/shc/llvm/llvm-project/build/bin/clang++ -march=rv64gc hello_world.cpp -o hello_world
如果您没有使用 cmake 标志设置默认目标三重,target
选项应保留:
For C:
/home/shc/llvm/llvm-project/build/bin/clang --target=riscv64 -march=rv64gc hello_world.c -o hello_world
For C++:
/home/shc/llvm/llvm-project/build/bin/clang++ --target=riscv64 -march=rv64gc hello_world.cpp -o hello_world
2-)你可以通过sysroot https://stackoverflow.com/questions/39920712/what-is-a-sysroot-exactly-and-how-do-i-create-one and 海湾合作委员会工具链 https://stackoverflow.com/questions/50307733/what-is-a-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
flag),尽管它并不比上述选项更健康。 (注意:区别仅在于linux
关键字,通常是-target riscv32-unknown-elf
):
对于 32 位 riscv:
-target riscv32-unknown-linux-elf
对于 64 位 riscv:
-target riscv64-unknown-linux-elf
4-)您可以使用riscv-llvm 仓库 https://github.com/sifive/riscv-llvm遵循给定的说明,尽管它已经过时了。
Note:我根据您的示例调整了我的文件位置,以便更好地理解。
您可以在这里查看更多信息:https://github.com/lowRISC/riscv-llvm#how-can-i-build-upstream-llvmclang-and-use-it-to-cross-compile-for-a-riscv32-target https://github.com/lowRISC/riscv-llvm#how-can-i-build-upstream-llvmclang-and-use-it-to-cross-compile-for-a-riscv32-target