Add Makefile example for allocator interop#20
Conversation
Configures the crate as a staticlib for linking from C. Relates to problem-space/0001-incompatible-allocators.md
Exposes rust_alloc_array() and rust_free_array() via extern C. Uses Vec and mem::forget to transfer ownership across the FFI boundary. Memory must be freed using rust_free_array(), not free(). Relates to problem-space/0001-incompatible-allocators.md
Calls rust_alloc_array() and correctly frees using rust_free_array() instead of C's free() to avoid undefined behaviour from allocator mismatch. Relates to problem-space/0001-incompatible-allocators.md
Builds Rust staticlib with cargo and links with gcc. Uses rustc --print=native-static-libs for correct linker flags. Relates to problem-space/0001-incompatible-allocators.md
Documents the example, expected output, and explains why rust_free_array() must be used instead of C's free() to avoid undefined behaviour from incompatible allocators. Relates to problem-space/0001-incompatible-allocators.md
|
Hi @teor2345 |
teor2345
left a comment
There was a problem hiding this comment.
Sorry, I can't merge this without changes. Try to minimise changes to existing code.
| # Actions are pinned to a commit to prevent supply-chain attacks | ||
| steps: | ||
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | ||
|
|
||
| - name: Build Rust in each example | ||
| run: | | ||
| # FIXME: handle spaces and special characters in example directory names (in all jobs) | ||
| for EXAMPLE in $(find examples -name Cargo.toml | sort); do | ||
| EXAMPLE=$(dirname "$EXAMPLE") | ||
| echo "Building Rust in '$EXAMPLE'..." | ||
| # cd, but using a stack of directories that can be popped off |
There was a problem hiding this comment.
Please don't modify or delete existing comments or the newline at the end of the file. This note applies to the whole file.
(If your AI tool has done this, it might not reliably stop when you tell it to. Instead, you can use git reset <commit-hash> and git add to interactively choose which parts of the changes to commit.)
| - name: Install C toolchain | ||
| run: sudo apt-get install -y gcc make | ||
|
|
||
| - name: Mark run.sh scripts as executable | ||
| run: | | ||
| find examples -name run.sh -exec chmod +x {} \; |
There was a problem hiding this comment.
These steps aren't necessary for any other examples. Please use the pre-installed C++ compiler instead (likely clang or clang++), and mark the scripts executable and commit that change.
|
|
||
| let length = length as usize; | ||
|
|
||
| let _ = Vec::from_raw_parts(ptr, length, length); |
There was a problem hiding this comment.
This does not meet the safety conditions:
https://doc.rust-lang.org/std/vec/struct.Vec.html#safety
Summary
This PR adds a build script example showing how to correctly allocate
memory in Rust and free it from C using a plain Makefile.
It directly relates to:
What's included
src/lib.rs— exposes rust_alloc_array() and rust_free_array() via extern Cmain.c— calls rust_alloc_array() and frees correctly using rust_free_array()Makefile— builds Rust staticlib with cargo, links with gccCargo.toml— configures the crate as a staticlibREADME.md— explains the example and the key safety ruleHow to run
cd examples/allocator-interop-makefile makeExpected output:
Key point
Calling C's free() on a Rust-allocated pointer is undefined behaviour.
This example shows the correct pattern: rust_free_array() takes back
ownership of the Vec and drops it using Rust's allocator.
Notes
This is submitted as part of the Outreachy Round 32 contribution
process for the "Adding Rust to an existing C/C++ build system" project.