How/where to parse environment for embedded toolchain

Hello everyone,

I am currently looking into adding a target spec for building Rust for the real-time operating system RTEMS (https://www.rtems.org/).
Locally, I currently have a working toolchain for one board support package which can build a (very) simple Rust application. For that I have created a target spec which sets the correct ABI flags.
RTEMS has also pkg-config files which detail some further flags for compiler/linker, i.e. the cpu specific flags (-mcpu, -mfpu) and some include/library paths. Currently, I created a build_script.sh which reads the information from pkg-config and passes the flags to cargo.

My question would be if it is possible to automate this process a bit?
Can I create a crate from this build script and when it is added as a (build) dependency it is automatically executed as part of the compilation?
I would find it more convenient if one doesn't need to add this manually to every RTEMS project.

Best regards,

Jan

PS: I am not sure if the embedded category is the right place or if it should go into the help section.

Can you share the script and maybe an example project?

Sure. The build.rs currently looks like below. I just noticed I forget to mention that one also needs to compile one C file which collects some kernel configuration for the RTEMS.
The RTEMS_BSP environment variable just holds the name of the concrete board support package (e.g. xilinx_zynq_zedboard for an armv7a-eabihf based board).

fn main() {
    let bsp : &'static str = std::option_env!("RTEMS_BSP").expect("Environment variable 'RTEMS_BSP' is not set. Please set to the name of the desired BSP");

    // Just check if the BSP could be found and print error if not
    let abi_flags = pkg_config::get_variable(bsp, "ABI_FLAGS").unwrap();
    let include_dir = pkg_config::get_variable(bsp, "includedir").unwrap();
    let lib_dir = pkg_config::get_variable(bsp, "libdir").unwrap();

    // Use the `cc` crate to build a C file and statically link it.
    let mut build_config = cc::Build::new();

    build_config.file("src/rtemsconfig.c")
        .compiler("arm-rtems6-gcc")
        .warnings(false)
        .include(include_dir)
        .flag("-qrtems");

    for flag in abi_flags.split_whitespace()
    {
        build_config.flag(flag);
    }
    build_config.compile("rtemsconfig");

    println!("cargo:rerun-if-changed=src/rtemsconfig.c");
    println!("cargo:rustc-link-search={lib_dir}");
    println!("cargo:rerun-if-env-changed=RTEMS_BSP");
}

The Rust code of the appliation is quite uninteresting it's just a function which calls puts saying hello world plus some boilerplate for panic handler because I only have the core library available atm.

The typical approach is to create a rtems-sys crate who's build script adds folders to the include path, tells the compiler which native libraries to link with, and so on. It's also where you can write declarations for any C functions RTEMS provides for interacting with the runtime.

That way a crate just needs to include rtems-sys as a dependency and it'll automatically link in RTEMS and your compiled rtemsconfig.

2 Likes

Great, that sounds exactly what I want.

Thanks, for pointing me in the right direction. There seems to be ample references now that I know what to search for.

I think I ran into a problem.
Some of the ABI flags are handled by the target spec, namely -march and -mfloat-abi.

Other ABI flags however are only known when I look at the pkg-config information of the BSP, e.g. -mtune and -mfpu because they are dependent on the actual processor of the target board.

How would I set these in the rtems-sys crate, so that they are used in the dependent crates?
I first thought cargo:rustc-flags would be the right candidate, but in only allows -l or -L options.
Would something like the CARGO_ENCODED_RUSTFLAGS work if I set them via "cargo:rustc-env=?

I'm not sure, but you should be able to find what you need from the build script docs.

Otherwise, you might need to make sure the person compiling an application for a specific board sets $RUSTFLAGS accordingly.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.