mirror of
https://github.com/Kitware/CMake.git
synced 2026-08-04 06:40:24 +00:00
Each Rust source file given to a target is considered a separate crate root. There's a concept of a "main crate root", which is the `.rs` file that is given to the final linker phase in CMake. Other Rust source file in a target are built as rlib separately. The project can still build `.rs` files into object files by setting the Rust_EMIT property on the desired source file.
67 lines
2.0 KiB
Rust
67 lines
2.0 KiB
Rust
|
|
use std::process::Command;
|
|
|
|
#[cfg(target_os="macos")]
|
|
fn is_pie_executable(executable: &str) -> bool {
|
|
let output = Command::new("otool")
|
|
.args(["-hv", executable])
|
|
.output()
|
|
.expect("Failed to check executable");
|
|
if !output.status.success() {
|
|
panic!("otool exited with non-zero exit code");
|
|
}
|
|
|
|
output.stdout.windows(5).any(|w| {
|
|
(w[0] == b' ' || w[0] == b'\t')
|
|
&& (w[1..=3] == b"PIE")
|
|
&& (w[4] == b' ' || w[4] == b'\n')
|
|
})
|
|
}
|
|
|
|
#[cfg(all(target_family="unix", not(target_os="macos")))]
|
|
fn is_pie_executable(executable: &str) -> bool {
|
|
let output = Command::new("readelf")
|
|
.args(["-lW", executable])
|
|
.env("LANG", "C")
|
|
.env("LC_ALL", "C")
|
|
.output()
|
|
.expect("Failed to check executable");
|
|
if !output.status.success() {
|
|
panic!("readelf exited with non-zero exit code");
|
|
}
|
|
let is_pie = output.stdout.windows(20).any(|w| w == b"Elf file type is DYN");
|
|
let is_not_pie = output.stdout.windows(21).any(|w| w == b"Elf file type is EXEC");
|
|
assert!(is_pie ^ is_not_pie, "Cannot determine type of ELF file");
|
|
is_pie
|
|
}
|
|
|
|
fn main() {
|
|
let commands = [
|
|
// The actual path to the commands will be filled in by CMake.
|
|
r#"$<TARGET_FILE:default_RustPie>"#,
|
|
r#"$<TARGET_FILE:disabled_RustPie>"#,
|
|
r#"$<TARGET_FILE:enabled_RustPie>"#,
|
|
];
|
|
for command in commands {
|
|
println!("Start command: {command:?}");
|
|
let result = Command::new(command)
|
|
.spawn()
|
|
.expect("Failed to launch command")
|
|
.wait()
|
|
.expect("Failure while waiting for process to finish")
|
|
.success();
|
|
if !result {
|
|
panic!("Process exited with non-zero exit code.");
|
|
}
|
|
}
|
|
|
|
assert!(
|
|
!is_pie_executable(commands[1]),
|
|
"ERROR: disabled_RustPie must not be a PIE executable, but it is not."
|
|
);
|
|
assert!(
|
|
is_pie_executable(commands[2]),
|
|
"ERROR: enabled_RustPie must be a PIE executable, but it is not."
|
|
);
|
|
}
|