Expand description
ferroui-build
Build-script support: compiles the markup documents of a crate to Rust
source and embeds its assets (docs/porting/xaml.md, section 9.6). The
counterpart of the build tasks of the upstream project
(CompileXamlTask with XamlCompilerTaskExecutor, and
GenerateResourcesTask), which run after the compiler and rewrite the
assembly; a Rust crate has no such step, so the build script of the crate
runs before the compiler and writes source the crate includes.
// build.rs
fn main() {
ferroui_controls::register_types(); // the types the documents name
ferroui_build::Build::from_env()
.assembly(&ASSEMBLY) // the assembly of the crate
.embed_assets(&["Assets"])
.compile_xaml() // every *.xaml of the crate
.run();
}
// lib.rs
ferroui_markup_xaml::include_compiled_xaml!(); // pub mod compiled_xaml, pub mod compiled_markup
pub fn register_types() { /* .. */ compiled_markup::register(); }§What a run does, in order
- Reads the
.xamlmetaof every crate the crate depends on directly (DEP_<CRATE>_XAML_XAMLMETA, which Cargo sets from thelinkskey and thecargo::metadata=xamlmeta=<path>line of that crate) and, transitively, the files they name: the compiled documents an include of a document of another crate is linked to. - Compiles each group of documents as upstream compiles the documents of
an assembly (parse, transform, group transformers, emit) and writes
$OUT_DIR/xaml/<module>.rswith its position map. - Lists the assets, leaving out the documents it compiled (upstream removes a compiled resource from the assembly).
- Writes
$OUT_DIR/<crate>.xamlmeta(the compiled documents of the crate, and the paths of the files of step 1) and$OUT_DIR/xaml/mod.rs(the modules of the groups, the asset table, the loader table of the crate andregister()). - Prints the
cargo::lines:rerun-if-changedfor every input,metadata=xamlmeta=<path>for the crates that depend on this one, andrustc-env=FERROUI_XAMLMETA=<path>for the crate itself.
Every document is compiled before the run fails: each error is printed as
a cargo::error= line, and the script exits with a failure once.
§Diagnostics
What the compiler reports has the code of upstream’s build task
(FerroXamlDiagnosticCodes) and, where it is known, the document and the
position: Views/Main.xaml(12,8): warning FRN2208: ... A diagnostic of the
transform goes through the filter of upstream’s task
(xaml_compiler_diagnostics_filter): the EditorConfig files of the build
(Build::analyzer_config_files) state its severity by its code, and
Build::warnings_as_errors makes every warning that is left an error. A
warning is a cargo::warning= line; an error fails the build: a group that
does not transform (FRN2000, once for the group, or the diagnostics of the
transform that say why), a document the emitter refuses (FRN3000, with the
document and the node), a class no load by URI can create (FRN3001, a
warning).
§Where the type metadata comes from
A build compiles against the type models of the crates
(TypeSystem::Model, the next section): this crate links the compiler
(the transform and the emitter of Rust source) and the base crate, and
neither the XAML runtime library nor the controls, so a build script that
uses it builds none of them for the host.
The other host is the feature runtime-host (TypeSystem::Runtime): the
compiler transforms a document against the run-time type system, the
types, properties and constructors the crates registered in the process
(register_types() of each). A build script that enables it takes the crates
whose types its documents name as build dependencies and registers them
before it calls Build::run, and it starts whatever application
services the transform of its documents needs. Two consequences:
- those crates are built for the host as well as for the target (once more when the two differ or their features do);
- a build script cannot link the crate it builds, so it cannot compile a
document that names a type of that crate: neither the document of a
class of the crate (
x:Class) nor a document that uses one of its types. Such a document is generated by a test of the crate and checked in (rust_emitter::generate_class_file); its loader table and its.xamlmetajoin the ones of the build throughBuild::loaderandBuild::checked_in_metadata.
The feature links the XAML runtime library and, through it, the controls. No crate of the repository enables it.
§The build-time type model
The way out of both consequences is xaml.md 9.5: the types read from the
sources instead of the process. With Build::type_system and
TypeSystem::Model a build scans the crate, reads the type models of
the crates it depends on from their .xamlmeta (the framework crates
export theirs from their own build scripts) and compiles every group
against the type system over those models: the build script registers
nothing, needs no crate for its types, and compiles the documents of the
classes of the crate it builds (XamlGroup::class_document). The
run-time type system stays the value of a build that does not state one, and
is an error of the build without the feature runtime-host.
// build.rs
fn main() {
ferroui_build::Build::from_env()
.type_system(ferroui_build::TypeSystem::Model) // the assembly is the one the sources state
.compile_group(XamlGroup::new("compiled_xaml").documents(DOCUMENTS))
.compile_group(XamlGroup::new("compiled_main_window").documents(VIEWS).class_document("MainWindow.xaml"))
.run();
}What is here:
model,scanner,model_set,call_forms,export: the type model of a crate and its file (the.xamlmetaof format 2), the source scanner that fills it, the models of several crates read together, the call form of every declared member, and the export of a model from a build script. They are the crateferroui-build-scan, which links nothing of the framework so that the framework crates can scan themselves with it, exported here under the names they had in this crate;Build::export_metadata: the scan of the crate, with the models of its dependencies, written into its.xamlmeta;type_system: the type system of the compiler over the models (ModelTypeSystem, xaml.md 9.5.5), with the closed table of runtime library types it shares with the run-time type system, and what the models state for the emitter (ModelEmitTypes, xaml.md 9.5.12).
What a build against the models does not have yet: the compile-time value parser of the run-time host (text a type refuses is found when the document is built, not when it is compiled), and a position map for the file of a class.
// build.rs of a crate that declares types and has no documents
fn main() {
ferroui_build::Build::from_env().export_metadata().run();
}§A crate with checked-in compiled markup
A crate that keeps all of its compiled markup checked in (the two themes)
does not need this crate: its build script prints the line of step 5 for
its checked-in file, and its manifest has the links key.
println!("cargo::metadata=xamlmeta={}/compiled_xaml.xamlmeta", env!("CARGO_MANIFEST_DIR"));Modules§
- call_
forms - The choice of a call form for every callable of a model
(docs/porting/xaml.md, 9.5.3): how generated code calls a constructor, a
method, a static field, an event,
Parseor the accessor of a plain property that a declaration states by a callable. - deterministic_
id_ generator - Port of
DeterministicIdGenerator.cs. - export
- The export of the type model of a crate from its build script
(docs/porting/xaml.md, 9.5.13 and 9.6.3): the sources of the crate are
scanned, with the models of the crates it depends on, and the model is
written to
$OUT_DIR/<crate>.xamlmeta, whose path Cargo hands to the build scripts of the crates that depend on this one (thelinkskey of the manifest and thecargo::metadata=xamlmeta=<path>line: they readDEP_<LINKS>_XAMLMETA). - model
- The build-time type model of a crate and its serialised form, the
.xamlmetafile (docs/porting/xaml.md, 9.5.1). - model_
set - The models of several crates read together: the model of a crate and the models of the crates it is built on (docs/porting/xaml.md, 9.5.1 and 9.6.3).
- scanner
- The source scanner: reads the sources of a crate and fills the build-time type model from its declarations (docs/porting/xaml.md, 9.5.1 and 9.5.2).
- type_
system - The build-time type system of the compiler: the type-system contracts of
XamlX (
IXamlTypeSystem,IXamlTypeand its members) over the type models of a set of crates (AssemblyModel) and the closed table of runtime library types (docs/porting/xaml.md, 9.5.2 and 9.5.5). - xaml_
compiler_ diagnostics_ filter - Port of
XamlCompilerDiagnosticsFilter.cs.
Structs§
- Build
- The build of the markup of a crate; see the crate documentation.
- Outcome
- What a build did: the lines for Cargo and the errors.
- Xaml
Group - A group of documents that are compiled together into one module: the group transformers see every document of it, so includes between them are linked, as upstream compiles the documents of an assembly.
Enums§
- Class
Constructor - The public constructor of a class that the loader table of its document
creates the class with (
XamlCompilerTaskExecutor: a public parameterless constructor, else a public constructor whose single parameter is the service provider). The name is the associated function of the class. - Type
System - The type system the documents of a build are compiled against (
Build::type_system).
Constants§
- DEFAULT_
MODULE - The name of the module of the default group (
Build::compile_xaml). - XAMLMETA_
VARIABLE - The environment variable the build sets for the crate: the path of its
.xamlmeta(env!("FERROUI_XAMLMETA")).
Functions§
- compile_
xaml - Compiles every
.xamlfile of the crate whose build script is running (Build::from_env().assembly(assembly).compile_xaml().run()). - embed_
assets - Embeds the files below
directoriesas the assets of the crate whose build script is running (Build::from_env().assembly(assembly).embed_assets(directories).run()). - export_
metadata - Scans the sources of the crate whose build script is running and exports its type
model (
Build::from_env().export_metadata().run()).