问题
我正在学习如何在裸金属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:/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:/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:/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:lpay/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 for 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
}
}
型
1条答案
按热度按时间hts6caw31#
库具有平台依赖性,必须由您需要提供的特定于平台的移植层来解决。这是必要的,因为I/O和内存管理是平台依赖性的。
对于arm-none-eabi-gcc通常使用的Newlib C库,这是“syscalls”层。
大多数系统调用都可以作为不起作用的存根来实现。如果你只需要支持
printf
,那么为stdout
实现write
就足够了。如果你使用动态内存分配也
sbrk
。如果你的应用程序是多线程的,那么你应该实现后缀为
_r
的可重入版本。文档中提供了这些存根的最小实现。例如,您需要做的就是创建一个C源代码syscalls. c,包含这些存根,然后编译并将其链接到您的项目。有些需要重新实现才能正常工作,但这将允许您的代码链接。
作为对Carl Norum的评论的回应,newlib的内部部分使用动态分配。这可能是用第三方“轻量级”实现覆盖
printf()
的一个很好的理由。为了确保它得到支持,您至少需要有一个小堆。通常链接器脚本将创建一个堆空间(通常是静态分配后的所有可用空间),在这种情况下,下面的sbrk
实现将提供一个堆:字符串
_sbrk_r()
如果需要的话(多线程代码)会有一个线程本地的errno
(或者只是不依赖于errno
是正确的)。此外,在多线程环境中,你需要覆盖__malloc_lock()
和__malloc_unlock()
存根来使动态内存分配线程安全。