summaryrefslogtreecommitdiff
path: root/components/rust/examples/modules/SConscript
diff options
context:
space:
mode:
Diffstat (limited to 'components/rust/examples/modules/SConscript')
-rw-r--r--components/rust/examples/modules/SConscript159
1 files changed, 159 insertions, 0 deletions
diff --git a/components/rust/examples/modules/SConscript b/components/rust/examples/modules/SConscript
new file mode 100644
index 0000000000..98e57d1fd9
--- /dev/null
+++ b/components/rust/examples/modules/SConscript
@@ -0,0 +1,159 @@
+import os
+import sys
+import subprocess
+import toml
+from building import *
+
+cwd = GetCurrentDir()
+
+RUSTC_FLAGS = {
+ "linker": "-C linker=ld.lld",
+ "panic": "-C panic=abort",
+}
+
+CARGO_CMD = {
+ "base": "cargo build",
+ "build_std": "-Z build-std=core,alloc,panic_abort",
+ "target_flag": "--target",
+ "target_arch": "%s",
+ "release_profile": "--release",
+ "debug_profile": "", # No additional flag for debug mode
+}
+
+tools_dir = os.path.join(cwd, '..', '..', 'tools')
+sys.path.insert(0, tools_dir)
+
+from build_support import detect_rust_target, ensure_rust_target_installed, clean_rust_build
+
+def _has(sym: str) -> bool:
+ """Helper function to check if a configuration symbol is enabled"""
+ try:
+ return bool(GetDepend([sym]))
+ except Exception:
+ return bool(GetDepend(sym))
+
+def detect_target_for_dynamic_modules():
+ """
+ Detect the appropriate Rust target for dynamic modules.
+ For dynamic modules, we need Linux targets instead of bare-metal targets.
+ """
+ if detect_rust_target is not None:
+ try:
+ import rtconfig
+ bare_metal_target = detect_rust_target(_has, rtconfig)
+
+ if bare_metal_target:
+ if "riscv64" in bare_metal_target:
+ return "riscv64gc-unknown-linux-gnu"
+ elif "riscv32" in bare_metal_target:
+ return "riscv32gc-unknown-linux-gnu"
+ elif "aarch64" in bare_metal_target:
+ return "aarch64-unknown-linux-gnu"
+ elif "arm" in bare_metal_target or "thumb" in bare_metal_target:
+ return "armv7-unknown-linux-gnueabihf"
+ except Exception as e:
+ print(f"Error: Target detection failed: {e}")
+ raise RuntimeError(f"Failed to detect Rust target for dynamic modules: {e}")
+
+ print("Error: Unable to detect appropriate Rust target for dynamic modules")
+ raise RuntimeError("Target detection failed - no valid target found")
+
+def build_rust_module(module_dir, build_root):
+ """Build a Rust dynamic module with automatic target detection"""
+ cargo_toml_path = os.path.join(module_dir, 'Cargo.toml')
+ if not os.path.exists(cargo_toml_path):
+ return [], [], ""
+
+ with open(cargo_toml_path, 'r') as f:
+ cargo_config = toml.load(f)
+
+ module_name = cargo_config['package']['name']
+
+ # Detect target automatically based on the current configuration
+ target = detect_target_for_dynamic_modules()
+ print(f"Building Rust module '{module_name}' for target: {target}")
+
+ # Detect debug mode from rtconfig (same as main rust/SConscript)
+ debug = bool(_has('RUST_DEBUG_BUILD'))
+ build_mode = "debug" if debug else "release"
+ print(f"Building in {build_mode} mode")
+
+ # Use global RUSTFLAGS configuration for dynamic modules
+ rustflags = " ".join(RUSTC_FLAGS.values())
+
+ # Verify that the target is installed
+ if ensure_rust_target_installed is not None:
+ if not ensure_rust_target_installed(target):
+ print(f"Error: Rust target '{target}' is not installed")
+ print(f"Please install it with: rustup target add {target}")
+ return [], [], ""
+ else:
+ print(f"Warning: Cannot verify if target '{target}' is installed")
+
+ # Set up build environment
+ env = os.environ.copy()
+ env['RUSTFLAGS'] = rustflags
+ env['CARGO_TARGET_DIR'] = build_root
+
+ # Build the module with configurable parameters using dictionary configuration
+ build_cmd = [
+ CARGO_CMD["base"].split()[0], # 'cargo'
+ CARGO_CMD["base"].split()[1], # 'build'
+ CARGO_CMD["target_flag"], # '--target'
+ target, # actual target architecture
+ ]
+
+ # Add profile flag based on debug mode
+ profile_flag = CARGO_CMD["debug_profile"] if debug else CARGO_CMD["release_profile"]
+ if profile_flag:
+ build_cmd.append(profile_flag)
+
+ # Add build-std flag if specified
+ if CARGO_CMD["build_std"]:
+ build_std_parts = CARGO_CMD["build_std"].split()
+ build_cmd.extend(build_std_parts)
+
+ try:
+ subprocess.run(build_cmd, cwd=module_dir, env=env, check=True, capture_output=True)
+ lib_dir = os.path.join(build_root, target, build_mode)
+ return [module_name], [lib_dir], ""
+ except subprocess.CalledProcessError:
+ return [], [], ""
+
+# Check dependencies
+if not _has('RT_RUST_BUILD_MODULES'):
+ Return([])
+
+build_root = os.path.join(Dir('#').abspath, "build", "rust_modules")
+
+# Handle clean operation
+if GetOption('clean'):
+ if clean_rust_build is not None:
+ modules_build_dir = clean_rust_build(Dir('#').abspath, "rust_modules")
+ if os.path.exists(modules_build_dir):
+ print(f'Registering {modules_build_dir} for cleanup')
+ Clean('.', modules_build_dir)
+ else:
+ print('No rust_modules build artifacts to clean')
+ else:
+ print('Warning: clean_rust_build function not available')
+else:
+ # Build all Rust modules in subdirectories
+ modules_built = []
+ for item in os.listdir(cwd):
+ item_path = os.path.join(cwd, item)
+ if os.path.isdir(item_path) and os.path.exists(os.path.join(item_path, 'Cargo.toml')):
+ result = build_rust_module(item_path, build_root)
+ if result[0]:
+ modules_built.extend(result[0])
+
+ if modules_built:
+ print(f"Successfully built {len(modules_built)} Rust dynamic module(s): {', '.join(modules_built)}")
+
+group = DefineGroup(
+ 'rust_modules',
+ [],
+ depend=['RT_RUST_BUILD_MODULES']
+)
+
+Return('group') \ No newline at end of file