Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gcoap: adapt to API change in [PR20900] #130

Merged
merged 2 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,53 @@ fn main() {
for module in known_modules {
println!("cargo::rustc-check-cfg=cfg(riot_module_{})", module);
}

// As a means of last resort, we emulate cfg(accessible(::path::to::thing)), as a
// workaround for https://github.com/rust-lang/rust/issues/64797
//
// This is sometimes necessary when some C API compatible change (eg. renaming a field with a
// deprecated union while introducing a proper accessor, as done in
// https://github.com/RIOT-OS/RIOT/pull/20900) leads to changes in bindgen and c2rust outputs.
//
// This is similar to the markers that were previously used in riot-sys. We access files
// directly to avoid going through `links=` (see also
// <https://github.com/RIOT-OS/rust-riot-sys/pull/38>). This
//
// * limits the impact of source changes (this way, only changs to relevant headerst trigger
// a rebuild of riot-wrappers), and
// * removes the need for lock-stepping riot-sys and riot-wrappers.
//
// The downside of the tighter coupling with the paths in RIOT is reduced by keeping things
// local and the stabiity structure: All these access checks can be removed once riot-wrappers
// stops supporting a RIOT version that has the symbol unconditionally, without any concern for
// compatibility between crates (as the cfgs are just internal).

let riotbase: std::path::PathBuf = env::var("RIOTBASE")
.expect("No RIOTBASE set, can not inspect source files for symbol presence.")
.into();
println!("cargo:rerun-if-env-changed=RIOTBASE");

let emulate_accessible = [
// It's a static inline function and riot-sys currently only gives the file for the bindgen
// output, not the c2rust output. Using coap_build_udp_hdr presence as a stand-in.
//
// Remove this after a release including coap_pkt_set_code
// <https://github.com/RIOT-OS/riot/issues/20900> has been published.
(
&"inline_coap_pkt_set_code",
&"sys/include/net/nanocoap.h",
&"coap_pkt_set_code",
),
];

for (rust_name, header_file, header_search_string) in emulate_accessible {
let header_file = riotbase.join(header_file);
println!("cargo:rerun-if-changed={}", header_file.display());
let header_code =
std::fs::read_to_string(&header_file).expect("Failed to read header file");
println!("cargo:rustc-check-cfg=cfg(accessible_riot_sys_{rust_name})");
if header_code.contains(header_search_string) {
println!("cargo:rustc-cfg=accessible_riot_sys_{rust_name}");
}
}
}
11 changes: 10 additions & 1 deletion src/gcoap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,16 @@ impl<'b> PacketBuffer<'b> {
}

pub fn set_code_raw(&mut self, code: u8) {
unsafe { (*(*self.pkt).hdr).code = code };
#[cfg(accessible_riot_sys_inline_coap_pkt_set_code)]
{
unsafe {
riot_sys::inline::coap_pkt_set_code(crate::inline_cast_ref_mut(self.pkt), code)
};
}
#[cfg(not(accessible_riot_sys_inline_coap_pkt_set_code))]
{
unsafe { (*(*self.pkt).hdr).code = code };
}
}

/// Return the total number of bytes in the message, given that `payload_used` bytes were
Expand Down
2 changes: 1 addition & 1 deletion src/gnrc/netreg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type PktsnipPort = crate::msg::v2::SendPort<
///
/// It might be convenient for this to return at some point (in case of short-lived network
/// services). Deregistration could be done and everything returned alright -- but the grant would
/// still be lost. This could be mitigated by accepting a 'static PktsnipPort or a clonable version
/// still be lost. This could be mitigated by accepting a 'static PktsnipPort or a cloneable version
/// thereof -- not that anything could still be recombined after that, but at least it could be
/// used once more (with the risk that messages from the old registration arrive in the new one,
/// which is wrong correctness-wise but safe because it'll still be a pointer to a pktsnip).
Expand Down
2 changes: 1 addition & 1 deletion src/msg/v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub struct ReceivePort<TYPE: Send, const TYPENO: u16> {
/// share a shared reference), it would be possible to create a version of the SendPort
/// that counts its clones at runtime and can only be returned when all of them are recombined, or
/// just to create a version that can be cloned at will but never recombined any more. (One way to
/// do the latter would be to add a const boolean type parameter "CLONED"; a `.clonable(self) ->
/// do the latter would be to add a const boolean type parameter "CLONED"; a `.cloneable(self) ->
/// Self` would switch that from false to true, and then copy and clone would be implemented for
/// the result, whereas recombination would only be implemented for the CLONED = false version).
pub struct SendPort<TYPE: Send, const TYPENO: u16> {
Expand Down
Loading