目的
コードが増えるにつれてメモリ管理がだるくなってきたので
楽したい
経緯
最初はc++にしようと思ったけど
試しに流行り?(多分だいぶ遅れてる)のRustを使ってみよう
環境
ソフト | バージョン |
---|---|
Fedora | 6.14.0-0.rc6.49.fc43.x86_64(rawhide) |
buildroot | buildroot-2025.02.tar.gz |
qemu | 9.2.0 |
手順
Rustでstatic libraryを作ってcでリンクする
パッケージはcとRustで分けた方が絶対に楽
Rust側のパッケージ
例) pdf-viewer-rustlib
という名前で作った場合
├ package
┊ ├ pdf-viewer-rustlib
┊ ┊ ├ Config.in
┊ ┊ └ pdf-viewer-rustlib.mk
<snip>
configは適当でOK
package/pdf-viewer-rustlib/Config.in
config BR2_PACKAGE_PDF_VIEWER_RUSTLIB
bool "pdf_viewer_rustlib"
help
PDF Viewer Rust Library
makefileはstatic libraryだけだと
cargo
がインストール対象なしとなってエラーになる
したがって、[パッケージ名]_INSTALL_TARGET_CMDSを作成する必要がある
gitに置く場合は ここなどを参考にしてください
package/pdf-viewer-rustlib/pdf-viewer-rustlib.mk
PDF_VIEWER_RUSTLIB_LICENSE = Public Domain
PDF_VIEWER_RUSTLIB_VERSION = 0.0.1
PDF_VIEWER_RUSTLIB_SITE = /home/tyano/workspace/pdf/pdf_viewer_rustlib
PDF_VIEWER_RUSTLIB_SITE_VERSION = $(PDF_VIEWER_RUSTLIB_VERSION)
PDF_VIEWER_RUSTLIB_SITE_METHOD = local
PDF_VIEWER_RUSTLIB_INSTALL_STAGING = YES
define PDF_VIEWER_RUSTLIB_INSTALL_TARGET_CMDS
$(INSTALL) -D $(@D)/target/aarch64-unknown-linux-gnu/release/librustlib.a $(STAGING_DIR)/usr/lib/librustlib.a
$(INSTALL) -D $(@D)/src/rustlib.h $(STAGING_DIR)/usr/include/rustlib.h
endef
$(eval $(cargo-package))
Rust側のソースコード
こんな感じ
├ Cargo.lock
├ Cargo.toml
└ src
├ lib.rs
└ rustlib.h
buildroot側で --locked
を外す方法が分からなかった
本来不要なはずなのでbuild時のオプションを変えられたら削除可能と思う
Cargo.lock
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "rustlib"
version = "0.1.0"
Cargo.toml
[package]
name = "rustlib"
version = "0.1.0"
edition = "2021"
[lib]
name = "rustlib"
crate-type = ["staticlib"]
cからの受け口。好きに作ってください
src/rustlib.h
#ifndef __RUSTLIB_H__
#define __RUSTLIB_H__
extern int rust_add(int a, int b);
#endif
これも適当に作ってください
src/lib.rs
#[no_mangle]
pub extern "C" fn rust_add(a: i32, b: i32) -> i32 {
a + b
}
c側からコール
これはinclude追加してリンクするだけ
main.c
#include "rustlib.h"
...
d("rust 1+2=%d", rust_add(1, 2));
Makefile.am
...
pdf_viewer_lvgl_LDADD = $(STATIC_LIB) -lrustlib
...
実行結果
ホスト
当然動く
rustも動いてる
$ grep rust /tmp/pdf_viewer.log
250516_093959.746 main.c(70) main rust 1+2=3
250516_224413.541 main.c(70) main rust 1+2=3
250516_224501.451 main.c(70) main rust 1+2=3
qemu上
動いた
ログもちゃんと表示されてる
Welcome to the rock4c+ board
rock4cp login: [ 100.561075] hrtimer: interrupt took 893232 ns
root
# grep rust /tmp/pdf_viewer.log
250516_144236.240 main.c(70) main rust 1+2=3
#
その他
サブプロジェクトにして
同じパッケージ内でクロスビルドしようとするとすごい大変です