mirror of
https://github.com/apache/nuttx-apps.git
synced 2026-08-01 20:29:00 +00:00
On the sim target (Windows/macOS/Linux), hello_rust_cargo_main() ended
with an infinite `loop {}` that never returned control to NSH, so the
example could not exit and the shell prompt hung.
Introduce a Cargo `sim` feature that is enabled only when CONFIG_ARCH_SIM
is set, and use it to compile out the trailing infinite loop and return 0
instead. Other embedded targets keep the original looping behavior.
Signed-off-by: Shoji Tokunaga <toku@mac.com>
228 lines
7.5 KiB
CMake
228 lines
7.5 KiB
CMake
# ##############################################################################
|
|
# cmake/nuttx_add_rust.cmake
|
|
#
|
|
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
|
|
# license agreements. See the NOTICE file distributed with this work for
|
|
# additional information regarding copyright ownership. The ASF licenses this
|
|
# file to you under the Apache License, Version 2.0 (the "License"); you may not
|
|
# use this file except in compliance with the License. You may obtain a copy of
|
|
# the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations under
|
|
# the License.
|
|
#
|
|
# ##############################################################################
|
|
|
|
include(nuttx_parse_function_args)
|
|
|
|
# ~~~
|
|
# Convert architecture type to Rust NuttX target
|
|
#
|
|
# Supported architectures:
|
|
# - armv7a: armv7a-nuttx-eabi, armv7a-nuttx-eabihf
|
|
# - thumbv6m: thumbv6m-nuttx-eabi
|
|
# - thumbv7a: thumbv7a-nuttx-eabi, thumbv7a-nuttx-eabihf
|
|
# - thumbv7m: thumbv7m-nuttx-eabi
|
|
# - thumbv7em: thumbv7em-nuttx-eabihf
|
|
# - thumbv8m.main: thumbv8m.main-nuttx-eabi, thumbv8m.main-nuttx-eabihf
|
|
# - thumbv8m.base: thumbv8m.base-nuttx-eabi, thumbv8m.base-nuttx-eabihf
|
|
# - riscv32: riscv32imc/imac/imafc-unknown-nuttx-elf
|
|
# - riscv64: riscv64imac/imafdc-unknown-nuttx-elf
|
|
# - x86: i686-unknown-nuttx
|
|
# - x86_64: x86_64-unknown-nuttx-macho for sim on macOS,
|
|
# x86_64-unknown-nuttx otherwise
|
|
# - aarch64: aarch64-unknown-nuttx-macho for sim on macOS,
|
|
# aarch64-unknown-nuttx otherwise
|
|
#
|
|
# Inputs:
|
|
# ARCHTYPE - Architecture type (e.g. thumbv7m, riscv32)
|
|
# ABITYPE - ABI type (e.g. eabi, eabihf)
|
|
# CPUTYPE - CPU type (e.g. cortex-m4, sifive-e20)
|
|
#
|
|
# Output:
|
|
# OUTPUT - Rust target triple (e.g. riscv32imac-unknown-nuttx-elf,
|
|
# thumbv7m-nuttx-eabi, thumbv7em-nuttx-eabihf)
|
|
# ~~~
|
|
|
|
function(nuttx_rust_target_triple ARCHTYPE ABITYPE CPUTYPE OUTPUT)
|
|
if(ARCHTYPE STREQUAL "x86_64")
|
|
if(CONFIG_ARCH_SIM AND CONFIG_HOST_MACOS)
|
|
set(TARGET_TRIPLE
|
|
"${PROJECT_SOURCE_DIR}/tools/x86_64-unknown-nuttx-macho.json")
|
|
else()
|
|
set(TARGET_TRIPLE "${PROJECT_SOURCE_DIR}/tools/x86_64-unknown-nuttx.json")
|
|
endif()
|
|
elseif(ARCHTYPE STREQUAL "x86")
|
|
set(TARGET_TRIPLE "${PROJECT_SOURCE_DIR}/tools/i486-unknown-nuttx.json")
|
|
elseif(ARCHTYPE STREQUAL "aarch64")
|
|
if(CONFIG_ARCH_SIM AND CONFIG_HOST_MACOS)
|
|
set(TARGET_TRIPLE
|
|
"${PROJECT_SOURCE_DIR}/tools/aarch64-unknown-nuttx-macho.json")
|
|
else()
|
|
set(TARGET_TRIPLE
|
|
"${PROJECT_SOURCE_DIR}/tools/aarch64-unknown-nuttx.json")
|
|
endif()
|
|
elseif(ARCHTYPE MATCHES "thumb")
|
|
if(ARCHTYPE MATCHES "thumbv8m")
|
|
# Extract just the base architecture type (thumbv8m.main or thumbv8m.base)
|
|
if(ARCHTYPE MATCHES "thumbv8m.main")
|
|
set(ARCH_BASE "thumbv8m.main")
|
|
elseif(ARCHTYPE MATCHES "thumbv8m.base")
|
|
set(ARCH_BASE "thumbv8m.base")
|
|
else()
|
|
# Otherwise determine if we should use thumbv8m.main or thumbv8m.base
|
|
# based on CPU type
|
|
if(CPUTYPE MATCHES "cortex-m23")
|
|
set(ARCH_BASE "thumbv8m.base")
|
|
else()
|
|
set(ARCH_BASE "thumbv8m.main")
|
|
endif()
|
|
endif()
|
|
set(TARGET_TRIPLE "${ARCH_BASE}-nuttx-${ABITYPE}")
|
|
else()
|
|
set(TARGET_TRIPLE "${ARCHTYPE}-nuttx-${ABITYPE}")
|
|
endif()
|
|
elseif(ARCHTYPE STREQUAL "riscv32")
|
|
if(CPUTYPE STREQUAL "sifive-e20")
|
|
set(TARGET_TRIPLE "riscv32imc-unknown-nuttx-elf")
|
|
elseif(CPUTYPE STREQUAL "sifive-e31")
|
|
set(TARGET_TRIPLE "riscv32imac-unknown-nuttx-elf")
|
|
elseif(CPUTYPE STREQUAL "sifive-e76")
|
|
set(TARGET_TRIPLE "riscv32imafc-unknown-nuttx-elf")
|
|
else()
|
|
set(TARGET_TRIPLE "riscv32imc-unknown-nuttx-elf")
|
|
endif()
|
|
elseif(ARCHTYPE STREQUAL "riscv64")
|
|
if(CPUTYPE STREQUAL "sifive-s51")
|
|
set(TARGET_TRIPLE "riscv64imac-unknown-nuttx-elf")
|
|
elseif(CPUTYPE STREQUAL "sifive-u54")
|
|
set(TARGET_TRIPLE "riscv64imafdc-unknown-nuttx-elf")
|
|
else()
|
|
set(TARGET_TRIPLE "riscv64imac-unknown-nuttx-elf")
|
|
endif()
|
|
endif()
|
|
|
|
if(NOT TARGET_TRIPLE)
|
|
message(
|
|
FATAL_ERROR
|
|
"Unsupported Rust target: LLVM_ARCHTYPE=${ARCHTYPE}, LLVM_ABITYPE=${ABITYPE}, LLVM_CPUTYPE=${CPUTYPE}"
|
|
)
|
|
endif()
|
|
set(${OUTPUT}
|
|
${TARGET_TRIPLE}
|
|
PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# ~~~
|
|
# nuttx_add_rust
|
|
#
|
|
# Description:
|
|
# Build a Rust crate and add it as a static library to the NuttX build system
|
|
#
|
|
# Example:
|
|
# nuttx_add_rust(
|
|
# CRATE_NAME
|
|
# hello
|
|
# CRATE_PATH
|
|
# ${CMAKE_CURRENT_SOURCE_DIR}/hello
|
|
# FEATURES
|
|
# sim
|
|
# )
|
|
# ~~~
|
|
|
|
function(nuttx_add_rust)
|
|
|
|
# parse arguments into variables
|
|
nuttx_parse_function_args(
|
|
FUNC
|
|
nuttx_add_rust
|
|
ONE_VALUE
|
|
CRATE_NAME
|
|
CRATE_PATH
|
|
MULTI_VALUE
|
|
FEATURES
|
|
REQUIRED
|
|
CRATE_NAME
|
|
CRATE_PATH
|
|
ARGN
|
|
${ARGN})
|
|
|
|
# Determine build profile based on CONFIG_DEBUG_FULLOPT
|
|
if(CONFIG_DEBUG_FULLOPT)
|
|
set(RUST_PROFILE_FLAG "--release")
|
|
set(RUST_PROFILE "release")
|
|
set(RUST_PANIC_FLAGS "-Zunstable-options -Cpanic=immediate-abort")
|
|
else()
|
|
set(RUST_PROFILE_FLAG "")
|
|
set(RUST_PROFILE "debug")
|
|
set(RUST_PANIC_FLAGS "")
|
|
endif()
|
|
|
|
foreach(feature ${FEATURES})
|
|
list(APPEND RUST_FEATURE_FLAGS --features ${feature})
|
|
endforeach()
|
|
|
|
# Get the Rust target triple
|
|
nuttx_rust_target_triple(${LLVM_ARCHTYPE} ${LLVM_ABITYPE} ${LLVM_CPUTYPE}
|
|
RUST_TARGET)
|
|
|
|
# Get binary directory path using target triple base name if it's a JSON file
|
|
if(RUST_TARGET MATCHES ".json$")
|
|
get_filename_component(TARGET_BASE ${RUST_TARGET} NAME_WE)
|
|
else()
|
|
set(TARGET_BASE ${RUST_TARGET})
|
|
endif()
|
|
|
|
set(RUST_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/${CRATE_NAME}/target)
|
|
set(RUST_LIB_PATH
|
|
${RUST_BUILD_DIR}/${TARGET_BASE}/${RUST_PROFILE}/lib${CRATE_NAME}.a)
|
|
|
|
# Create build directory
|
|
file(MAKE_DIRECTORY ${RUST_BUILD_DIR})
|
|
|
|
# Collect Rust source files and manifests as dependencies so that changes in
|
|
# the crate trigger a rebuild via CMake/Ninja.
|
|
file(
|
|
GLOB_RECURSE
|
|
RUST_CRATE_SOURCES
|
|
CONFIGURE_DEPENDS
|
|
"${CRATE_PATH}/Cargo.toml"
|
|
"${CRATE_PATH}/Cargo.lock"
|
|
"${CRATE_PATH}/build.rs"
|
|
"${CRATE_PATH}/src/*.rs"
|
|
"${CRATE_PATH}/src/**/*.rs")
|
|
|
|
# Add a custom command to build the Rust crate
|
|
add_custom_command(
|
|
OUTPUT ${RUST_LIB_PATH}
|
|
COMMAND
|
|
${CMAKE_COMMAND} -E env
|
|
NUTTX_INCLUDE_DIR=${PROJECT_SOURCE_DIR}/include:${CMAKE_BINARY_DIR}/include:${CMAKE_BINARY_DIR}/include/arch
|
|
RUSTFLAGS=${RUST_PANIC_FLAGS} cargo build ${RUST_PROFILE_FLAG}
|
|
-Zbuild-std=std,panic_abort -Zjson-target-spec --manifest-path
|
|
${CRATE_PATH}/Cargo.toml --target ${RUST_TARGET} --target-dir
|
|
${RUST_BUILD_DIR} ${RUST_FEATURE_FLAGS}
|
|
DEPENDS ${RUST_CRATE_SOURCES}
|
|
COMMENT "Building Rust crate ${CRATE_NAME}"
|
|
VERBATIM)
|
|
|
|
# Add a custom target that depends on the built library
|
|
add_custom_target(${CRATE_NAME}_build ALL DEPENDS ${RUST_LIB_PATH})
|
|
|
|
# Add imported library target
|
|
add_library(${CRATE_NAME} STATIC IMPORTED GLOBAL)
|
|
set_target_properties(${CRATE_NAME} PROPERTIES IMPORTED_LOCATION
|
|
${RUST_LIB_PATH})
|
|
|
|
# Add the Rust library to NuttX build
|
|
nuttx_add_extra_library(${RUST_LIB_PATH})
|
|
|
|
# Ensure the Rust library is built before linking
|
|
add_dependencies(${CRATE_NAME} ${CRATE_NAME}_build)
|
|
|
|
endfunction()
|