Skip to content

Commit

Permalink
Simplify build.rs
Browse files Browse the repository at this point in the history
Merges: #79
  • Loading branch information
chrysn committed Feb 1, 2024
2 parents 95e973d + 6886a10 commit 9d2068a
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 77 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "riot-wrappers"
version = "0.8.2"
authors = ["Christian Amsüss <chrysn@fsfe.org>"]
edition = "2021"
rust-version = "1.65"
rust-version = "1.75"

description = "Rust API wrappers for the RIOT operating system"
documentation = "https://rustdoc.etonomy.org/riot_wrappers/"
Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ Supported RIOT & Rust versions
Currently, this crate targets the latest development version of RIOT.
Support for the latest release is maintained on a best-effort basis.

This crate works on stable Rust 1.64,
unless particular features are enabled.
This crate has no MSRV, it may start depending on the latest stable as soon as RIOT's build infrastructure has it.

When a released version of RIOT is used with anything but the riot-sys / riot-wrappers / nightly-compiler combination it was released with,
it is likely that all these must be upgraded together.
Expand All @@ -62,7 +61,7 @@ On item presence and modules

This crate makes some of its modules' presence conditional on whether the
corresponding RIOT module is active in the build configuration; that
information is obtained through the riot-sys crate. For example,
information is obtained by inspecting the `riotbuild.h file`. For example,
`riot_wrappers::saul` is only present if `USEMODULE += saul` is (directly or
indirectly) set in the Makefile.

Expand Down
106 changes: 42 additions & 64 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,78 +3,56 @@ extern crate shlex;
use std::env;

fn main() {
let cflags = env::var("DEP_RIOT_SYS_CFLAGS")
.expect("DEP_RIOT_SYS_CFLAGS is not set, check whether riot-sys exports it.");
let cflags = shlex::split(&cflags).expect("Odd shell escaping in CFLAGS");

println!("cargo:rerun-if-env-changed=DEP_RIOT_SYS_CFLAGS");
println!("cargo:rerun-if-env-changed=RIOTBUILD_CONFIG_HEADER_C");
let riotbuildh = env::var("RIOTBUILD_CONFIG_HEADER_C")
.expect("riotbuild.h is expected to be indicated in the RIOTBUILD_CONFIG_HEADER_C environment variable, or another source of enabled modules provided.");
println!("cargo:rerun-if-changed={riotbuildh}");

let mut defines = std::collections::HashMap::new();

use std::io::BufRead;
for line in std::io::BufReader::new(
std::fs::File::open(riotbuildh)
.expect("Failed to read riotbuild.h (RIOTBUILD_CONFIG_HEADER_C)"),
)
.lines()
{
let line = line.expect("Error reading line from riotbuild.h (RIOTBUILD_CONFIG_HEADER_C)");
if let Some(name) = line.strip_prefix("#undef ") {
defines.remove(name.trim());
}
if let Some((name, val)) = line
.strip_prefix("#define ")
.and_then(|nv| nv.split_once(" "))
{
defines.insert(name.trim().to_owned(), val.trim().to_owned());
}
}

for flag in cflags.iter() {
if flag.starts_with("-DMODULE_") {
const BOOLEAN_FLAGS: &[&str] = &[
// This decides whether or not some fields are populated ... and unlike with other
// structs, the zeroed default is not a good solution here. (It'd kind of work, but
// it'd produce incorrect debug output).
"CONFIG_AUTO_INIT_ENABLE_DEBUG",
];

for (def, val) in defines {
if val != "1" {
// So far, only processing boolean flags
continue;
}
if let Some(module) = def.strip_prefix("MODULE_") {
// Some modules like cmsis-dsp_StatisticsFunctions have funny characters
println!(
"cargo:rustc-cfg=riot_module_{}",
flag[9..].to_lowercase().replace("-", "_")
module.to_lowercase().replace("-", "_")
);
}

if flag == "-DDEVELHELP" {
if def == "DEVELHELP" {
println!("cargo:rustc-cfg=riot_develhelp");
}
}

let mut bindgen_output_file = None;

for (key, value) in env::vars() {
if let Some(marker) = key.strip_prefix("DEP_RIOT_SYS_MARKER_") {
println!("cargo:rerun-if-env-changed={}", key);
// It appears that they get uppercased in Cargo -- but should be lower-case as in the
// original riot-sys build.rs, especially to not make the cfg statements look weird.
println!("cargo:rustc-cfg=marker_{}", marker.to_lowercase());
}
if key == "DEP_RIOT_SYS_BINDGEN_OUTPUT_FILE" {
bindgen_output_file = Some(value);
}
}

if let Some(bindgen_output_file) = bindgen_output_file {
let bindgen_output = std::fs::read_to_string(bindgen_output_file)
.expect("Failed to read BINDGEN_OUTPUT_FILE");

const BOOLEAN_FLAGS: &[&str] = &[
// This decides whether or not some fields are populated ... and unlike with other
// structs, the zeroed default is not a good solution here. (It'd kind of work, but
// it'd produce incorrect debug output).
"CONFIG_AUTO_INIT_ENABLE_DEBUG",
];

let parsed = syn::parse_file(&bindgen_output).expect("Failed to parse bindgen output");
for item in &parsed.items {
if let syn::Item::Const(const_) = item {
// It's the easiest way to get something we can `contains`...
let ident = const_.ident.to_string();
if BOOLEAN_FLAGS.contains(&ident.as_str()) {
if let syn::Expr::Lit(syn::ExprLit {
lit: syn::Lit::Int(litint),
..
}) = &*const_.expr
{
let value: usize = litint
.base10_parse()
.expect("Identifier is integer literal but not parsable");
if value != 0 {
println!("cargo:rustc-cfg=marker_{}", ident.to_lowercase());
}
continue;
}
panic!(
"Found {} but it's not the literal const it was expected to be",
ident
);
}
}
if BOOLEAN_FLAGS.contains(&def.as_str()) {
println!("cargo:rustc-cfg=marker_{}", def.to_lowercase());
}
} else {
println!("cargo:warning=Old riot-sys did not provide BINDGEN_OUTPUT_FILE, assuming it's an old RIOT version");
}
}
10 changes: 1 addition & 9 deletions src/gcoap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ use riot_sys::{coap_optpos_t, coap_pkt_t, gcoap_listener_t};

use riot_sys::coap_resource_t;

#[cfg(marker_coap_request_ctx_t)]
type HandlerArg4 = riot_sys::coap_request_ctx_t;
#[cfg(not(marker_coap_request_ctx_t))]
type HandlerArg4 = libc::c_void;

/// Give the caller a way of registering Gcoap handlers into the global Gcoap registry inside a
/// callback. When the callback terminates, the registered handlers are deregistered again,
/// theoretically allowing the registration of non-'static handlers.
Expand Down Expand Up @@ -177,14 +172,11 @@ where
pkt: *mut coap_pkt_t,
buf: *mut u8,
len: u32,
context: *mut HandlerArg4,
context: *mut riot_sys::coap_request_ctx_t,
) -> i32 {
#[cfg(marker_coap_request_ctx_t)]
/* The remaining information in the request_ctx is inaccessible through the CoAP handler
* API as it is now */
let h = riot_sys::coap_request_ctx_get_context(context) as *mut H;
#[cfg(not(marker_coap_request_ctx_t))]
let h = context as *mut H;

let h = &mut *h;
let mut pb = PacketBuffer {
Expand Down

0 comments on commit 9d2068a

Please sign in to comment.