< 返回版块

greedyhao 发表于 2024-04-19 08:57

Tags:gcc

我想使用自定义 gcc 编译程序并生成静态库

我通过创建一个 target 来使用自定义的 gcc,但是编译会报错

这是错误信息

error: data-layout for target `test-15916131297364407962`, `e-m:e-p:32:32-n32-S32`, differs from LLVM target's `riscv32-none-elf-gcc` default layout, `e-m:e-p:32:32-i64:64-n32-S128`

target json 文件如下

{
    "arch": "riscv32",
    "cpu": "generic-rv32",
    "crt-objects-fallback": "false",
    "data-layout": "e-m:e-p:32:32-n32-S32",
    "eh-frame-header": false,
    "emit-debug-gdb-scripts": false,
    "features": "+m,+a,+c",
    "linker": "C:\\Program Files (x86)\\RV32-Toolchain\\RV32-V2\\bin\\riscv32-elf-gcc.exe",
    "linker-flavor": "gcc",
    "llvm-target": "riscv32-none-elf-gcc",
    "max-atomic-width": 0,
    "panic-strategy": "abort",
    "relocation-model": "static",
    "target-pointer-width": "32",
    "pre-link-args": {
        "gcc": [
            "-Wall -march=rv32imacxbs1 -ffunction-sections -fdata-sections -msave-restore -mjump-tables-in-text",
            "-Os"
        ]
    }
}

评论区

写评论
作者 greedyhao 2024-04-19 13:44

好吧,多谢

--
👇
TinusgragLin: 懂了,你的项目用的 rv32 工具链比较特殊,改了 data-layout (和/或其他一些东西),那感觉确实棘手啊,感觉需要给 llvm 改一改编译选项,自己重新编译 llvm 和 rustc......只能祝兄弟好运了。

TinusgragLin 2024-04-19 12:20

懂了,你的项目用的 rv32 工具链比较特殊,改了 data-layout (和/或其他一些东西),那感觉确实棘手啊,感觉需要给 llvm 改一改编译选项,自己重新编译 llvm 和 rustc......只能祝兄弟好运了。

作者 greedyhao 2024-04-19 12:06

但我就是需要修改这个参数

而且还有一些自定义指令也需要gcc这边支持

--
👇
TinusgragLin: 从报错信息来看,应该是说你在 target.json 中指定的 data-layout 和 llvm 默认的 data-layout 不一致吧

--
👇
greedyhao: 不太行,需要用特定的工具链才行,工具链改过 data layout,跟标准的不一样;用标准工具链生成的库没有办法在原先工程中调用

--
👇
TinusgragLin: rust 默认是 llvm backend 的吧,如果是(为了 gcc 的什么特性)要用 gcc 做整个 backend 的话,有 rustc-codegen-gccgccrc 不过都是实验性的。如果只是想要编译成 rv32 程序的话,我看到平台支持列表里已经列出了一些 rv32 架构(不过好像只支持 no-std),楼主应该只需要在这个支持列表中找到你想要的target,下载对应的rust工具链,在 .cargo/config.toml 中配置 target 选项 (主要是 linker 选项)和 默认 target 就可以了。

作者 greedyhao 2024-04-19 12:05

主要还是用不了标准的,看了下 esp32 那边,还需要修改 llvm 源码,感觉好麻烦

--
👇
TinusgragLin: 楼主的这种方式我都没见过,查了一下好像是与给rustc加新的(llvm)支持的target有关的,如果只是要编译 rv32 程序的话应该不用这么复杂?

TinusgragLin 2024-04-19 12:03

从报错信息来看,应该是说你在 target.json 中指定的 data-layout 和 llvm 默认的 data-layout 不一致吧

--
👇
greedyhao: 不太行,需要用特定的工具链才行,工具链改过 data layout,跟标准的不一样;用标准工具链生成的库没有办法在原先工程中调用

--
👇
TinusgragLin: rust 默认是 llvm backend 的吧,如果是(为了 gcc 的什么特性)要用 gcc 做整个 backend 的话,有 rustc-codegen-gccgccrc 不过都是实验性的。如果只是想要编译成 rv32 程序的话,我看到平台支持列表里已经列出了一些 rv32 架构(不过好像只支持 no-std),楼主应该只需要在这个支持列表中找到你想要的target,下载对应的rust工具链,在 .cargo/config.toml 中配置 target 选项 (主要是 linker 选项)和 默认 target 就可以了。

TinusgragLin 2024-04-19 11:58

楼主的这种方式我都没见过,查了一下好像是与给rustc加新的(llvm)支持的target有关的,如果只是要编译 rv32 程序的话应该不用这么复杂?

作者 greedyhao 2024-04-19 11:57

不太行,需要用特定的工具链才行,工具链改过 data layout,跟标准的不一样;用标准工具链生成的库没有办法在原先工程中调用

--
👇
TinusgragLin: rust 默认是 llvm backend 的吧,如果是(为了 gcc 的什么特性)要用 gcc 做整个 backend 的话,有 rustc-codegen-gccgccrc 不过都是实验性的。如果只是想要编译成 rv32 程序的话,我看到平台支持列表里已经列出了一些 rv32 架构(不过好像只支持 no-std),楼主应该只需要在这个支持列表中找到你想要的target,下载对应的rust工具链,在 .cargo/config.toml 中配置 target 选项 (主要是 linker 选项)和 默认 target 就可以了。

作者 greedyhao 2024-04-19 11:55

我在工程中添加了 config.toml

[build]
target = "riscv32imac-unknown-none-elf"
target-dir = "target"
rustflags = ["-C", "linker-flavor=gcc"]

[target.riscv32imac-unknown-none-elf]
linker = "C:\\Program Files (x86)\\RV32-Toolchain\\RV32-V2\\bin\\riscv32-elf-gcc.exe"

[unstable]
build-std = ["core"]

cargo build 可以正常编译,target 下生成了 riscv32imac-unknown-none-elf 对应的目录;但是感觉并没有用到我指定的工具链编译。我故意把 linker 的路径改成错误的,但是它还是可以正常编译

而且这种方式的话,不知道编译参数怎么设置

--
👇
asuper: 相当于交叉编译呗?分享一下我的交叉编译配置

首先是.cargo/config文件,内容如下

[target.arm-unknown-linux-gnueabihf]
linker = "/home/asuper/cross_env/rv1126-toolchain/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc"

编译指令

export PATH=$PATH:/home/asuper/cross_env/rv1126-toolchain/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin
export CC=/home/asuper/cross_env/rv1126-toolchain/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc

cargo build --target arm-unknown-linux-gnueabihf

实际上我写了个编译脚本,里面指定了其他依赖库路径,还能指定编译目标、是否release等

TinusgragLin 2024-04-19 11:55

rust 默认是 llvm backend 的吧,如果是(为了 gcc 的什么特性)要用 gcc 做整个 backend 的话,有 rustc-codegen-gccgccrc 不过都是实验性的。如果只是想要编译成 rv32 程序的话,我看到平台支持列表里已经列出了一些 rv32 架构(不过好像只支持 no-std),楼主应该只需要在这个支持列表中找到你想要的target,下载对应的rust工具链,在 .cargo/config.toml 中配置 target 选项 (主要是 linker 选项)和 默认 target 就可以了。

asuper 2024-04-19 10:32

相当于交叉编译呗?分享一下我的交叉编译配置

首先是.cargo/config文件,内容如下

[target.arm-unknown-linux-gnueabihf]
linker = "/home/asuper/cross_env/rv1126-toolchain/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc"

编译指令

export PATH=$PATH:/home/asuper/cross_env/rv1126-toolchain/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin
export CC=/home/asuper/cross_env/rv1126-toolchain/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc

cargo build --target arm-unknown-linux-gnueabihf

实际上我写了个编译脚本,里面指定了其他依赖库路径,还能指定编译目标、是否release等

1 共 10 条评论, 1 页