Rust 交叉编译到 ARM:链接静态 C 库时未定义对 printf 的引用

问题描述 投票:0回答:1

问题

我正在学习如何在裸机 Rust 项目中进行 C 互操作。我有一个简单的 C 项目,它接受一个结构并打印它。我使用 arm-none-eabi-gcc 编译它以生成 libfoo.a 并将其链接到我的 Rust 项目。

Rust 项目配置为使用

.cargo.config.toml
中的arm gcc 和链接器。我使用 bindgen 生成绑定并通过该绑定调用 C 函数。

我在编译项目时遇到问题。当 Rust 尝试链接静态 C 库时,它会抱怨

error: linking with `arm-none-eabi-gcc` failed: exit status: 1
  |
  = note: LC_ALL="C" PATH="/Users/yuenton/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/bin:/Users/yuenton/.pyenv/shims:/Applica
tions/Simplicity Studio.app/Contents/Eclipse/developer/adapter_packs/commander/Commander.app/Contents/MacOS:/usr/local/opt/ruby/bin:/usr/local/lib/ruby/gems/2.7
.0/bin:/Users/yuenton/workplace/hht-scripts/src/HHTFirmwareScripts/stable/unix:/Applications/cov-analysis-macosx-2022-3-0/bin/:/Applications/SEGGER/JLink_V760h:
/usr/local/opt/gcc-arm-none-eabi-8-2019-q3-update/bin:/Users/yuenton/.toolbox/bin:/Users/yuenton/.nvm/versions/node/v14.20.0/bin:/Users/yuenton/bin:/usr/local/b
in:/opt/homebrew/bin:/opt/homebrew/sbin:/Users/yuenton/.local/share/nvim/mason/bin:/Users/yuenton/.pyenv/bin:/Applications/Simplicity Studio.app/Contents/Eclips
e/developer/adapter_packs/commander/Commander.app/Contents/MacOS:/usr/local/opt/ruby/bin:/usr/local/lib/ruby/gems/2.7.0/bin:/Users/yuenton/workplace/hht-scripts
/src/HHTFirmwareScripts/stable/unix:/Applications/cov-analysis-macosx-2022-3-0/bin/:/Applications/SEGGER/JLink_V760h:/usr/local/opt/gcc-arm-none-eabi-8-2019-q3-
update/bin:/Users/yuenton/.toolbox/bin:/Users/yuenton/.nvm/versions/node/v14.20.0/bin:/Users/yuenton/bin:/usr/local/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/us
r/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/
var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Users/yuen
ton/.cargo/bin:/Applications/kitty.app/Contents/MacOS:/usr/local/opt/fzf/bin" VSLANG="1033" "arm-none-eabi-gcc" "/var/folders/lm/n3lqn5fx2qsddzty2389rfgcfkmffy/
T/rustc5AOqmy/symbols.o" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/app-6d1120295b5167b4.44hpxx6ly2g0n
6p4.rcgu.o" "-Wl,--as-needed" "-L" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps" "-L" "/Volumes/workplac
e/playground/rust_embedded_with_c_interop/app/target/debug/deps" "-L" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/
debug/build/app-fca9b4a0fb47443d/out" "-L" "/usr/local/opt/arm-none-eabi-gcc/gcc/arm-none-eabi/lib" "-L" "./c_proj/build/" "-L" "/Volumes/workplace/playground/r
ust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/build/cortex-m-c1b153b4741594d3/out" "-L" "/Volumes/workplace/playground/rust_embedded_with_c_in
terop/app/target/thumbv7m-none-eabi/debug/build/cortex-m-rt-feabb8431baf6f6c/out" "-L" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/th
umbv7m-none-eabi/debug/build/cortex-m-semihosting-3928837b527a45a9/out" "-L" "/Users/yuenton/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/thumbv7m-
none-eabi/lib" "-Wl,-Bstatic" "-lfoo" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libcty-580a16e85c8469
02.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libcortex_m_rt-c96c0df2d2e53803.rlib" "/Volumes/wo
rkplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libr0-c044695858752b9f.rlib" "/Volumes/workplace/playground/rust_embedd
ed_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libcortex_m-4e3d1e159a5b50d2.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/ta
rget/thumbv7m-none-eabi/debug/deps/libaligned-433f80187af623df.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/d
ebug/deps/libas_slice-7cd7b96cd776cbe0.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libstable_dere
f_trait-d6be1c622a71e64c.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libgeneric_array-2fb71faed80
7ea2c.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libgeneric_array-fe72171b4f9ffd35.rlib" "/Volum
es/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libgeneric_array-b85e7f6fe2cef964.rlib" "/Volumes/workplace/playgr
ound/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libtypenum-271c16d2a2f77c26.rlib" "/Volumes/workplace/playground/rust_embedded_with_c
_interop/app/target/thumbv7m-none-eabi/debug/deps/libpanic_halt-4d0b3983ed02fa87.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/th
umbv7m-none-eabi/debug/deps/libcortex_m_semihosting-695180d6324c8ba4.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-
eabi/debug/deps/libcortex_m-09751e7d921baf68.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libembed
ded_hal-2809cd32091c3ba8.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libvoid-fb1bf4e02014cb07.rli
b" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libnb-56a04b5218fae863.rlib" "/Volumes/workplace/playgro
und/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libnb-f9897756642f2d1b.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_inter
op/app/target/thumbv7m-none-eabi/debug/deps/libvolatile_register-6c4b892b7612085e.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/t
humbv7m-none-eabi/debug/deps/libvcell-16cd54fe2c2cf158.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/dep
s/libbare_metal-cdf719ed4a7ace5b.rlib" "/Users/yuenton/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/thumbv7m-none-eabi/lib/librustc_std_workspace_c
ore-05bb5221ddab705b.rlib" "/Users/yuenton/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/thumbv7m-none-eabi/lib/libcore-43d826545f9dd0d1.rlib" "/Use
rs/yuenton/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/thumbv7m-none-eabi/lib/libcompiler_builtins-c59fdfa9b274eac2.rlib" "-Wl,-Bdynamic" "-Wl,--e
h-frame-hdr" "-Wl,-z,noexecstack" "-L" "/Users/yuenton/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/thumbv7m-none-eabi/lib" "-o" "/Volumes/workplac
e/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/app-6d1120295b5167b4" "-Wl,--gc-sections" "-no-pie" "-nodefaultlibs" "-Wl,-Tl
ink.x" "-nostartfiles"
  = note: /usr/local/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /Volumes/workplace/playground/r
ust_embedded_with_c_interop/app/target/debug/deps/libfoo.a(foo.o): in function `print_hello_foo':
          foo.c:(.text+0x4c): undefined reference to `printf'
          collect2: error: ld returned 1 exit status
          
  = note: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
  = note: use the `-l` flag to specify native libraries to link
  = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scrip
ts.html#cargorustc-link-libkindname)

我尝试链接arm-none-eabi提供的libc.a来获取对printf定义的引用,但它引入了更多未定义的引用

error: linking with `arm-none-eabi-gcc` failed: exit status: 1
  |
  = note: LC_ALL="C" PATH="/Users/yuenton/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/bin:/Users/yuenton/.pyenv/shims:/Applica
tions/Simplicity Studio.app/Contents/Eclipse/developer/adapter_packs/commander/Commander.app/Contents/MacOS:/usr/local/opt/ruby/bin:/usr/local/lib/ruby/gems/2.7
.0/bin:/Users/yuenton/workplace/hht-scripts/src/HHTFirmwareScripts/stable/unix:/Applications/cov-analysis-macosx-2022-3-0/bin/:/Applications/SEGGER/JLink_V760h:
/usr/local/opt/gcc-arm-none-eabi-8-2019-q3-update/bin:/Users/yuenton/.toolbox/bin:/Users/yuenton/.nvm/versions/node/v14.20.0/bin:/Users/yuenton/bin:/usr/local/b
in:/opt/homebrew/bin:/opt/homebrew/sbin:/Users/yuenton/.local/share/nvim/mason/bin:/Users/yuenton/.pyenv/bin:/Applications/Simplicity Studio.app/Contents/Eclips
e/developer/adapter_packs/commander/Commander.app/Contents/MacOS:/usr/local/opt/ruby/bin:/usr/local/lib/ruby/gems/2.7.0/bin:/Users/yuenton/workplace/hht-scripts
/src/HHTFirmwareScripts/stable/unix:/Applications/cov-analysis-macosx-2022-3-0/bin/:/Applications/SEGGER/JLink_V760h:/usr/local/opt/gcc-arm-none-eabi-8-2019-q3-
update/bin:/Users/yuenton/.toolbox/bin:/Users/yuenton/.nvm/versions/node/v14.20.0/bin:/Users/yuenton/bin:/usr/local/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/us
r/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/
var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Users/yuen
ton/.cargo/bin:/Applications/kitty.app/Contents/MacOS:/usr/local/opt/fzf/bin" VSLANG="1033" "arm-none-eabi-gcc" "/var/folders/lm/n3lqn5fx2qsddzty2389rfgcfkmffy/
T/rustcjzQWtq/symbols.o" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/app-6d1120295b5167b4.44hpxx6ly2g0n
6p4.rcgu.o" "-Wl,--as-needed" "-L" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps" "-L" "/Volumes/workplac
e/playground/rust_embedded_with_c_interop/app/target/debug/deps" "-L" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/
debug/build/app-fca9b4a0fb47443d/out" "-L" "/usr/local/opt/arm-none-eabi-gcc/gcc/arm-none-eabi/lib" "-L" "./c_proj/build/" "-L" "/Volumes/workplace/playground/r
ust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/build/cortex-m-c1b153b4741594d3/out" "-L" "/Volumes/workplace/playground/rust_embedded_with_c_in
terop/app/target/thumbv7m-none-eabi/debug/build/cortex-m-rt-feabb8431baf6f6c/out" "-L" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/th
umbv7m-none-eabi/debug/build/cortex-m-semihosting-3928837b527a45a9/out" "-L" "/Users/yuenton/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/thumbv7m-
none-eabi/lib" "-Wl,-Bstatic" "-lfoo" "-lc" "-lc_nano" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libc
ty-580a16e85c846902.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libcortex_m_rt-c96c0df2d2e53803.r
lib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libr0-c044695858752b9f.rlib" "/Volumes/workplace/playg
round/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libcortex_m-4e3d1e159a5b50d2.rlib" "/Volumes/workplace/playground/rust_embedded_with
_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libaligned-433f80187af623df.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thu
mbv7m-none-eabi/debug/deps/libas_slice-7cd7b96cd776cbe0.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/de
ps/libstable_deref_trait-d6be1c622a71e64c.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libgeneric_
array-2fb71faed807ea2c.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libgeneric_array-fe72171b4f9ff
d35.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libgeneric_array-b85e7f6fe2cef964.rlib" "/Volumes
/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libtypenum-271c16d2a2f77c26.rlib" "/Volumes/workplace/playground/rus
t_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libpanic_halt-4d0b3983ed02fa87.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_inte
rop/app/target/thumbv7m-none-eabi/debug/deps/libcortex_m_semihosting-695180d6324c8ba4.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/targ
et/thumbv7m-none-eabi/debug/deps/libcortex_m-09751e7d921baf68.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/de
bug/deps/libembedded_hal-2809cd32091c3ba8.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libvoid-fb1
bf4e02014cb07.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libnb-56a04b5218fae863.rlib" "/Volumes/
workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libnb-f9897756642f2d1b.rlib" "/Volumes/workplace/playground/rust_embe
dded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/libvolatile_register-6c4b892b7612085e.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_int
erop/app/target/thumbv7m-none-eabi/debug/deps/libvcell-16cd54fe2c2cf158.rlib" "/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-no
ne-eabi/debug/deps/libbare_metal-cdf719ed4a7ace5b.rlib" "/Users/yuenton/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/thumbv7m-none-eabi/lib/librust
c_std_workspace_core-05bb5221ddab705b.rlib" "/Users/yuenton/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/thumbv7m-none-eabi/lib/libcore-43d826545f9
dd0d1.rlib" "/Users/yuenton/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/thumbv7m-none-eabi/lib/libcompiler_builtins-c59fdfa9b274eac2.rlib" "-Wl,-B
dynamic" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/Users/yuenton/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/thumbv7m-none-eabi/lib" "-o" "
/Volumes/workplace/playground/rust_embedded_with_c_interop/app/target/thumbv7m-none-eabi/debug/deps/app-6d1120295b5167b4" "-Wl,--gc-sections" "-no-pie" "-nodefa
ultlibs" "-Wl,-Tlink.x" "-nostartfiles"
  = note: /usr/local/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /usr/local/opt/arm-none-eabi-gc
c/gcc/arm-none-eabi/lib/libc.a(lib_a-sbrkr.o): in function `_sbrk_r':
          sbrkr.c:(.text._sbrk_r+0x18): undefined reference to `_sbrk'
          /usr/local/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /usr/local/opt/arm-none-eabi-gc
c/gcc/arm-none-eabi/lib/libc.a(lib_a-writer.o): in function `_write_r':
          writer.c:(.text._write_r+0x24): undefined reference to `_write'
          /usr/local/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /usr/local/opt/arm-none-eabi-gc
c/gcc/arm-none-eabi/lib/libc.a(lib_a-closer.o): in function `_close_r':
          closer.c:(.text._close_r+0x18): undefined reference to `_close'
          /usr/local/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /usr/local/opt/arm-none-eabi-gc
c/gcc/arm-none-eabi/lib/libc.a(lib_a-fstatr.o): in function `_fstat_r':
          fstatr.c:(.text._fstat_r+0x1c): undefined reference to `_fstat'
          /usr/local/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /usr/local/opt/arm-none-eabi-gc
c/gcc/arm-none-eabi/lib/libc.a(lib_a-isattyr.o): in function `_isatty_r':
          isattyr.c:(.text._isatty_r+0x18): undefined reference to `_isatty'
          /usr/local/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /usr/local/opt/arm-none-eabi-gc
c/gcc/arm-none-eabi/lib/libc.a(lib_a-lseekr.o): in function `_lseek_r':
          lseekr.c:(.text._lseek_r+0x24): undefined reference to `_lseek'
          /usr/local/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /usr/local/opt/arm-none-eabi-gc
c/gcc/arm-none-eabi/lib/libc.a(lib_a-readr.o): in function `_read_r':
          readr.c:(.text._read_r+0x24): undefined reference to `_read'
          /usr/local/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /usr/local/opt/arm-none-eabi-gc
c/gcc/arm-none-eabi/lib/libc.a(lib_a-abort.o): in function `abort':
          abort.c:(.text.abort+0x10): undefined reference to `_exit'
          /usr/local/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /usr/local/opt/arm-none-eabi-gc
c/gcc/arm-none-eabi/lib/libc.a(lib_a-signalr.o): in function `_kill_r':
          signalr.c:(.text._kill_r+0x1c): undefined reference to `_kill'
          /usr/local/opt/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld: /usr/local/opt/arm-none-eabi-gc
c/gcc/arm-none-eabi/lib/libc.a(lib_a-signalr.o): in function `_getpid_r':
          signalr.c:(.text._getpid_r+0x4): undefined reference to `_getpid'
          collect2: error: ld returned 1 exit status
          
  = note: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
  = note: use the `-l` flag to specify native libraries to link
  = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scrip
ts.html#cargorustc-link-libkindname)

我希望 glib 函数定义由编译器自动链接,我不必提供库。我在设置 C 静态库时错过了一个步骤吗?

我很困惑当与 Rust 交叉编译 C 库时,本机库应该如何链接。非常感谢任何帮助!

项目设置

这是我的C文件

// foo.h
typedef struct {
  int x;
  float y;
  char str[20];
} foo_s;

void print_hello_foo(const foo_s *foo);

// foo.c
#include "include/foo.h"
#include <stdio.h>

void print_hello_foo(const foo_s *foo) {
  printf("foo says hello, x: %i, y: %f, str: %s\n", foo->x, foo->y, foo->str);
}

我有一个编译它的cmake项目

// CMakeLists.txt
cmake_minimum_required(VERSION 3.23)

set(CMAKE_C_COMPILER_FORCED TRUE)
set(CMAKE_CXX_COMPILER_FORCED TRUE)

project(foo)

add_library(foo foo.c)
target_include_directories(foo PUBLIC include)

message(styuen "$(CMAKE_INSTALL_INCLUDEDIR)")
install(TARGETS foo PUBLIC_HEADER DESTINATION $(CMAKE_INSTALL_INCLUDEDIR)/foo)

// toolchain.cmake
set(CMAKE_SYSTEM_NAME Generic CACHE STRING "The operating system to target. Generic for cross-platform" FORCE)
set(CMAKE_SYSTEM_PROCESSOR arm CACHE STRING "The target CPU architecture" FORCE)
set(CMAKE_CROSSCOMPILING 1 CACHE STRING "" FORCE)

set(TOOLCHAIN_PREFIX arm-none-eabi-)
find_program(BINUTILS_PATH ${TOOLCHAIN_PREFIX}gcc NO_CACHE)

if (NOT BINUTILS_PATH)
    message(FATAL_ERROR "ARM GCC toolchain not found")
endif ()

get_filename_component(ARM_TOOLCHAIN_DIR ${BINUTILS_PATH} DIRECTORY)
# Without that flag CMake is not able to pass test compilation check
if (${CMAKE_VERSION} VERSION_EQUAL "3.6.0" OR ${CMAKE_VERSION} VERSION_GREATER "3.6")
    set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
else ()
    set(CMAKE_EXE_LINKER_FLAGS_INIT "--specs=nosys.specs")
endif ()

set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc CACHE STRING "" FORCE)
set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER} CACHE STRING "" FORCE)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++ CACHE STRING "" FORCE)
set(CMAKE_AR ${TOOLCHAIN_PREFIX}gcc-ar CACHE STRING "" FORCE)
set(CMAKE_RANLIB ${TOOLCHAIN_PREFIX}gcc-ranlib CACHE STRING "" FORCE)
set(CMAKE_LINKER ${TOOLCHAIN_PREFIX}/arm-none-eabi-ld CACHE STRING "" FORCE)

execute_process(COMMAND ${CMAKE_C_COMPILER} -print-sysroot
    OUTPUT_VARIABLE ARM_GCC_SYSROOT OUTPUT_STRIP_TRAILING_WHITESPACE)

在我的 Rust 项目中,我使用以下构建配置

# .cargo/config.toml
[target.thumbv7m-none-eabi]
# uncomment this to make `cargo run` execute programs on QEMU
runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel"

[target.'cfg(all(target_arch = "arm", target_os = "none"))']
# uncomment ONE of these three option to make `cargo run` start a GDB session
# which option to pick depends on your system
runner = "arm-none-eabi-gdb -q -x openocd.gdb"
# runner = "gdb-multiarch -q -x openocd.gdb"
# runner = "gdb -q -x openocd.gdb"

rustflags = [
  # Previously, the linker arguments --nmagic and -Tlink.x were set here.
  # They are now set by build.rs instead. The linker argument can still
  # only be set here, if a custom linker is needed.

  # By default, the LLD linker is used, which is shipped with the Rust
  # toolchain. If you run into problems with LLD, you can switch to the
  # GNU linker by uncommenting this line:
  "-C", "linker=arm-none-eabi-ld",

  # If you need to link to pre-compiled C libraries provided by a C toolchain
  # use GCC as the linker by uncommenting the three lines below:
  "-C", "linker=arm-none-eabi-gcc",
  "-C", "link-arg=-Wl,-Tlink.x",
  "-C", "link-arg=-nostartfiles",
]

[build]
# Pick ONE of these default compilation targets
# target = "thumbv6m-none-eabi"        # Cortex-M0 and Cortex-M0+
target = "thumbv7m-none-eabi"        # Cortex-M3
# target = "thumbv7em-none-eabi"       # Cortex-M4 and Cortex-M7 (no FPU)
# target = "thumbv7em-none-eabihf"     # Cortex-M4F and Cortex-M7F (with FPU)
# target = "thumbv8m.base-none-eabi"   # Cortex-M23
# target = "thumbv8m.main-none-eabi"   # Cortex-M33 (no FPU)
# target = "thumbv8m.main-none-eabihf" # Cortex-M33 (with FPU)

// build.rs
//! This build script copies the `memory.x` file from the crate root into
//! a directory where the linker can always find it at build time.
//! For many projects this is optional, as the linker always searches the
//! project root directory -- wherever `Cargo.toml` is. However, if you
//! are using a workspace or have a more complicated build setup, this
//! build script becomes required. Additionally, by requesting that
//! Cargo re-run the build script whenever `memory.x` is changed,
//! updating `memory.x` ensures a rebuild of the application with the
//! new memory settings.
//!
//! The build script also sets the linker flags to tell it which link script to use.

use cmake::Config;
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;

fn main() {
    // Put `memory.x` in our output directory and ensure it's
    // on the linker search path.
    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
    File::create(out.join("memory.x"))
        .unwrap()
        .write_all(include_bytes!("memory.x"))
        .unwrap();
    println!("cargo:rustc-link-search={}", out.display());

    // By default, Cargo will re-run a build script whenever
    // any file in the project changes. By specifying `memory.x`
    // here, we ensure the build script is only re-run when
    // `memory.x` is changed.
    println!("cargo:rerun-if-changed=memory.x");

    println!(
        "cargo:rustc-link-search=native=/usr/local/opt/arm-none-eabi-gcc/gcc/arm-none-eabi/lib"
    );
    println!("cargo:rustc-link-search=native=./c_proj/build/");

    println!("cargo:rustc-link-lib=static=foo");
    // println!("cargo:rustc-link-lib=static=c");
    println!("cargo:rerun-if-changed=c_proj/include/foo.h");
    println!("cargo:rerun-if-changed=c_proj/foo.c");

    let bindings = bindgen::Builder::default()
        .header("c_proj/include/foo.h")
        .use_core()
        .ctypes_prefix("cty")
        .parse_callbacks(Box::new(bindgen::CargoCallbacks))
        .generate()
        .expect("Unable to generate bindings");

    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");
}

rust main.rs

#![no_std]
#![no_main]
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));

use cortex_m_semihosting::{debug, hprintln};
// pick a panicking behavior
use panic_halt as _; // you can put a breakpoint on `rust_begin_unwind` to catch panics
                     // use panic_abort as _; // requires nightly
                     // use panic_itm as _; // logs messages over ITM; requires ITM support
                     // use panic_semihosting as _; // logs messages to the host stderr; requires a debugger

use cortex_m::asm;
use cortex_m_rt::entry;

#[entry]
fn main() -> ! {
    hprintln!("Hello, world!");

    let foo = foo_s {
        x: 3,
        y: 3.14,
        str_: [
            116, 101, 115, 116, 105, 110, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        ],
    };

    unsafe {
        print_hello_foo(&foo);
    }

    // exit QEMU
    // NOTE do not run this on hardware; it can corrupt OpenOCD state
    debug::exit(debug::EXIT_SUCCESS);

    loop {
        // your code goes here
    }
}
c gcc rust arm embedded
1个回答
0
投票

该库具有平台依赖性,必须通过您需要提供的特定于平台的移植层来解决。这是必要的,因为 I/O 和内存管理依赖于平台。

对于arm-none-eabi-gcc 通常使用的Newlib C 库,这是“系统调用”层

大多数系统调用都可以实现为非功能性存根。如果您只需要支持

printf
,那么为
write
实现
stdout
就足够了。

如果您也使用动态内存分配

sbrk

如果您的应用程序是多线程的,那么您应该实现后缀为

_r
的可重入版本。

文档中提供了这些存根的最小实现。例如,您所需要做的就是创建一个 C 源 syscalls.c,其中包含这些存根,然后编译并将其链接到您的项目。有些需要重新实现才能发挥作用,但这将允许您的代码链接。

© www.soinside.com 2019 - 2024. All rights reserved.