253 lines
8.9 KiB
Rust
253 lines
8.9 KiB
Rust
mod build;
|
|
mod command;
|
|
mod dependencies;
|
|
mod packaging;
|
|
mod version;
|
|
|
|
use afs::Layout;
|
|
use alvr_filesystem as afs;
|
|
use pico_args::Arguments;
|
|
use std::{fs, time::Instant};
|
|
use xshell::{cmd, Shell};
|
|
|
|
const HELP_STR: &str = r#"
|
|
cargo xtask
|
|
Developement actions for ALVR.
|
|
|
|
USAGE:
|
|
cargo xtask <SUBCOMMAND> [FLAG] [ARGS]
|
|
|
|
SUBCOMMANDS:
|
|
prepare-deps Download and compile server and client external dependencies
|
|
build-server Build server driver, then copy binaries to build folder
|
|
build-client Build client, then copy binaries to build folder
|
|
build-client-lib Build a C-ABI ALVR client library and header.
|
|
run-server Build server and then open the launcher
|
|
package-server Build server in release mode, make portable version and installer
|
|
package-client-lib Build client library then zip it
|
|
clean Removes all build artifacts and dependencies.
|
|
bump Bump server and client package versions
|
|
clippy Show warnings for selected clippy lints
|
|
kill-oculus Kill all Oculus processes
|
|
|
|
FLAGS:
|
|
--help Print this text
|
|
--no-nvidia Disables nVidia support on Linux. For prepare-deps subcommand
|
|
--release Optimized build without debug info. For build subcommands
|
|
--gpl Bundle GPL libraries. For build subcommands
|
|
--experiments Build unfinished features. For build subcommands
|
|
--local-ffmpeg Use local build of ffmpeg in non GPL build. For build subcommands
|
|
--appimage Package as AppImage. For package-server subcommand
|
|
--zsync For --appimage, create .zsync update file and build AppImage with embedded update information. For package-server subcommand
|
|
--nightly Append nightly tag to versions. For bump subcommand
|
|
--no-rebuild Do not rebuild the server with run-server
|
|
--ci Do some CI related tweaks. Depends on the other flags and subcommand
|
|
|
|
ARGS:
|
|
--platform <NAME> Name of the platform (operative system or hardware name). snake_case
|
|
--version <VERSION> Specify version to set with the bump-versions subcommand
|
|
--root <PATH> Installation root. By default no root is set and paths are calculated using
|
|
relative paths, which requires conforming to FHS on Linux.
|
|
"#;
|
|
|
|
// Crates at "alvr/" level that are prefixed with "alvr_"
|
|
pub fn crate_dir_names() -> Vec<String> {
|
|
let sh = Shell::new().unwrap();
|
|
|
|
// NB: macOS might create a .DS_Store file. Filter to only directories
|
|
sh.read_dir(afs::workspace_dir().join("alvr"))
|
|
.unwrap()
|
|
.into_iter()
|
|
.filter(|path| path.is_dir())
|
|
.map(|path| {
|
|
path.file_name()
|
|
.unwrap()
|
|
.to_string_lossy()
|
|
.as_ref()
|
|
.to_owned()
|
|
})
|
|
.collect()
|
|
}
|
|
|
|
pub fn run_server() {
|
|
let sh = Shell::new().unwrap();
|
|
|
|
let launcher_exe = Layout::new(&afs::server_build_dir()).launcher_exe();
|
|
|
|
cmd!(sh, "{launcher_exe}").run().unwrap();
|
|
}
|
|
|
|
pub fn clean() {
|
|
fs::remove_dir_all(afs::build_dir()).ok();
|
|
fs::remove_dir_all(afs::deps_dir()).ok();
|
|
if afs::target_dir() == afs::workspace_dir().join("target") {
|
|
// Detete target folder only if in the local wokspace!
|
|
fs::remove_dir_all(afs::target_dir()).ok();
|
|
}
|
|
}
|
|
|
|
fn clippy() {
|
|
let crate_flags = crate_dir_names()
|
|
.into_iter()
|
|
.filter(|name| name != "client" && name != "vulkan_layer")
|
|
.flat_map(|name| ["-p".into(), format!("alvr_{name}")]);
|
|
|
|
// lints updated for Rust 1.59
|
|
let restriction_lints = [
|
|
// "allow_attributes_without_reason", // Rust 1.61
|
|
"clone_on_ref_ptr",
|
|
"create_dir",
|
|
"decimal_literal_representation",
|
|
"else_if_without_else",
|
|
"expect_used",
|
|
"float_cmp_const",
|
|
"fn_to_numeric_cast_any",
|
|
"get_unwrap",
|
|
"if_then_some_else_none",
|
|
"let_underscore_must_use",
|
|
"lossy_float_literal",
|
|
"mem_forget",
|
|
"multiple_inherent_impl",
|
|
"rest_pat_in_fully_bound_structs",
|
|
"self_named_module_files",
|
|
"str_to_string",
|
|
"string_slice",
|
|
"string_to_string",
|
|
"try_err",
|
|
"unnecessary_self_imports",
|
|
"unneeded_field_pattern",
|
|
"unseparated_literal_suffix",
|
|
"verbose_file_reads",
|
|
"wildcard_enum_match_arm",
|
|
];
|
|
let pedantic_lints = [
|
|
// "borrow_as_ptr", // Rust 1.60
|
|
"enum_glob_use",
|
|
"explicit_deref_methods",
|
|
"explicit_into_iter_loop",
|
|
"explicit_iter_loop",
|
|
"filter_map_next",
|
|
"flat_map_option",
|
|
"float_cmp",
|
|
// todo: add more lints
|
|
];
|
|
|
|
let flags = restriction_lints
|
|
.into_iter()
|
|
.chain(pedantic_lints)
|
|
.flat_map(|name| ["-W".to_owned(), format!("clippy::{name}")]);
|
|
|
|
let sh = Shell::new().unwrap();
|
|
cmd!(sh, "cargo clippy {crate_flags...} -- {flags...}")
|
|
.run()
|
|
.unwrap();
|
|
}
|
|
|
|
// Avoid Oculus link popups when debugging the client
|
|
pub fn kill_oculus_processes() {
|
|
let sh = Shell::new().unwrap();
|
|
cmd!(
|
|
sh,
|
|
"powershell Start-Process taskkill -ArgumentList \"/F /IM OVR* /T\" -Verb runas"
|
|
)
|
|
.run()
|
|
.unwrap();
|
|
}
|
|
|
|
fn main() {
|
|
let begin_time = Instant::now();
|
|
|
|
let mut args = Arguments::from_env();
|
|
|
|
if args.contains(["-h", "--help"]) {
|
|
println!("{HELP_STR}");
|
|
} else if let Ok(Some(subcommand)) = args.subcommand() {
|
|
let no_nvidia = args.contains("--no-nvidia");
|
|
let is_release = args.contains("--release");
|
|
let gpl = args.contains("--gpl");
|
|
let experiments = args.contains("--experiments");
|
|
let is_nightly = args.contains("--nightly");
|
|
let no_rebuild = args.contains("--no-rebuild");
|
|
let for_ci = args.contains("--ci");
|
|
|
|
let appimage = args.contains("--appimage");
|
|
let zsync = args.contains("--zsync");
|
|
|
|
let local_ffmpeg = args.contains("--local-ffmpeg");
|
|
|
|
let platform: Option<String> = args.opt_value_from_str("--platform").unwrap();
|
|
let version: Option<String> = args.opt_value_from_str("--version").unwrap();
|
|
let root: Option<String> = args.opt_value_from_str("--root").unwrap();
|
|
|
|
if args.finish().is_empty() {
|
|
match subcommand.as_str() {
|
|
"prepare-deps" => {
|
|
if let Some(platform) = platform {
|
|
match platform.as_str() {
|
|
"windows" => dependencies::prepare_windows_deps(for_ci),
|
|
"linux" => dependencies::build_ffmpeg_linux(!no_nvidia),
|
|
"android" => dependencies::build_android_deps(for_ci),
|
|
_ => panic!("Unrecognized platform."),
|
|
}
|
|
} else {
|
|
if cfg!(windows) {
|
|
dependencies::prepare_windows_deps(for_ci);
|
|
} else if cfg!(target_os = "linux") {
|
|
dependencies::build_ffmpeg_linux(!no_nvidia);
|
|
}
|
|
|
|
dependencies::build_android_deps(for_ci);
|
|
}
|
|
}
|
|
"build-server" => {
|
|
build::build_server(is_release, gpl, None, false, experiments, local_ffmpeg)
|
|
}
|
|
"build-client" => build::build_quest_client(is_release),
|
|
"build-client-lib" => build::build_client_lib(is_release),
|
|
"run-server" => {
|
|
if !no_rebuild {
|
|
build::build_server(
|
|
is_release,
|
|
gpl,
|
|
None,
|
|
false,
|
|
experiments,
|
|
local_ffmpeg,
|
|
);
|
|
}
|
|
run_server();
|
|
}
|
|
"package-server" => {
|
|
packaging::package_server(root, gpl, local_ffmpeg, appimage, zsync)
|
|
}
|
|
"package-client" => build::build_quest_client(true),
|
|
"package-client-lib" => packaging::package_client_lib(),
|
|
"clean" => clean(),
|
|
"bump" => version::bump_version(version, is_nightly),
|
|
"clippy" => clippy(),
|
|
"kill-oculus" => kill_oculus_processes(),
|
|
_ => {
|
|
println!("\nUnrecognized subcommand.");
|
|
println!("{HELP_STR}");
|
|
return;
|
|
}
|
|
}
|
|
} else {
|
|
println!("\nWrong arguments.");
|
|
println!("{HELP_STR}");
|
|
return;
|
|
}
|
|
} else {
|
|
println!("\nMissing subcommand.");
|
|
println!("{HELP_STR}");
|
|
return;
|
|
}
|
|
|
|
let elapsed_time = Instant::now() - begin_time;
|
|
println!(
|
|
"\nDone [{}m {}s]\n",
|
|
elapsed_time.as_secs() / 60,
|
|
elapsed_time.as_secs() % 60
|
|
);
|
|
}
|