///|
pub(all) enum Command {
Build(target_dir~ : String, targets~ : Array[Target], paths~ : Array[String])
Exec(target~ : Target, argv~ : Array[String])
Help
Version
} derive(Eq, Debug)
///|
/// The default value of `--target-dir`.
pub let default_target_dir : String = "_build/cross"
///|
pub fn help_text() -> String {
(
#|Usage:
#| zig-cross build [--target-dir DIR] ... [-- ...]
#| zig-cross exec -- ...
#| zig-cross --help | --version
#|
#|build Build the native release binaries for each target with `moon build`, check the
#| header of each executable, and print a summary. The wrappers go to DIR/zig/.
#| DIR is "_build/cross" by default. The output of a target goes to DIR/.
#|exec Run the command with MOON_CC and MOON_AR set to the wrappers of one target.
#|
#|Targets: linux-x64, linux-arm64, darwin-arm64, darwin-x64, windows-x64, host
#|Zig 0.17.0 must be on PATH. zig-cross runs on Linux and macOS only.
)
}
///|
fn parse_target(text : String) -> Result[Target, String] {
match Target::parse(text) {
Some(target) => Ok(target)
None =>
Err(
"unknown target: \{text} (expected one of \{all_target_names().join(", ")})",
)
}
}
///|
fn parse_build(args : ArrayView[String]) -> Result[Command, String] {
let mut target_dir = default_target_dir
let targets : Array[Target] = []
let paths : Array[String] = []
let mut in_paths = false
let mut i = 0
while i < args.length() {
let arg = args[i]
if in_paths {
paths.push(arg)
} else if arg == "--" {
in_paths = true
} else if arg == "--target-dir" {
i += 1
if i >= args.length() {
return Err("give a directory after --target-dir")
}
target_dir = args[i]
} else if arg.has_prefix("--target-dir=") {
target_dir = arg[13:].to_owned()
} else if arg.has_prefix("-") {
return Err("unknown option: \{arg}")
} else {
match parse_target(arg) {
Ok(target) => targets.push(target)
Err(message) => return Err(message)
}
}
i += 1
}
if targets.is_empty() {
return Err("give at least one target")
}
Ok(Build(target_dir~, targets~, paths~))
}
///|
fn parse_exec(args : ArrayView[String]) -> Result[Command, String] {
if args.is_empty() {
return Err("give a target")
}
let target = match parse_target(args[0]) {
Ok(target) => target
Err(message) => return Err(message)
}
if args.length() < 3 || args[1] != "--" {
return Err("give a command after --")
}
Ok(Exec(target~, argv=args[2:].to_owned()))
}
///|
/// Parse the arguments, without `argv[0]`.
pub fn parse_args(args : Array[String]) -> Result[Command, String] {
if args.is_empty() {
return Ok(Help)
}
match args[0] {
"--help" | "-h" => Ok(Help)
"--version" => Ok(Version)
"build" => parse_build(args[1:])
"exec" => parse_exec(args[1:])
other => Err("unknown command: \{other} (expected build or exec)")
}
}