mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-28 04:45:13 +00:00

This is relatively straight-forward via a pass in the compiler to collect the resources to embed and then use include_bytes! (once per resource). What's really annoying is that the rust resource enum can't store a &'static [u8] because cbindgen doesn't represent that, probably because the slice representation isn't guaranteed to stay as it is. So instead this, for now, uses raw pointers.
109 lines
3.8 KiB
Rust
109 lines
3.8 KiB
Rust
use sixtyfps_compilerlib::*;
|
|
use std::error::Error;
|
|
use std::io::Write;
|
|
|
|
pub fn test(testcase: &test_driver_lib::TestCase) -> Result<(), Box<dyn Error>> {
|
|
let source = std::fs::read_to_string(&testcase.absolute_path)?;
|
|
|
|
let (syntax_node, mut diag) = parser::parse(&source);
|
|
diag.current_path = testcase.absolute_path.clone();
|
|
let mut tr = typeregister::TypeRegister::builtin();
|
|
let doc = object_tree::Document::from_node(syntax_node, &mut diag, &mut tr);
|
|
let compiler_config = CompilerConfiguration::default();
|
|
run_passes(&doc, &mut diag, &mut tr, &compiler_config);
|
|
|
|
if diag.has_error() {
|
|
let vec = diag.inner.iter().map(|d| d.message.clone()).collect::<Vec<String>>();
|
|
return Err(vec.join("\n").into());
|
|
}
|
|
|
|
let mut generated_cpp: Vec<u8> = Vec::new();
|
|
|
|
generator::generate(&mut generated_cpp, &doc.root_component, &mut diag)?;
|
|
|
|
if diag.has_error() {
|
|
let vec = diag.inner.iter().map(|d| d.message.clone()).collect::<Vec<String>>();
|
|
return Err(vec.join("\n").into());
|
|
}
|
|
|
|
generated_cpp.write_all(b"int main() {\n")?;
|
|
for x in test_driver_lib::extract_test_functions(&source).filter(|x| x.language_id == "cpp") {
|
|
write!(generated_cpp, " {{\n {}\n }}\n", x.source.replace("\n", "\n "))?;
|
|
}
|
|
generated_cpp.write_all(b"}\n")?;
|
|
|
|
//println!("CODE: {}", String::from_utf8(generated_cpp.clone())?);
|
|
|
|
let mut cpp_file = tempfile::Builder::new().suffix(".cpp").tempfile()?;
|
|
|
|
cpp_file
|
|
.write(&generated_cpp)
|
|
.map_err(|err| format!("Error writing generated code: {}", err))?;
|
|
cpp_file
|
|
.as_file()
|
|
.sync_all()
|
|
.map_err(|err| format!("Error flushing generated code to disk: {}", err))?;
|
|
|
|
let compiler = cc::Build::new()
|
|
.cargo_metadata(false)
|
|
.cpp(true)
|
|
.opt_level_str(env!("OPT_LEVEL"))
|
|
.target(env!("TARGET"))
|
|
.host(env!("HOST"))
|
|
.include(env!("GENERATED_CPP_HEADERS_PATH"))
|
|
.include(env!("CPP_API_HEADERS_PATH"))
|
|
.try_get_compiler()?;
|
|
|
|
let mut compiler_command = compiler.to_command();
|
|
|
|
let binary_path = cpp_file.path().with_extension(std::env::consts::EXE_EXTENSION);
|
|
|
|
let keep_temp_files = std::env::var("KEEP_TEMP_FILES").is_ok();
|
|
|
|
let binary_path = scopeguard::guard(binary_path, |path| {
|
|
if !keep_temp_files {
|
|
std::fs::remove_file(path).unwrap_or(());
|
|
}
|
|
});
|
|
|
|
compiler_command.arg("-o").arg(binary_path.clone()).arg(cpp_file.path());
|
|
|
|
if compiler.is_like_clang() || compiler.is_like_gnu() {
|
|
compiler_command.arg("-std=c++17");
|
|
compiler_command.arg(concat!("-L", env!("CPP_LIB_PATH")));
|
|
compiler_command.arg("-lsixtyfps_rendering_backend_gl");
|
|
}
|
|
|
|
let output = compiler_command.output()?;
|
|
print!("{}", String::from_utf8_lossy(output.stderr.as_ref()));
|
|
if !output.status.success() {
|
|
return Err("C++ Compilation error (see stdout)".to_owned().into());
|
|
}
|
|
|
|
std::process::Command::new(binary_path.clone())
|
|
.spawn()
|
|
.map_err(|err| format!("Error launching testcase binary: {}", err))?
|
|
.wait()
|
|
.map_err(|err| format!("Test case could not be run: {}", err))
|
|
.and_then(|status| {
|
|
if status.success() {
|
|
Ok(())
|
|
} else if let Some(exit_code) = status.code() {
|
|
Err(format!("Test case exited with non-zero code: {}", exit_code))
|
|
} else {
|
|
Err("Test case exited by signal".into())
|
|
}
|
|
})?;
|
|
|
|
if keep_temp_files {
|
|
println!(
|
|
"Left temporary files behind for {} : source {} binary {}",
|
|
testcase.absolute_path.display(),
|
|
cpp_file.path().display(),
|
|
binary_path.display()
|
|
);
|
|
cpp_file.keep()?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|