From ec6bdd526c1868750de93ebf182a4ffd50cc289e Mon Sep 17 00:00:00 2001 From: Meister1593 Date: Mon, 4 Aug 2025 10:39:48 +0200 Subject: [PATCH 01/14] Reproducible builds now use --frozen --offline --- alvr/xtask/src/build.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/alvr/xtask/src/build.rs b/alvr/xtask/src/build.rs index 8b2ef9e147..814d17538c 100644 --- a/alvr/xtask/src/build.rs +++ b/alvr/xtask/src/build.rs @@ -40,7 +40,8 @@ pub fn build_server_lib(profile: Profile, root: Option, reproducible: bo Profile::Debug => (), } if reproducible { - flags.push("--locked"); + flags.push("--frozen"); + flags.push("--offline"); } let flags_ref = &flags; @@ -93,7 +94,8 @@ pub fn build_streamer( Profile::Debug => (), } if reproducible { - common_flags.push("--locked"); + common_flags.push("--frozen"); + common_flags.push("--offline"); } let artifacts_dir = if cfg!(all(windows, target_arch = "aarch64")) { @@ -286,7 +288,8 @@ pub fn build_launcher(profile: Profile, reproducible: bool) { Profile::Debug => (), } if reproducible { - common_flags.push("--locked"); + common_flags.push("--frozen"); + common_flags.push("--offline"); } let common_flags_ref = &common_flags; From a2c5eebb7cd706d28c3ed9d8926f19ad10b77d49 Mon Sep 17 00:00:00 2001 From: Meister1593 Date: Mon, 4 Aug 2025 10:46:22 +0200 Subject: [PATCH 02/14] Add reproducible flag and use it whenever possible --- alvr/xtask/src/main.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/alvr/xtask/src/main.rs b/alvr/xtask/src/main.rs index ccd0c6fc5a..9383e2e4be 100644 --- a/alvr/xtask/src/main.rs +++ b/alvr/xtask/src/main.rs @@ -184,6 +184,7 @@ fn main() { let keep_config = args.contains("--keep-config"); let link_stdcpp = !args.contains("--no-stdcpp"); let all_targets = args.contains("--all-targets"); + let reproducible: bool = args.contains("--reproducible"); let platform: Option = args.opt_value_from_str("--platform").unwrap(); let platform = platform.as_deref().map(|platform| match platform { @@ -229,10 +230,10 @@ fn main() { } } "build-streamer" => { - build::build_streamer(profile, gpl, None, false, profiling, keep_config) + build::build_streamer(profile, gpl, None, reproducible, profiling, keep_config) } - "build-launcher" => build::build_launcher(profile, false), - "build-server-lib" => build::build_server_lib(profile, None, false), + "build-launcher" => build::build_launcher(profile, reproducible), + "build-server-lib" => build::build_server_lib(profile, None, reproducible), "build-client" => build::build_android_client(profile), "build-client-lib" => { build::build_android_client_core_lib(profile, link_stdcpp, all_targets) @@ -242,13 +243,13 @@ fn main() { } "run-streamer" => { if !no_rebuild { - build::build_streamer(profile, gpl, None, false, profiling, keep_config); + build::build_streamer(profile, gpl, None, reproducible, profiling, keep_config); } run_streamer(); } "run-launcher" => { if !no_rebuild { - build::build_launcher(profile, false); + build::build_launcher(profile, reproducible); } run_launcher(); } From 2482d9b1f91aaf9e309cd34f3e686ef851128cc1 Mon Sep 17 00:00:00 2001 From: Meister1593 Date: Tue, 5 Aug 2025 21:17:08 +0200 Subject: [PATCH 03/14] separate download, build processes in prepare-deps --- alvr/xtask/src/dependencies.rs | 129 +++++++++++++++++---------------- alvr/xtask/src/main.rs | 47 ++++++------ alvr/xtask/src/packaging.rs | 2 +- 3 files changed, 90 insertions(+), 88 deletions(-) diff --git a/alvr/xtask/src/dependencies.rs b/alvr/xtask/src/dependencies.rs index 3ac3d94c87..831a8e7bca 100644 --- a/alvr/xtask/src/dependencies.rs +++ b/alvr/xtask/src/dependencies.rs @@ -17,11 +17,11 @@ pub fn choco_install(sh: &Shell, packages: &[&str]) -> Result<(), xshell::Error> .run() } -pub fn prepare_x264_windows(deps_path: &Path) { - let sh = Shell::new().unwrap(); - +pub fn prepare_prebuilt_x264_windows(deps_path: &Path) { const VERSION: &str = "0.164"; const REVISION: usize = 3086; + + let sh = Shell::new().unwrap(); let destination = deps_path.join("x264"); @@ -37,7 +37,7 @@ pub fn prepare_x264_windows(deps_path: &Path) { fs::write( afs::deps_dir().join("x264.pc"), format!( - r#" + r" prefix={} exec_prefix=${{prefix}}/bin/x64 libdir=${{prefix}}/lib/x64 @@ -48,7 +48,7 @@ Description: x264 library Version: {VERSION} Libs: -L${{libdir}} -lx264 Cflags: -I${{includedir}} -"#, +", destination.to_string_lossy().replace('\\', "/") ), ) @@ -57,7 +57,7 @@ Cflags: -I${{includedir}} cmd!(sh, "setx PKG_CONFIG_PATH {deps_path}").run().unwrap(); } -pub fn prepare_ffmpeg_windows(deps_path: &Path) { +pub fn prepare_prebuilt_ffmpeg_windows(deps_path: &Path) { command::download_and_extract_zip( &format!( "https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/{}", @@ -89,8 +89,8 @@ pub fn prepare_windows_deps(skip_admin_priv: bool) { .unwrap(); } - prepare_x264_windows(&deps_path); - prepare_ffmpeg_windows(&deps_path); + prepare_prebuilt_x264_windows(&deps_path); + prepare_prebuilt_ffmpeg_windows(&deps_path); } pub fn prepare_linux_deps(enable_nvenc: bool) { @@ -100,13 +100,19 @@ pub fn prepare_linux_deps(enable_nvenc: bool) { sh.remove_path(&deps_path).ok(); sh.create_dir(&deps_path).unwrap(); - build_x264_linux(&deps_path); - build_ffmpeg_linux(enable_nvenc, &deps_path); -} + let x264_src_path = download_linux_x264_src(&deps_path); + let ffmpeg_src_path = download_linux_ffmpeg_src(&deps_path); + let nvenc_headers_path = if enable_nvenc { + Some(download_linux_nvidia_ffmpeg_deps(&deps_path)) + } else { + None + }; -pub fn build_x264_linux(deps_path: &Path) { - let sh = Shell::new().unwrap(); + build_linux_x264(&x264_src_path); + build_linux_ffmpeg(&ffmpeg_src_path, nvenc_headers_path.as_deref()); +} +pub fn download_linux_x264_src(deps_path: &Path) -> std::path::PathBuf { // x264 0.164 command::download_and_extract_tar( "https://code.videolan.org/videolan/x264/-/archive/c196240409e4d7c01b47448d93b1f9683aaa7cf7/x264-c196240409e4d7c01b47448d93b1f9683aaa7cf7.tar.bz2", @@ -114,19 +120,24 @@ pub fn build_x264_linux(deps_path: &Path) { ) .unwrap(); - let final_path = deps_path.join("x264"); + let x264_src_path = deps_path.join("x264"); fs::rename( deps_path.join("x264-c196240409e4d7c01b47448d93b1f9683aaa7cf7"), - &final_path, + &x264_src_path, ) .unwrap(); + x264_src_path +} + +pub fn build_linux_x264(x264_src_path: &Path) { + let sh = Shell::new().unwrap(); let flags = ["--enable-static", "--disable-cli", "--enable-pic"]; - let install_prefix = format!("--prefix={}", final_path.join("alvr_build").display()); + let install_prefix = format!("--prefix={}", x264_src_path.join("alvr_build").display()); - let _push_guard = sh.push_dir(final_path); + let _push_guard = sh.push_dir(x264_src_path); cmd!(sh, "./configure {install_prefix} {flags...}") .run() @@ -137,18 +148,21 @@ pub fn build_x264_linux(deps_path: &Path) { cmd!(sh, "make install").run().unwrap(); } -pub fn build_ffmpeg_linux(enable_nvenc: bool, deps_path: &Path) { - let sh = Shell::new().unwrap(); - +fn download_linux_ffmpeg_src(deps_path: &Path) -> std::path::PathBuf { command::download_and_extract_zip( "https://codeload.github.com/FFmpeg/FFmpeg/zip/n6.0", deps_path, ) .unwrap(); - let final_path = deps_path.join("ffmpeg"); + let ffmpeg_src_path = deps_path.join("ffmpeg"); + fs::rename(deps_path.join("FFmpeg-n6.0"), &ffmpeg_src_path).unwrap(); - fs::rename(deps_path.join("FFmpeg-n6.0"), &final_path).unwrap(); + ffmpeg_src_path +} + +pub fn build_linux_ffmpeg(ffmpeg_src_path: &Path, nvenc_headers_path: Option<&Path>) { + let sh = Shell::new().unwrap(); let flags = [ "--enable-gpl", @@ -176,20 +190,20 @@ pub fn build_ffmpeg_linux(enable_nvenc: bool, deps_path: &Path) { "--enable-rpath", "--fatal-warnings", ]; - let install_prefix = format!("--prefix={}", final_path.join("alvr_build").display()); + let install_prefix = format!("--prefix={}", ffmpeg_src_path.join("alvr_build").display()); // The reason for 4x$ in LDSOFLAGS var refer to https://stackoverflow.com/a/71429999 // all varients of --extra-ldsoflags='-Wl,-rpath,$ORIGIN' do not work! don't waste your time trying! // - let config_vars = r#"-Wl,-rpath,'$$$$ORIGIN'"#; + let config_vars = r"-Wl,-rpath,'$$$$ORIGIN'"; - let _push_guard = sh.push_dir(final_path); + let _push_guard = sh.push_dir(ffmpeg_src_path); let _env_vars = sh.push_env("LDSOFLAGS", config_vars); // Patches ffmpeg for workarounds and patches that have yet to be unstreamed let ffmpeg_command = "for p in ../../../alvr/xtask/patches/*; do patch -p1 < $p; done"; cmd!(sh, "bash -c {ffmpeg_command}").run().unwrap(); - if enable_nvenc { + if let Some(nvenc_headers_path) = nvenc_headers_path { /* Describing Nvidia specific options --nvccflags: nvcc from CUDA toolkit version 11.0 or higher does not support compiling for 'compute_30' (default in ffmpeg) @@ -201,26 +215,11 @@ pub fn build_ffmpeg_linux(enable_nvenc: bool, deps_path: &Path) { */ #[cfg(target_os = "linux")] { - let codec_header_version = "12.1.14.0"; - let temp_download_dir = deps_path.join("dl_temp"); - command::download_and_extract_zip( - &format!("https://github.com/FFmpeg/nv-codec-headers/archive/refs/tags/n{codec_header_version}.zip"), - &temp_download_dir - ) - .unwrap(); - - let header_dir = deps_path.join("nv-codec-headers"); - let header_build_dir = header_dir.join("build"); - fs::rename( - temp_download_dir.join(format!("nv-codec-headers-n{codec_header_version}")), - &header_dir, - ) - .unwrap(); - fs::remove_dir_all(temp_download_dir).unwrap(); + let header_build_dir = nvenc_headers_path.join("build"); { let make_header_cmd = format!("make install PREFIX='{}'", header_build_dir.display()); - let _header_push_guard = sh.push_dir(&header_dir); + let _header_push_guard = sh.push_dir(nvenc_headers_path); cmd!(sh, "bash -c {make_header_cmd}").run().unwrap(); } @@ -274,29 +273,33 @@ pub fn build_ffmpeg_linux(enable_nvenc: bool, deps_path: &Path) { cmd!(sh, "make install").run().unwrap(); } +fn download_linux_nvidia_ffmpeg_deps(deps_path: &Path) -> std::path::PathBuf { + let codec_header_version = "12.1.14.0"; + let temp_download_dir = deps_path.join("dl_temp"); + command::download_and_extract_zip( + &format!("https://github.com/FFmpeg/nv-codec-headers/archive/refs/tags/n{codec_header_version}.zip"), + &temp_download_dir + ) + .unwrap(); + + let header_dir = deps_path.join("nv-codec-headers"); + fs::rename( + temp_download_dir.join(format!("nv-codec-headers-n{codec_header_version}")), + &header_dir, + ) + .unwrap(); + fs::remove_dir_all(temp_download_dir).unwrap(); + header_dir +} + pub fn prepare_macos_deps() {} -pub fn prepare_server_deps( - platform: Option, - skip_admin_priv: bool, - enable_nvenc: bool, -) { +pub fn prepare_server_deps(platform: BuildPlatform, skip_admin_priv: bool, enable_nvenc: bool) { match platform { - Some(BuildPlatform::Windows) => prepare_windows_deps(skip_admin_priv), - Some(BuildPlatform::Linux) => prepare_linux_deps(enable_nvenc), - Some(BuildPlatform::Macos) => prepare_macos_deps(), - Some(BuildPlatform::Android) => panic!("Android is not supported"), - None => { - if cfg!(windows) { - prepare_windows_deps(skip_admin_priv); - } else if cfg!(target_os = "linux") { - prepare_linux_deps(enable_nvenc); - } else if cfg!(target_os = "macos") { - prepare_macos_deps(); - } else { - panic!("Unsupported platform"); - } - } + BuildPlatform::Windows => prepare_windows_deps(skip_admin_priv), + BuildPlatform::Linux => prepare_linux_deps(enable_nvenc), + BuildPlatform::Macos => prepare_macos_deps(), + BuildPlatform::Android => panic!("Android is not supported"), } } diff --git a/alvr/xtask/src/main.rs b/alvr/xtask/src/main.rs index 9383e2e4be..901b024ea1 100644 --- a/alvr/xtask/src/main.rs +++ b/alvr/xtask/src/main.rs @@ -15,7 +15,7 @@ use pico_args::Arguments; use std::{fs, process, time::Instant}; use xshell::{Shell, cmd}; -const HELP_STR: &str = r#" +const HELP_STR: &str = r" cargo xtask Developement actions for ALVR. @@ -63,7 +63,7 @@ ARGS: --version Specify version to set with the bump-versions subcommand --root Installation root. By default no root is set and paths are calculated using relative paths, which requires conforming to FHS on Linux -"#; +"; enum BuildPlatform { Windows, @@ -187,13 +187,13 @@ fn main() { let reproducible: bool = args.contains("--reproducible"); let platform: Option = args.opt_value_from_str("--platform").unwrap(); - let platform = platform.as_deref().map(|platform| match platform { - "windows" => BuildPlatform::Windows, - "linux" => BuildPlatform::Linux, - "macos" => BuildPlatform::Macos, - "android" => BuildPlatform::Android, + let platform = match platform.as_deref() { + Some("windows") => BuildPlatform::Windows, + Some("linux") => BuildPlatform::Linux, + Some("macos") => BuildPlatform::Macos, + Some("android") => BuildPlatform::Android, _ => print_help_and_exit("Unrecognized platform"), - }); + }; let version: Option = args.opt_value_from_str("--version").unwrap(); let root: Option = args.opt_value_from_str("--root").unwrap(); @@ -209,26 +209,18 @@ fn main() { if args.finish().is_empty() { match subcommand.as_str() { "prepare-deps" => { - if let Some(platform) = platform { - if matches!(platform, BuildPlatform::Android) { - dependencies::build_android_deps( - for_ci, - all_targets, - OpenXRLoadersSelection::All, - ); - } else { - dependencies::prepare_server_deps(Some(platform), for_ci, !no_nvidia); - } - } else { - dependencies::prepare_server_deps(platform, for_ci, !no_nvidia); - + if matches!(platform, BuildPlatform::Android) { dependencies::build_android_deps( for_ci, all_targets, OpenXRLoadersSelection::All, ); + } else { + dependencies::prepare_server_deps(platform, for_ci, !no_nvidia); } } + "download-server-deps" => todo!(), + "build-server-deps" => todo!(), "build-streamer" => { build::build_streamer(profile, gpl, None, reproducible, profiling, keep_config) } @@ -243,7 +235,14 @@ fn main() { } "run-streamer" => { if !no_rebuild { - build::build_streamer(profile, gpl, None, reproducible, profiling, keep_config); + build::build_streamer( + profile, + gpl, + None, + reproducible, + profiling, + keep_config, + ); } run_streamer(); } @@ -265,9 +264,9 @@ fn main() { "bump" => version::bump_version(version, is_nightly), "clippy" => { if for_ci { - ci::clippy_ci() + ci::clippy_ci(); } else { - clippy() + clippy(); } } "check-msrv" => version::check_msrv(), diff --git a/alvr/xtask/src/packaging.rs b/alvr/xtask/src/packaging.rs index eeea148ffa..63497352df 100644 --- a/alvr/xtask/src/packaging.rs +++ b/alvr/xtask/src/packaging.rs @@ -51,7 +51,7 @@ pub fn include_licenses(root_path: &Path, gpl: bool) { } pub fn package_streamer( - platform: Option, + platform: BuildPlatform, skip_admin_priv: bool, enable_nvenc: bool, gpl: bool, From 26ae9d2fcf5b8a1547d0048a1d127779190213ce Mon Sep 17 00:00:00 2001 From: Meister1593 Date: Tue, 5 Aug 2025 21:39:24 +0200 Subject: [PATCH 04/14] make dependencies paths available beforehand --- alvr/xtask/src/dependencies.rs | 78 +++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/alvr/xtask/src/dependencies.rs b/alvr/xtask/src/dependencies.rs index 831a8e7bca..5ec65ca728 100644 --- a/alvr/xtask/src/dependencies.rs +++ b/alvr/xtask/src/dependencies.rs @@ -20,7 +20,7 @@ pub fn choco_install(sh: &Shell, packages: &[&str]) -> Result<(), xshell::Error> pub fn prepare_prebuilt_x264_windows(deps_path: &Path) { const VERSION: &str = "0.164"; const REVISION: usize = 3086; - + let sh = Shell::new().unwrap(); let destination = deps_path.join("x264"); @@ -93,46 +93,62 @@ pub fn prepare_windows_deps(skip_admin_priv: bool) { prepare_prebuilt_ffmpeg_windows(&deps_path); } +fn linux_deps_path() -> std::path::PathBuf { + afs::deps_dir().join("linux") +} + +fn linux_x264_path() -> std::path::PathBuf { + linux_deps_path().join("x264") +} + +fn linux_ffmpeg_path() -> std::path::PathBuf { + linux_deps_path().join("ffmpeg") +} + +fn linux_nvenc_headers_path() -> std::path::PathBuf { + linux_deps_path().join("nv-codec-headers") +} + pub fn prepare_linux_deps(enable_nvenc: bool) { let sh = Shell::new().unwrap(); - let deps_path = afs::deps_dir().join("linux"); + let deps_path = linux_deps_path(); sh.remove_path(&deps_path).ok(); sh.create_dir(&deps_path).unwrap(); - let x264_src_path = download_linux_x264_src(&deps_path); - let ffmpeg_src_path = download_linux_ffmpeg_src(&deps_path); - let nvenc_headers_path = if enable_nvenc { - Some(download_linux_nvidia_ffmpeg_deps(&deps_path)) - } else { - None - }; + download_linux_x264_src(); + download_linux_ffmpeg_src(); + if enable_nvenc { + download_linux_nvidia_ffmpeg_deps(); + } - build_linux_x264(&x264_src_path); - build_linux_ffmpeg(&ffmpeg_src_path, nvenc_headers_path.as_deref()); + build_linux_x264(); + build_linux_ffmpeg(enable_nvenc); } -pub fn download_linux_x264_src(deps_path: &Path) -> std::path::PathBuf { +pub fn download_linux_x264_src() { + let deps_path = linux_deps_path(); + let x264_src_path = linux_x264_path(); + // x264 0.164 command::download_and_extract_tar( "https://code.videolan.org/videolan/x264/-/archive/c196240409e4d7c01b47448d93b1f9683aaa7cf7/x264-c196240409e4d7c01b47448d93b1f9683aaa7cf7.tar.bz2", - deps_path, + &deps_path, ) .unwrap(); - let x264_src_path = deps_path.join("x264"); - fs::rename( deps_path.join("x264-c196240409e4d7c01b47448d93b1f9683aaa7cf7"), &x264_src_path, ) .unwrap(); - x264_src_path } -pub fn build_linux_x264(x264_src_path: &Path) { +pub fn build_linux_x264() { let sh = Shell::new().unwrap(); + let x264_src_path = linux_x264_path(); + let flags = ["--enable-static", "--disable-cli", "--enable-pic"]; let install_prefix = format!("--prefix={}", x264_src_path.join("alvr_build").display()); @@ -148,22 +164,25 @@ pub fn build_linux_x264(x264_src_path: &Path) { cmd!(sh, "make install").run().unwrap(); } -fn download_linux_ffmpeg_src(deps_path: &Path) -> std::path::PathBuf { +fn download_linux_ffmpeg_src() { + let deps_path = linux_deps_path(); + let ffmpeg_src_path = linux_ffmpeg_path(); + command::download_and_extract_zip( "https://codeload.github.com/FFmpeg/FFmpeg/zip/n6.0", - deps_path, + &deps_path, ) .unwrap(); - let ffmpeg_src_path = deps_path.join("ffmpeg"); fs::rename(deps_path.join("FFmpeg-n6.0"), &ffmpeg_src_path).unwrap(); - - ffmpeg_src_path } -pub fn build_linux_ffmpeg(ffmpeg_src_path: &Path, nvenc_headers_path: Option<&Path>) { +pub fn build_linux_ffmpeg(enable_nvenc: bool) { + let ffmpeg_src_path = linux_ffmpeg_path(); + let nvenc_headers_path = linux_nvenc_headers_path(); + let sh = Shell::new().unwrap(); - + let flags = [ "--enable-gpl", "--enable-version3", @@ -203,7 +222,7 @@ pub fn build_linux_ffmpeg(ffmpeg_src_path: &Path, nvenc_headers_path: Option<&Pa let ffmpeg_command = "for p in ../../../alvr/xtask/patches/*; do patch -p1 < $p; done"; cmd!(sh, "bash -c {ffmpeg_command}").run().unwrap(); - if let Some(nvenc_headers_path) = nvenc_headers_path { + if enable_nvenc { /* Describing Nvidia specific options --nvccflags: nvcc from CUDA toolkit version 11.0 or higher does not support compiling for 'compute_30' (default in ffmpeg) @@ -273,7 +292,10 @@ pub fn build_linux_ffmpeg(ffmpeg_src_path: &Path, nvenc_headers_path: Option<&Pa cmd!(sh, "make install").run().unwrap(); } -fn download_linux_nvidia_ffmpeg_deps(deps_path: &Path) -> std::path::PathBuf { +fn download_linux_nvidia_ffmpeg_deps() { + let deps_path = linux_deps_path(); + let nvenc_headers_path = linux_nvenc_headers_path(); + let codec_header_version = "12.1.14.0"; let temp_download_dir = deps_path.join("dl_temp"); command::download_and_extract_zip( @@ -282,14 +304,12 @@ fn download_linux_nvidia_ffmpeg_deps(deps_path: &Path) -> std::path::PathBuf { ) .unwrap(); - let header_dir = deps_path.join("nv-codec-headers"); fs::rename( temp_download_dir.join(format!("nv-codec-headers-n{codec_header_version}")), - &header_dir, + &nvenc_headers_path, ) .unwrap(); fs::remove_dir_all(temp_download_dir).unwrap(); - header_dir } pub fn prepare_macos_deps() {} From 3a203954d55b56095448068e616c07c32ff6eae2 Mon Sep 17 00:00:00 2001 From: Meister1593 Date: Tue, 5 Aug 2025 23:56:21 +0200 Subject: [PATCH 05/14] adjust modifiers, reorder functions, use download/build functions now --- alvr/xtask/src/dependencies.rs | 423 ------------------------- alvr/xtask/src/dependencies/android.rs | 106 +++++++ alvr/xtask/src/dependencies/linux.rs | 249 +++++++++++++++ alvr/xtask/src/dependencies/mod.rs | 40 +++ alvr/xtask/src/dependencies/windows.rs | 105 ++++++ alvr/xtask/src/main.rs | 8 +- alvr/xtask/src/packaging.rs | 2 +- 7 files changed, 506 insertions(+), 427 deletions(-) delete mode 100644 alvr/xtask/src/dependencies.rs create mode 100644 alvr/xtask/src/dependencies/android.rs create mode 100644 alvr/xtask/src/dependencies/linux.rs create mode 100644 alvr/xtask/src/dependencies/mod.rs create mode 100644 alvr/xtask/src/dependencies/windows.rs diff --git a/alvr/xtask/src/dependencies.rs b/alvr/xtask/src/dependencies.rs deleted file mode 100644 index 5ec65ca728..0000000000 --- a/alvr/xtask/src/dependencies.rs +++ /dev/null @@ -1,423 +0,0 @@ -use crate::{BuildPlatform, command}; -use alvr_filesystem as afs; -use std::{fs, path::Path}; -use xshell::{Shell, cmd}; - -pub enum OpenXRLoadersSelection { - OnlyGeneric, - OnlyPico, - All, -} - -pub fn choco_install(sh: &Shell, packages: &[&str]) -> Result<(), xshell::Error> { - cmd!( - sh, - "powershell Start-Process choco -ArgumentList \"install {packages...} -y\" -Verb runAs -Wait" - ) - .run() -} - -pub fn prepare_prebuilt_x264_windows(deps_path: &Path) { - const VERSION: &str = "0.164"; - const REVISION: usize = 3086; - - let sh = Shell::new().unwrap(); - - let destination = deps_path.join("x264"); - - command::download_and_extract_zip( - &format!( - "{}/{VERSION}.r{REVISION}/libx264_{VERSION}.r{REVISION}_msvc16.zip", - "https://github.com/ShiftMediaProject/x264/releases/download", - ), - &destination, - ) - .unwrap(); - - fs::write( - afs::deps_dir().join("x264.pc"), - format!( - r" -prefix={} -exec_prefix=${{prefix}}/bin/x64 -libdir=${{prefix}}/lib/x64 -includedir=${{prefix}}/include - -Name: x264 -Description: x264 library -Version: {VERSION} -Libs: -L${{libdir}} -lx264 -Cflags: -I${{includedir}} -", - destination.to_string_lossy().replace('\\', "/") - ), - ) - .unwrap(); - - cmd!(sh, "setx PKG_CONFIG_PATH {deps_path}").run().unwrap(); -} - -pub fn prepare_prebuilt_ffmpeg_windows(deps_path: &Path) { - command::download_and_extract_zip( - &format!( - "https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/{}", - "ffmpeg-n7.1-latest-win64-gpl-shared-7.1.zip" - ), - deps_path, - ) - .unwrap(); - - fs::rename( - deps_path.join("ffmpeg-n7.1-latest-win64-gpl-shared-7.1"), - deps_path.join("ffmpeg"), - ) - .unwrap(); -} - -pub fn prepare_windows_deps(skip_admin_priv: bool) { - let sh = Shell::new().unwrap(); - - let deps_path = afs::deps_dir().join("windows"); - sh.remove_path(&deps_path).ok(); - sh.create_dir(&deps_path).unwrap(); - - if !skip_admin_priv { - choco_install( - &sh, - &["zip", "unzip", "llvm", "vulkan-sdk", "pkgconfiglite"], - ) - .unwrap(); - } - - prepare_prebuilt_x264_windows(&deps_path); - prepare_prebuilt_ffmpeg_windows(&deps_path); -} - -fn linux_deps_path() -> std::path::PathBuf { - afs::deps_dir().join("linux") -} - -fn linux_x264_path() -> std::path::PathBuf { - linux_deps_path().join("x264") -} - -fn linux_ffmpeg_path() -> std::path::PathBuf { - linux_deps_path().join("ffmpeg") -} - -fn linux_nvenc_headers_path() -> std::path::PathBuf { - linux_deps_path().join("nv-codec-headers") -} - -pub fn prepare_linux_deps(enable_nvenc: bool) { - let sh = Shell::new().unwrap(); - - let deps_path = linux_deps_path(); - sh.remove_path(&deps_path).ok(); - sh.create_dir(&deps_path).unwrap(); - - download_linux_x264_src(); - download_linux_ffmpeg_src(); - if enable_nvenc { - download_linux_nvidia_ffmpeg_deps(); - } - - build_linux_x264(); - build_linux_ffmpeg(enable_nvenc); -} - -pub fn download_linux_x264_src() { - let deps_path = linux_deps_path(); - let x264_src_path = linux_x264_path(); - - // x264 0.164 - command::download_and_extract_tar( - "https://code.videolan.org/videolan/x264/-/archive/c196240409e4d7c01b47448d93b1f9683aaa7cf7/x264-c196240409e4d7c01b47448d93b1f9683aaa7cf7.tar.bz2", - &deps_path, - ) - .unwrap(); - - fs::rename( - deps_path.join("x264-c196240409e4d7c01b47448d93b1f9683aaa7cf7"), - &x264_src_path, - ) - .unwrap(); -} - -pub fn build_linux_x264() { - let sh = Shell::new().unwrap(); - - let x264_src_path = linux_x264_path(); - - let flags = ["--enable-static", "--disable-cli", "--enable-pic"]; - - let install_prefix = format!("--prefix={}", x264_src_path.join("alvr_build").display()); - - let _push_guard = sh.push_dir(x264_src_path); - - cmd!(sh, "./configure {install_prefix} {flags...}") - .run() - .unwrap(); - - let nproc = cmd!(sh, "nproc").read().unwrap(); - cmd!(sh, "make -j{nproc}").run().unwrap(); - cmd!(sh, "make install").run().unwrap(); -} - -fn download_linux_ffmpeg_src() { - let deps_path = linux_deps_path(); - let ffmpeg_src_path = linux_ffmpeg_path(); - - command::download_and_extract_zip( - "https://codeload.github.com/FFmpeg/FFmpeg/zip/n6.0", - &deps_path, - ) - .unwrap(); - - fs::rename(deps_path.join("FFmpeg-n6.0"), &ffmpeg_src_path).unwrap(); -} - -pub fn build_linux_ffmpeg(enable_nvenc: bool) { - let ffmpeg_src_path = linux_ffmpeg_path(); - let nvenc_headers_path = linux_nvenc_headers_path(); - - let sh = Shell::new().unwrap(); - - let flags = [ - "--enable-gpl", - "--enable-version3", - "--enable-static", - "--disable-programs", - "--disable-doc", - "--disable-avdevice", - "--disable-avformat", - "--disable-swresample", - "--disable-swscale", - "--disable-postproc", - "--disable-network", - "--disable-everything", - "--enable-encoder=h264_vaapi", - "--enable-encoder=hevc_vaapi", - "--enable-encoder=av1_vaapi", - "--enable-hwaccel=h264_vaapi", - "--enable-hwaccel=hevc_vaapi", - "--enable-hwaccel=av1_vaapi", - "--enable-filter=scale_vaapi", - "--enable-vulkan", - "--enable-libdrm", - "--enable-pic", - "--enable-rpath", - "--fatal-warnings", - ]; - let install_prefix = format!("--prefix={}", ffmpeg_src_path.join("alvr_build").display()); - // The reason for 4x$ in LDSOFLAGS var refer to https://stackoverflow.com/a/71429999 - // all varients of --extra-ldsoflags='-Wl,-rpath,$ORIGIN' do not work! don't waste your time trying! - // - let config_vars = r"-Wl,-rpath,'$$$$ORIGIN'"; - - let _push_guard = sh.push_dir(ffmpeg_src_path); - let _env_vars = sh.push_env("LDSOFLAGS", config_vars); - - // Patches ffmpeg for workarounds and patches that have yet to be unstreamed - let ffmpeg_command = "for p in ../../../alvr/xtask/patches/*; do patch -p1 < $p; done"; - cmd!(sh, "bash -c {ffmpeg_command}").run().unwrap(); - - if enable_nvenc { - /* - Describing Nvidia specific options --nvccflags: - nvcc from CUDA toolkit version 11.0 or higher does not support compiling for 'compute_30' (default in ffmpeg) - 52 is the minimum required for the current CUDA 11 version (Quadro M6000 , GeForce 900, GTX-970, GTX-980, GTX Titan X) - https://arnon.dk/matching-sm-architectures-arch-and-gencode-for-various-nvidia-cards/ - Anyway below 50 arch card don't support nvenc encoding hevc https://developer.nvidia.com/nvidia-video-codec-sdk (Supported devices) - Nvidia docs: - https://docs.nvidia.com/video-technologies/video-codec-sdk/ffmpeg-with-nvidia-gpu/#commonly-faced-issues-and-tips-to-resolve-them - */ - #[cfg(target_os = "linux")] - { - let header_build_dir = nvenc_headers_path.join("build"); - { - let make_header_cmd = - format!("make install PREFIX='{}'", header_build_dir.display()); - let _header_push_guard = sh.push_dir(nvenc_headers_path); - cmd!(sh, "bash -c {make_header_cmd}").run().unwrap(); - } - - let cuda = pkg_config::Config::new().probe("cuda").unwrap(); - let include_flags = cuda - .include_paths - .iter() - .map(|path| format!("-I{}", path.to_string_lossy())) - .reduce(|a, b| format!("{a} {b}")) - .expect("pkg-config cuda entry to have include-paths"); - let link_flags = cuda - .link_paths - .iter() - .map(|path| format!("-L{}", path.to_string_lossy())) - .reduce(|a, b| format!("{a} {b}")) - .expect("pkg-config cuda entry to have link-paths"); - - let nvenc_flags = &[ - "--enable-encoder=h264_nvenc", - "--enable-encoder=hevc_nvenc", - "--enable-encoder=av1_nvenc", - "--enable-nonfree", - "--enable-cuda-nvcc", - "--enable-libnpp", - "--nvccflags=\"-gencode arch=compute_52,code=sm_52 -O2\"", - &format!("--extra-cflags=\"{include_flags}\""), - &format!("--extra-ldflags=\"{link_flags}\""), - ]; - - let env_vars = format!( - "PKG_CONFIG_PATH='{}'", - header_build_dir.join("lib/pkgconfig").display() - ); - let flags_combined = flags.join(" "); - let nvenc_flags_combined = nvenc_flags.join(" "); - - let command = format!( - "{env_vars} ./configure {install_prefix} {flags_combined} {nvenc_flags_combined}" - ); - - cmd!(sh, "bash -c {command}").run().unwrap(); - } - } else { - cmd!(sh, "./configure {install_prefix} {flags...}") - .run() - .unwrap(); - } - - let nproc = cmd!(sh, "nproc").read().unwrap(); - cmd!(sh, "make -j{nproc}").run().unwrap(); - cmd!(sh, "make install").run().unwrap(); -} - -fn download_linux_nvidia_ffmpeg_deps() { - let deps_path = linux_deps_path(); - let nvenc_headers_path = linux_nvenc_headers_path(); - - let codec_header_version = "12.1.14.0"; - let temp_download_dir = deps_path.join("dl_temp"); - command::download_and_extract_zip( - &format!("https://github.com/FFmpeg/nv-codec-headers/archive/refs/tags/n{codec_header_version}.zip"), - &temp_download_dir - ) - .unwrap(); - - fs::rename( - temp_download_dir.join(format!("nv-codec-headers-n{codec_header_version}")), - &nvenc_headers_path, - ) - .unwrap(); - fs::remove_dir_all(temp_download_dir).unwrap(); -} - -pub fn prepare_macos_deps() {} - -pub fn prepare_server_deps(platform: BuildPlatform, skip_admin_priv: bool, enable_nvenc: bool) { - match platform { - BuildPlatform::Windows => prepare_windows_deps(skip_admin_priv), - BuildPlatform::Linux => prepare_linux_deps(enable_nvenc), - BuildPlatform::Macos => prepare_macos_deps(), - BuildPlatform::Android => panic!("Android is not supported"), - } -} - -fn get_android_openxr_loaders(selection: OpenXRLoadersSelection) { - fn get_openxr_loader(name: &str, url: &str, source_dir: &str) { - let sh = Shell::new().unwrap(); - let temp_dir = afs::build_dir().join("temp_download"); - sh.remove_path(&temp_dir).ok(); - sh.create_dir(&temp_dir).unwrap(); - let destination_dir = afs::deps_dir().join("android_openxr/arm64-v8a"); - fs::create_dir_all(&destination_dir).unwrap(); - - command::download_and_extract_zip(url, &temp_dir).unwrap(); - fs::copy( - temp_dir.join(source_dir).join("libopenxr_loader.so"), - destination_dir.join(format!("libopenxr_loader{name}.so")), - ) - .unwrap(); - fs::remove_dir_all(&temp_dir).ok(); - } - - get_openxr_loader( - "", - &format!( - "https://github.com/KhronosGroup/OpenXR-SDK-Source/releases/download/{}", - "release-1.0.34/openxr_loader_for_android-1.0.34.aar", - ), - "prefab/modules/openxr_loader/libs/android.arm64-v8a", - ); - - if matches!(selection, OpenXRLoadersSelection::OnlyGeneric) { - return; - } - - get_openxr_loader( - "_pico_old", - "https://sdk.picovr.com/developer-platform/sdk/PICO_OpenXR_SDK_220.zip", - "libs/android.arm64-v8a", - ); - - if matches!(selection, OpenXRLoadersSelection::OnlyPico) { - return; - } - - get_openxr_loader( - "_quest1", - "https://securecdn.oculus.com/binaries/download/?id=7577210995650755", // Version 64 - "OpenXR/Libs/Android/arm64-v8a/Release", - ); - - get_openxr_loader( - "_yvr", - "https://developer.yvrdream.com/yvrdoc/sdk/openxr/yvr_openxr_mobile_sdk_2.0.0.zip", - "yvr_openxr_mobile_sdk_2.0.0/OpenXR/Libs/Android/arm64-v8a", - ); - - get_openxr_loader( - "_lynx", - "https://portal.lynx-r.com/downloads/download/16", // version 1.0.0 - "jni/arm64-v8a", - ); -} - -pub fn build_android_deps( - skip_admin_priv: bool, - all_targets: bool, - openxr_loaders_selection: OpenXRLoadersSelection, -) { - let sh = Shell::new().unwrap(); - - if cfg!(windows) && !skip_admin_priv { - choco_install(&sh, &["unzip", "llvm"]).unwrap(); - } - - cmd!(sh, "rustup target add aarch64-linux-android") - .run() - .unwrap(); - if all_targets { - cmd!(sh, "rustup target add armv7-linux-androideabi") - .run() - .unwrap(); - cmd!(sh, "rustup target add x86_64-linux-android") - .run() - .unwrap(); - cmd!(sh, "rustup target add i686-linux-android") - .run() - .unwrap(); - } - cmd!(sh, "cargo install cbindgen").run().unwrap(); - cmd!(sh, "cargo install cargo-ndk --version 3.5.4") - .run() - .unwrap(); - cmd!( - sh, - "cargo install --git https://github.com/zarik5/cargo-apk cargo-apk" - ) - .run() - .unwrap(); - - get_android_openxr_loaders(openxr_loaders_selection); -} diff --git a/alvr/xtask/src/dependencies/android.rs b/alvr/xtask/src/dependencies/android.rs new file mode 100644 index 0000000000..b90a209728 --- /dev/null +++ b/alvr/xtask/src/dependencies/android.rs @@ -0,0 +1,106 @@ +use crate::{ + command, + dependencies::{OpenXRLoadersSelection, windows::choco_install}, +}; +use alvr_filesystem as afs; +use std::fs; +use xshell::{Shell, cmd}; + +pub fn build_deps( + skip_admin_priv: bool, + all_targets: bool, + openxr_loaders_selection: OpenXRLoadersSelection, +) { + let sh = Shell::new().unwrap(); + + if cfg!(windows) && !skip_admin_priv { + choco_install(&sh, &["unzip", "llvm"]).unwrap(); + } + + cmd!(sh, "rustup target add aarch64-linux-android") + .run() + .unwrap(); + if all_targets { + cmd!(sh, "rustup target add armv7-linux-androideabi") + .run() + .unwrap(); + cmd!(sh, "rustup target add x86_64-linux-android") + .run() + .unwrap(); + cmd!(sh, "rustup target add i686-linux-android") + .run() + .unwrap(); + } + cmd!(sh, "cargo install cbindgen").run().unwrap(); + cmd!(sh, "cargo install cargo-ndk --version 3.5.4") + .run() + .unwrap(); + cmd!( + sh, + "cargo install --git https://github.com/zarik5/cargo-apk cargo-apk" + ) + .run() + .unwrap(); + + get_android_openxr_loaders(openxr_loaders_selection); +} + +fn get_android_openxr_loaders(selection: OpenXRLoadersSelection) { + fn get_openxr_loader(name: &str, url: &str, source_dir: &str) { + let sh = Shell::new().unwrap(); + let temp_dir = afs::build_dir().join("temp_download"); + sh.remove_path(&temp_dir).ok(); + sh.create_dir(&temp_dir).unwrap(); + let destination_dir = afs::deps_dir().join("android_openxr/arm64-v8a"); + fs::create_dir_all(&destination_dir).unwrap(); + + command::download_and_extract_zip(url, &temp_dir).unwrap(); + fs::copy( + temp_dir.join(source_dir).join("libopenxr_loader.so"), + destination_dir.join(format!("libopenxr_loader{name}.so")), + ) + .unwrap(); + fs::remove_dir_all(&temp_dir).ok(); + } + + get_openxr_loader( + "", + &format!( + "https://github.com/KhronosGroup/OpenXR-SDK-Source/releases/download/{}", + "release-1.0.34/openxr_loader_for_android-1.0.34.aar", + ), + "prefab/modules/openxr_loader/libs/android.arm64-v8a", + ); + + if matches!(selection, OpenXRLoadersSelection::OnlyGeneric) { + return; + } + + get_openxr_loader( + "_pico_old", + "https://sdk.picovr.com/developer-platform/sdk/PICO_OpenXR_SDK_220.zip", + "libs/android.arm64-v8a", + ); + + if matches!(selection, OpenXRLoadersSelection::OnlyPico) { + return; + } + + get_openxr_loader( + "_quest1", + "https://securecdn.oculus.com/binaries/download/?id=7577210995650755", // Version 64 + "OpenXR/Libs/Android/arm64-v8a/Release", + ); + + get_openxr_loader( + "_yvr", + "https://developer.yvrdream.com/yvrdoc/sdk/openxr/yvr_openxr_mobile_sdk_2.0.0.zip", + "yvr_openxr_mobile_sdk_2.0.0/OpenXR/Libs/Android/arm64-v8a", + ); + + get_openxr_loader( + "_lynx", + "https://portal.lynx-r.com/downloads/download/16", // version 1.0.0 + "jni/arm64-v8a", + ); +} diff --git a/alvr/xtask/src/dependencies/linux.rs b/alvr/xtask/src/dependencies/linux.rs new file mode 100644 index 0000000000..98e904bfb8 --- /dev/null +++ b/alvr/xtask/src/dependencies/linux.rs @@ -0,0 +1,249 @@ +use crate::command; +use alvr_filesystem as afs; +use std::fs; +use xshell::{Shell, cmd}; + +pub fn prepare_deps(enable_nvenc: bool) { + let sh = Shell::new().unwrap(); + + let deps_path = deps_path(); + sh.remove_path(&deps_path).ok(); + sh.create_dir(&deps_path).unwrap(); + + download_x264_src(); + download_ffmpeg_src(); + if enable_nvenc { + download_nvidia_ffmpeg_deps(); + } + + build_x264(); + build_ffmpeg(enable_nvenc); +} + +pub fn download_deps(enable_nvenc: bool) { + let sh = Shell::new().unwrap(); + + let deps_path = deps_path(); + sh.remove_path(&deps_path).ok(); + sh.create_dir(&deps_path).unwrap(); + + download_x264_src(); + download_ffmpeg_src(); + if enable_nvenc { + download_nvidia_ffmpeg_deps(); + } +} + +pub fn build_deps(enable_nvenc: bool) { + let deps_path = deps_path(); + assert!(deps_path.exists(), "Please download dependencies first."); + + build_x264(); + build_ffmpeg(enable_nvenc); +} + +fn deps_path() -> std::path::PathBuf { + afs::deps_dir().join("linux") +} + +fn x264_path() -> std::path::PathBuf { + deps_path().join("x264") +} + +fn ffmpeg_path() -> std::path::PathBuf { + deps_path().join("ffmpeg") +} + +fn nvenc_headers_path() -> std::path::PathBuf { + deps_path().join("nv-codec-headers") +} + +fn download_x264_src() { + let deps_path = deps_path(); + // x264 0.164 + command::download_and_extract_tar( + "https://code.videolan.org/videolan/x264/-/archive/c196240409e4d7c01b47448d93b1f9683aaa7cf7/x264-c196240409e4d7c01b47448d93b1f9683aaa7cf7.tar.bz2", + &deps_path, + ) + .unwrap(); + + fs::rename( + deps_path.join("x264-c196240409e4d7c01b47448d93b1f9683aaa7cf7"), + x264_path(), + ) + .unwrap(); +} + +fn download_ffmpeg_src() { + let deps_path = deps_path(); + + command::download_and_extract_zip( + "https://codeload.github.com/FFmpeg/FFmpeg/zip/n6.0", + &deps_path, + ) + .unwrap(); + + fs::rename(deps_path.join("FFmpeg-n6.0"), ffmpeg_path()).unwrap(); +} + +fn download_nvidia_ffmpeg_deps() { + let deps_path = deps_path(); + + let codec_header_version = "12.1.14.0"; + let temp_download_dir = deps_path.join("dl_temp"); + command::download_and_extract_zip( + &format!("https://github.com/FFmpeg/nv-codec-headers/archive/refs/tags/n{codec_header_version}.zip"), + &temp_download_dir + ) + .unwrap(); + + fs::rename( + temp_download_dir.join(format!("nv-codec-headers-n{codec_header_version}")), + nvenc_headers_path(), + ) + .unwrap(); + fs::remove_dir_all(temp_download_dir).unwrap(); +} + +fn build_x264() { + let sh = Shell::new().unwrap(); + + let x264_src_path = x264_path(); + + let flags = ["--enable-static", "--disable-cli", "--enable-pic"]; + + let build_path = x264_src_path.join("alvr_build"); + sh.remove_path(&build_path).ok(); + + let install_prefix = format!("--prefix={}", build_path.display()); + + let _push_guard = sh.push_dir(x264_src_path); + + cmd!(sh, "./configure {install_prefix} {flags...}") + .run() + .unwrap(); + + let nproc = cmd!(sh, "nproc").read().unwrap(); + cmd!(sh, "make -j{nproc}").run().unwrap(); + cmd!(sh, "make install").run().unwrap(); +} + +fn build_ffmpeg(enable_nvenc: bool) { + let ffmpeg_src_path = ffmpeg_path(); + + let sh = Shell::new().unwrap(); + + let flags = [ + "--enable-gpl", + "--enable-version3", + "--enable-static", + "--disable-programs", + "--disable-doc", + "--disable-avdevice", + "--disable-avformat", + "--disable-swresample", + "--disable-swscale", + "--disable-postproc", + "--disable-network", + "--disable-everything", + "--enable-encoder=h264_vaapi", + "--enable-encoder=hevc_vaapi", + "--enable-encoder=av1_vaapi", + "--enable-hwaccel=h264_vaapi", + "--enable-hwaccel=hevc_vaapi", + "--enable-hwaccel=av1_vaapi", + "--enable-filter=scale_vaapi", + "--enable-vulkan", + "--enable-libdrm", + "--enable-pic", + "--enable-rpath", + "--fatal-warnings", + ]; + + let build_path = ffmpeg_src_path.join("alvr_build"); + sh.remove_path(&build_path).ok(); + + let install_prefix = format!("--prefix={}", build_path.display()); + // The reason for 4x$ in LDSOFLAGS var refer to https://stackoverflow.com/a/71429999 + // all varients of --extra-ldsoflags='-Wl,-rpath,$ORIGIN' do not work! don't waste your time trying! + // + let config_vars = r"-Wl,-rpath,'$$$$ORIGIN'"; + + let _push_guard = sh.push_dir(ffmpeg_src_path); + let _env_vars = sh.push_env("LDSOFLAGS", config_vars); + + // Patches ffmpeg for workarounds and patches that have yet to be unstreamed + let ffmpeg_command = "for p in ../../../alvr/xtask/patches/*; do patch -p1 < $p; done"; + cmd!(sh, "bash -c {ffmpeg_command}").run().unwrap(); + + if enable_nvenc { + /* + Describing Nvidia specific options --nvccflags: + nvcc from CUDA toolkit version 11.0 or higher does not support compiling for 'compute_30' (default in ffmpeg) + 52 is the minimum required for the current CUDA 11 version (Quadro M6000 , GeForce 900, GTX-970, GTX-980, GTX Titan X) + https://arnon.dk/matching-sm-architectures-arch-and-gencode-for-various-nvidia-cards/ + Anyway below 50 arch card don't support nvenc encoding hevc https://developer.nvidia.com/nvidia-video-codec-sdk (Supported devices) + Nvidia docs: + https://docs.nvidia.com/video-technologies/video-codec-sdk/ffmpeg-with-nvidia-gpu/#commonly-faced-issues-and-tips-to-resolve-them + */ + #[cfg(target_os = "linux")] + { + let nvenc_headers_path = nvenc_headers_path(); + let header_build_dir = nvenc_headers_path.join("build"); + sh.remove_path(&header_build_dir).ok(); + { + let make_header_cmd = + format!("make install PREFIX='{}'", header_build_dir.display()); + let _header_push_guard = sh.push_dir(nvenc_headers_path); + cmd!(sh, "bash -c {make_header_cmd}").run().unwrap(); + } + + let cuda = pkg_config::Config::new().probe("cuda").unwrap(); + let include_flags = cuda + .include_paths + .iter() + .map(|path| format!("-I{}", path.to_string_lossy())) + .reduce(|a, b| format!("{a} {b}")) + .expect("pkg-config cuda entry to have include-paths"); + let link_flags = cuda + .link_paths + .iter() + .map(|path| format!("-L{}", path.to_string_lossy())) + .reduce(|a, b| format!("{a} {b}")) + .expect("pkg-config cuda entry to have link-paths"); + + let nvenc_flags = &[ + "--enable-encoder=h264_nvenc", + "--enable-encoder=hevc_nvenc", + "--enable-encoder=av1_nvenc", + "--enable-nonfree", + "--enable-cuda-nvcc", + "--enable-libnpp", + "--nvccflags=\"-gencode arch=compute_52,code=sm_52 -O2\"", + &format!("--extra-cflags=\"{include_flags}\""), + &format!("--extra-ldflags=\"{link_flags}\""), + ]; + + let env_vars = format!( + "PKG_CONFIG_PATH='{}'", + header_build_dir.join("lib/pkgconfig").display() + ); + let flags_combined = flags.join(" "); + let nvenc_flags_combined = nvenc_flags.join(" "); + + let command = format!( + "{env_vars} ./configure {install_prefix} {flags_combined} {nvenc_flags_combined}" + ); + + cmd!(sh, "bash -c {command}").run().unwrap(); + } + } else { + cmd!(sh, "./configure {install_prefix} {flags...}") + .run() + .unwrap(); + } + + let nproc = cmd!(sh, "nproc").read().unwrap(); + cmd!(sh, "make -j{nproc}").run().unwrap(); + cmd!(sh, "make install").run().unwrap(); +} diff --git a/alvr/xtask/src/dependencies/mod.rs b/alvr/xtask/src/dependencies/mod.rs new file mode 100644 index 0000000000..6caa71f1e7 --- /dev/null +++ b/alvr/xtask/src/dependencies/mod.rs @@ -0,0 +1,40 @@ +use crate::BuildPlatform; + +pub mod android; +pub mod linux; +pub mod windows; + +pub enum OpenXRLoadersSelection { + OnlyGeneric, + OnlyPico, + All, +} + +pub fn prepare_server_deps(platform: BuildPlatform, skip_admin_priv: bool, enable_nvenc: bool) { + match platform { + BuildPlatform::Windows => windows::prepare_deps(skip_admin_priv), + BuildPlatform::Linux => linux::prepare_deps(enable_nvenc), + BuildPlatform::Macos => prepare_macos_deps(), + BuildPlatform::Android => panic!("Android is not supported"), + } +} + +pub fn download_server_deps(platform: BuildPlatform, skip_admin_priv: bool, enable_nvenc: bool) { + match platform { + BuildPlatform::Windows => windows::prepare_deps(skip_admin_priv), + BuildPlatform::Linux => linux::download_deps(enable_nvenc), + BuildPlatform::Macos => prepare_macos_deps(), + BuildPlatform::Android => panic!("Android is not supported"), + } +} + +pub fn build_server_deps(platform: BuildPlatform, enable_nvenc: bool) { + match platform { + BuildPlatform::Windows => panic!("Building windows dependencies is not supported"), + BuildPlatform::Linux => linux::build_deps(enable_nvenc), + BuildPlatform::Macos => prepare_macos_deps(), + BuildPlatform::Android => panic!("Android is not supported"), + } +} + +pub fn prepare_macos_deps() {} diff --git a/alvr/xtask/src/dependencies/windows.rs b/alvr/xtask/src/dependencies/windows.rs new file mode 100644 index 0000000000..e16b14ad5d --- /dev/null +++ b/alvr/xtask/src/dependencies/windows.rs @@ -0,0 +1,105 @@ +use crate::command; +use alvr_filesystem as afs; +use std::fs; +use xshell::{Shell, cmd}; + +pub fn choco_install(sh: &Shell, packages: &[&str]) -> Result<(), xshell::Error> { + cmd!( + sh, + "powershell Start-Process choco -ArgumentList \"install {packages...} -y\" -Verb runAs -Wait" + ) + .run() +} + +pub fn prepare_deps(skip_admin_priv: bool) { + let sh = Shell::new().unwrap(); + + let deps_path = deps_path(); + sh.remove_path(&deps_path).ok(); + sh.create_dir(&deps_path).unwrap(); + + if !skip_admin_priv { + choco_install( + &sh, + &["zip", "unzip", "llvm", "vulkan-sdk", "pkgconfiglite"], + ) + .unwrap(); + } + + prepare_prebuilt_x264_windows(); + prepare_prebuilt_ffmpeg_windows(); +} + +fn deps_path() -> std::path::PathBuf { + afs::deps_dir().join("windows") +} + +fn x264_path() -> std::path::PathBuf { + deps_path().join("x264") +} + +fn ffmpeg_path() -> std::path::PathBuf { + deps_path().join("ffmpeg") +} + +fn prepare_prebuilt_x264_windows() { + const VERSION: &str = "0.164"; + const REVISION: usize = 3086; + + let sh = Shell::new().unwrap(); + + let x264_src_path = x264_path(); + + command::download_and_extract_zip( + &format!( + "{}/{VERSION}.r{REVISION}/libx264_{VERSION}.r{REVISION}_msvc16.zip", + "https://github.com/ShiftMediaProject/x264/releases/download", + ), + &x264_src_path, + ) + .unwrap(); + + fs::write( + afs::deps_dir().join("x264.pc"), + format!( + r" +prefix={} +exec_prefix=${{prefix}}/bin/x64 +libdir=${{prefix}}/lib/x64 +includedir=${{prefix}}/include + +Name: x264 +Description: x264 library +Version: {VERSION} +Libs: -L${{libdir}} -lx264 +Cflags: -I${{includedir}} +", + x264_src_path.to_string_lossy().replace('\\', "/") + ), + ) + .unwrap(); + + cmd!(sh, "setx PKG_CONFIG_PATH {x264_src_path}") + .run() + .unwrap(); +} + +fn prepare_prebuilt_ffmpeg_windows() { + let deps_path = deps_path(); + let ffmpeg_path = ffmpeg_path(); + + command::download_and_extract_zip( + &format!( + "https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/{}", + "ffmpeg-n7.1-latest-win64-gpl-shared-7.1.zip" + ), + &deps_path, + ) + .unwrap(); + + fs::rename( + deps_path.join("ffmpeg-n7.1-latest-win64-gpl-shared-7.1"), + ffmpeg_path, + ) + .unwrap(); +} diff --git a/alvr/xtask/src/main.rs b/alvr/xtask/src/main.rs index 901b024ea1..cbee055d55 100644 --- a/alvr/xtask/src/main.rs +++ b/alvr/xtask/src/main.rs @@ -210,7 +210,7 @@ fn main() { match subcommand.as_str() { "prepare-deps" => { if matches!(platform, BuildPlatform::Android) { - dependencies::build_android_deps( + dependencies::android::build_deps( for_ci, all_targets, OpenXRLoadersSelection::All, @@ -219,8 +219,10 @@ fn main() { dependencies::prepare_server_deps(platform, for_ci, !no_nvidia); } } - "download-server-deps" => todo!(), - "build-server-deps" => todo!(), + "download-server-deps" => { + dependencies::download_server_deps(platform, for_ci, !no_nvidia) + } + "build-server-deps" => dependencies::build_server_deps(platform, !no_nvidia), "build-streamer" => { build::build_streamer(profile, gpl, None, reproducible, profiling, keep_config) } diff --git a/alvr/xtask/src/packaging.rs b/alvr/xtask/src/packaging.rs index 63497352df..492c82f131 100644 --- a/alvr/xtask/src/packaging.rs +++ b/alvr/xtask/src/packaging.rs @@ -108,7 +108,7 @@ pub fn package_client_openxr(flavor: ReleaseFlavor, skip_admin_priv: bool) { ReleaseFlavor::PicoStore => OpenXRLoadersSelection::OnlyPico, }; - dependencies::build_android_deps(skip_admin_priv, false, openxr_selection); + dependencies::android::build_deps(skip_admin_priv, false, openxr_selection); if !matches!(flavor, ReleaseFlavor::GitHub) { replace_client_openxr_manifest( From f0411916311e954076971dfca4e17ff2a8e66d1e Mon Sep 17 00:00:00 2001 From: Meister1593 Date: Wed, 6 Aug 2025 00:53:49 +0200 Subject: [PATCH 06/14] return option for platform, with some adjustments --- alvr/xtask/src/dependencies/mod.rs | 58 ++++++++++++++++++++---------- alvr/xtask/src/main.rs | 31 +++++++++------- alvr/xtask/src/packaging.rs | 2 +- 3 files changed, 58 insertions(+), 33 deletions(-) diff --git a/alvr/xtask/src/dependencies/mod.rs b/alvr/xtask/src/dependencies/mod.rs index 6caa71f1e7..08b4f5e623 100644 --- a/alvr/xtask/src/dependencies/mod.rs +++ b/alvr/xtask/src/dependencies/mod.rs @@ -1,4 +1,4 @@ -use crate::BuildPlatform; +use crate::{BuildPlatform, print_help_and_exit}; pub mod android; pub mod linux; @@ -10,30 +10,50 @@ pub enum OpenXRLoadersSelection { All, } -pub fn prepare_server_deps(platform: BuildPlatform, skip_admin_priv: bool, enable_nvenc: bool) { - match platform { - BuildPlatform::Windows => windows::prepare_deps(skip_admin_priv), - BuildPlatform::Linux => linux::prepare_deps(enable_nvenc), - BuildPlatform::Macos => prepare_macos_deps(), - BuildPlatform::Android => panic!("Android is not supported"), +pub fn prepare_server_deps( + platform: Option, + skip_admin_priv: bool, + enable_nvenc: bool, +) { + if let Some(platform) = platform { + match platform { + BuildPlatform::Windows => windows::prepare_deps(skip_admin_priv), + BuildPlatform::Linux => linux::prepare_deps(enable_nvenc), + BuildPlatform::Macos => prepare_macos_deps(), + BuildPlatform::Android => panic!("Android is not supported"), + } + } else { + print_help_and_exit("Please specify platform"); } } -pub fn download_server_deps(platform: BuildPlatform, skip_admin_priv: bool, enable_nvenc: bool) { - match platform { - BuildPlatform::Windows => windows::prepare_deps(skip_admin_priv), - BuildPlatform::Linux => linux::download_deps(enable_nvenc), - BuildPlatform::Macos => prepare_macos_deps(), - BuildPlatform::Android => panic!("Android is not supported"), +pub fn download_server_deps( + platform: Option, + skip_admin_priv: bool, + enable_nvenc: bool, +) { + if let Some(platform) = platform { + match platform { + BuildPlatform::Windows => windows::prepare_deps(skip_admin_priv), + BuildPlatform::Linux => linux::download_deps(enable_nvenc), + BuildPlatform::Macos => prepare_macos_deps(), + BuildPlatform::Android => panic!("Android is not supported"), + } + } else { + print_help_and_exit("Please specify platform"); } } -pub fn build_server_deps(platform: BuildPlatform, enable_nvenc: bool) { - match platform { - BuildPlatform::Windows => panic!("Building windows dependencies is not supported"), - BuildPlatform::Linux => linux::build_deps(enable_nvenc), - BuildPlatform::Macos => prepare_macos_deps(), - BuildPlatform::Android => panic!("Android is not supported"), +pub fn build_server_deps(platform: Option, enable_nvenc: bool) { + if let Some(platform) = platform { + match platform { + BuildPlatform::Windows => panic!("Building windows dependencies is not supported"), + BuildPlatform::Linux => linux::build_deps(enable_nvenc), + BuildPlatform::Macos => prepare_macos_deps(), + BuildPlatform::Android => panic!("Android is not supported"), + } + } else { + print_help_and_exit("Please specify platform"); } } diff --git a/alvr/xtask/src/main.rs b/alvr/xtask/src/main.rs index cbee055d55..3a3563bf27 100644 --- a/alvr/xtask/src/main.rs +++ b/alvr/xtask/src/main.rs @@ -9,6 +9,7 @@ mod version; use crate::build::Profile; use afs::Layout; use alvr_filesystem as afs; +use core::panic; use dependencies::OpenXRLoadersSelection; use packaging::ReleaseFlavor; use pico_args::Arguments; @@ -187,13 +188,13 @@ fn main() { let reproducible: bool = args.contains("--reproducible"); let platform: Option = args.opt_value_from_str("--platform").unwrap(); - let platform = match platform.as_deref() { - Some("windows") => BuildPlatform::Windows, - Some("linux") => BuildPlatform::Linux, - Some("macos") => BuildPlatform::Macos, - Some("android") => BuildPlatform::Android, + let platform = platform.as_deref().map(|platform| match platform { + "windows" => BuildPlatform::Windows, + "linux" => BuildPlatform::Linux, + "macos" => BuildPlatform::Macos, + "android" => BuildPlatform::Android, _ => print_help_and_exit("Unrecognized platform"), - }; + }); let version: Option = args.opt_value_from_str("--version").unwrap(); let root: Option = args.opt_value_from_str("--root").unwrap(); @@ -209,14 +210,18 @@ fn main() { if args.finish().is_empty() { match subcommand.as_str() { "prepare-deps" => { - if matches!(platform, BuildPlatform::Android) { - dependencies::android::build_deps( - for_ci, - all_targets, - OpenXRLoadersSelection::All, - ); + if let Some(platform) = platform { + if matches!(platform, BuildPlatform::Android) { + dependencies::android::build_deps( + for_ci, + all_targets, + OpenXRLoadersSelection::All, + ); + } else { + dependencies::prepare_server_deps(Some(platform), for_ci, !no_nvidia); + } } else { - dependencies::prepare_server_deps(platform, for_ci, !no_nvidia); + panic!("No selected ") } } "download-server-deps" => { diff --git a/alvr/xtask/src/packaging.rs b/alvr/xtask/src/packaging.rs index 492c82f131..bc6b694cc9 100644 --- a/alvr/xtask/src/packaging.rs +++ b/alvr/xtask/src/packaging.rs @@ -51,7 +51,7 @@ pub fn include_licenses(root_path: &Path, gpl: bool) { } pub fn package_streamer( - platform: BuildPlatform, + platform: Option, skip_admin_priv: bool, enable_nvenc: bool, gpl: bool, From f7ad9f70a21226c1d7aa3b31ac6a1ecc567f7241 Mon Sep 17 00:00:00 2001 From: Meister1593 Date: Wed, 6 Aug 2025 10:25:20 +0200 Subject: [PATCH 07/14] adjusted docs for new commands, returned platform omiting back --- alvr/xtask/src/dependencies/mod.rs | 69 ++++++++++++++++--------- alvr/xtask/src/main.rs | 82 ++++++++++++++++-------------- wiki/Building-From-Source.md | 6 +-- 3 files changed, 93 insertions(+), 64 deletions(-) diff --git a/alvr/xtask/src/dependencies/mod.rs b/alvr/xtask/src/dependencies/mod.rs index 08b4f5e623..ea92c518ea 100644 --- a/alvr/xtask/src/dependencies/mod.rs +++ b/alvr/xtask/src/dependencies/mod.rs @@ -15,15 +15,22 @@ pub fn prepare_server_deps( skip_admin_priv: bool, enable_nvenc: bool, ) { - if let Some(platform) = platform { - match platform { - BuildPlatform::Windows => windows::prepare_deps(skip_admin_priv), - BuildPlatform::Linux => linux::prepare_deps(enable_nvenc), - BuildPlatform::Macos => prepare_macos_deps(), - BuildPlatform::Android => panic!("Android is not supported"), + match platform { + Some(BuildPlatform::Windows) => windows::prepare_deps(skip_admin_priv), + Some(BuildPlatform::Linux) => linux::prepare_deps(enable_nvenc), + Some(BuildPlatform::Macos) => prepare_macos_deps(), + Some(BuildPlatform::Android) => panic!("Android is not supported"), + None => { + if cfg!(windows) { + windows::prepare_deps(skip_admin_priv); + } else if cfg!(target_os = "linux") { + linux::prepare_deps(enable_nvenc); + } else if cfg!(target_os = "macos") { + prepare_macos_deps(); + } else { + panic!("Unsupported platform"); + } } - } else { - print_help_and_exit("Please specify platform"); } } @@ -32,28 +39,42 @@ pub fn download_server_deps( skip_admin_priv: bool, enable_nvenc: bool, ) { - if let Some(platform) = platform { - match platform { - BuildPlatform::Windows => windows::prepare_deps(skip_admin_priv), - BuildPlatform::Linux => linux::download_deps(enable_nvenc), - BuildPlatform::Macos => prepare_macos_deps(), - BuildPlatform::Android => panic!("Android is not supported"), + match platform { + Some(BuildPlatform::Windows) => windows::prepare_deps(skip_admin_priv), + Some(BuildPlatform::Linux) => linux::download_deps(enable_nvenc), + Some(BuildPlatform::Macos) => prepare_macos_deps(), + Some(BuildPlatform::Android) => panic!("Android is not supported"), + None => { + if cfg!(windows) { + windows::prepare_deps(skip_admin_priv); + } else if cfg!(target_os = "linux") { + linux::download_deps(enable_nvenc); + } else if cfg!(target_os = "macos") { + prepare_macos_deps(); + } else { + panic!("Unsupported platform"); + } } - } else { - print_help_and_exit("Please specify platform"); } } pub fn build_server_deps(platform: Option, enable_nvenc: bool) { - if let Some(platform) = platform { - match platform { - BuildPlatform::Windows => panic!("Building windows dependencies is not supported"), - BuildPlatform::Linux => linux::build_deps(enable_nvenc), - BuildPlatform::Macos => prepare_macos_deps(), - BuildPlatform::Android => panic!("Android is not supported"), + match platform { + Some(BuildPlatform::Windows) => panic!("Building windows dependencies is unsupported"), + Some(BuildPlatform::Linux) => linux::build_deps(enable_nvenc), + Some(BuildPlatform::Macos) => prepare_macos_deps(), + Some(BuildPlatform::Android) => panic!("Android is not supported"), + None => { + if cfg!(windows) { + panic!("Building windows dependencies is unsupported"); + } else if cfg!(target_os = "linux") { + linux::build_deps(enable_nvenc); + } else if cfg!(target_os = "macos") { + prepare_macos_deps(); + } else { + panic!("Unsupported platform"); + } } - } else { - print_help_and_exit("Please specify platform"); } } diff --git a/alvr/xtask/src/main.rs b/alvr/xtask/src/main.rs index 3a3563bf27..cc137dec8a 100644 --- a/alvr/xtask/src/main.rs +++ b/alvr/xtask/src/main.rs @@ -24,46 +24,48 @@ USAGE: cargo xtask [FLAG] [ARGS] SUBCOMMANDS: - prepare-deps Download and compile streamer and client external dependencies - build-streamer Build streamer, then copy binaries to build folder - build-launcher Build launcher, then copy binaries to build folder - build-server-lib Build a C-ABI ALVR server library and header - build-client Build client, then copy binaries to build folder - build-client-lib Build a C-ABI ALVR client library and header - build-client-xr-lib Build a C-ABI ALVR OpenXR entry point client library and header - run-streamer Build streamer and then open the dashboard - run-launcher Build launcher and then open it - format Autoformat all code - check-format Check if code is correctly formatted - package-streamer Build streamer with distribution profile, make archive - package-launcher Build launcher with distribution profile, make archive - package-client Build client with distribution profile - package-client-lib Build client library then zip it - clean Removes all build artifacts and dependencies - bump Bump streamer and client package versions - clippy Show warnings for selected clippy lints - kill-oculus Kill all Oculus processes + prepare-deps Download and compile streamer and client external dependencies + download-server-deps Download streamer external dependencies + build-server-deps Compile streamer external dependencies + build-streamer Build streamer, then copy binaries to build folder + build-launcher Build launcher, then copy binaries to build folder + build-server-lib Build a C-ABI ALVR server library and header + build-client Build client, then copy binaries to build folder + build-client-lib Build a C-ABI ALVR client library and header + build-client-xr-lib Build a C-ABI ALVR OpenXR entry point client library and header + run-streamer Build streamer and then open the dashboard + run-launcher Build launcher and then open it + format Autoformat all code + check-format Check if code is correctly formatted + package-streamer Build streamer with distribution profile, make archive + package-launcher Build launcher with distribution profile, make archive + package-client Build client with distribution profile + package-client-lib Build client library then zip it + clean Removes all build artifacts and dependencies + bump Bump streamer and client package versions + clippy Show warnings for selected clippy lints + kill-oculus Kill all Oculus processes FLAGS: - --help Print this text - --keep-config Preserve the configuration file between rebuilds (session.json) - --no-nvidia Disables nVidia support on Linux. For prepare-deps subcommand - --release Optimized build with less debug checks. For build subcommands - --profiling Enable Profiling - --gpl Bundle GPL libraries (FFmpeg). Only for Windows - --nightly Append nightly tag to versions. For bump subcommand - --no-rebuild Do not rebuild the streamer with run-streamer - --ci Do some CI related tweaks. Depends on the other flags and subcommand - --no-stdcpp Disable linking to libc++_shared with build-client-lib - --all-targets For prepare-deps and build-client-lib subcommand, will build for all android supported ABI targets - --meta-store For package-client subcommand, build for Meta Store - --pico-store For package-client subcommand, build for Pico Store + --help Print this text + --keep-config Preserve the configuration file between rebuilds (session.json) + --no-nvidia Disables nVidia support on Linux. For prepare-deps subcommand + --release Optimized build with less debug checks. For build subcommands + --profiling Enable Profiling + --gpl Bundle GPL libraries (FFmpeg, x264) + --nightly Append nightly tag to versions. For bump subcommand + --no-rebuild Do not rebuild the streamer with run-streamer + --ci Do some CI related tweaks. Depends on the other flags and subcommand + --no-stdcpp Disable linking to libc++_shared with build-client-lib + --all-targets For prepare-deps and build-client-lib subcommand, will build for all android supported ABI targets + --meta-store For package-client subcommand, build for Meta Store + --pico-store For package-client subcommand, build for Pico Store ARGS: - --platform Can be one of: windows, linux, macos, android. Can be omitted - --version Specify version to set with the bump-versions subcommand - --root Installation root. By default no root is set and paths are calculated using - relative paths, which requires conforming to FHS on Linux + --platform Can be one of: windows, linux, macos, android. Can be omitted + --version Specify version to set with the bump-versions subcommand + --root Installation root. By default no root is set and paths are calculated using + relative paths, which requires conforming to FHS on Linux "; enum BuildPlatform { @@ -221,7 +223,13 @@ fn main() { dependencies::prepare_server_deps(Some(platform), for_ci, !no_nvidia); } } else { - panic!("No selected ") + dependencies::prepare_server_deps(platform, for_ci, !no_nvidia); + + dependencies::android::build_deps( + for_ci, + all_targets, + OpenXRLoadersSelection::All, + ); } } "download-server-deps" => { diff --git a/wiki/Building-From-Source.md b/wiki/Building-From-Source.md index 6ade045b35..b4fa755c7b 100644 --- a/wiki/Building-From-Source.md +++ b/wiki/Building-From-Source.md @@ -58,8 +58,8 @@ cargo xtask prepare-deps --platform [your platform] [--gpl] [--no-nvidia] ``` * Replace `[your platform]` with your computer OS, either `windows` or `linux` -* **Windows only:** Use the `--gpl` flag if you want to download, build and bundle FFmpeg inside the ALVR streamer. Keep in mind that this is only needed for software encoding. As the name suggests, if you use this flag you can only redistribute the final package as GPLv2.0 licensed; because of the x264 encoder. -* **Linux only:** Use the `--no-nvidia` flag if you have a AMD gpu. +* Use the `--gpl` flag if you want to download, build and bundle FFmpeg, x264 inside the ALVR streamer. As the name suggests, if you use this flag you can only redistribute the final package as GPLv2.0 licensed. +* **Linux only:** Use the `--no-nvidia` flag if you have a AMD or Intel gpu. Next up is the proper build of the streamer. Run the following: @@ -67,7 +67,7 @@ Next up is the proper build of the streamer. Run the following: cargo xtask build-streamer --release [--gpl] ``` -**Windows only:** Again, the `--gpl` flag is needed only if you want to bundle FFmpeg. +Again, the `--gpl` flag is needed only if you want to bundle FFmpeg and x264. You can find the resulting package in `build/alvr_streamer_[your platform]` From efc9036fab5523fe55d45601cd12e3c754c93fcd Mon Sep 17 00:00:00 2001 From: Meister1593 Date: Wed, 6 Aug 2025 10:45:42 +0200 Subject: [PATCH 08/14] remove unused uses --- alvr/xtask/src/dependencies/mod.rs | 2 +- alvr/xtask/src/main.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/alvr/xtask/src/dependencies/mod.rs b/alvr/xtask/src/dependencies/mod.rs index ea92c518ea..b2137eecd1 100644 --- a/alvr/xtask/src/dependencies/mod.rs +++ b/alvr/xtask/src/dependencies/mod.rs @@ -1,4 +1,4 @@ -use crate::{BuildPlatform, print_help_and_exit}; +use crate::BuildPlatform; pub mod android; pub mod linux; diff --git a/alvr/xtask/src/main.rs b/alvr/xtask/src/main.rs index cc137dec8a..89249ce043 100644 --- a/alvr/xtask/src/main.rs +++ b/alvr/xtask/src/main.rs @@ -9,7 +9,6 @@ mod version; use crate::build::Profile; use afs::Layout; use alvr_filesystem as afs; -use core::panic; use dependencies::OpenXRLoadersSelection; use packaging::ReleaseFlavor; use pico_args::Arguments; From b66c1eeace5b4c7d5c99eee78d51f1269e8daa28 Mon Sep 17 00:00:00 2001 From: Meister1593 Date: Sat, 9 Aug 2025 10:06:07 +0200 Subject: [PATCH 09/14] change reproducible to two separate flags (frozen + offline) as fully reproducible builds are not possible yet --- alvr/xtask/src/build.rs | 19 +++++++++++++------ alvr/xtask/src/main.rs | 27 +++++++++++++++++++-------- alvr/xtask/src/packaging.rs | 4 ++-- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/alvr/xtask/src/build.rs b/alvr/xtask/src/build.rs index 814d17538c..398d85bbbc 100644 --- a/alvr/xtask/src/build.rs +++ b/alvr/xtask/src/build.rs @@ -27,7 +27,7 @@ impl Display for Profile { } } -pub fn build_server_lib(profile: Profile, root: Option, reproducible: bool) { +pub fn build_server_lib(profile: Profile, root: Option, frozen: bool, offline: bool) { let sh = Shell::new().unwrap(); let mut flags = vec![]; @@ -39,8 +39,10 @@ pub fn build_server_lib(profile: Profile, root: Option, reproducible: bo Profile::Release => flags.push("--release"), Profile::Debug => (), } - if reproducible { + if frozen { flags.push("--frozen"); + } + if offline { flags.push("--offline"); } let flags_ref = &flags; @@ -76,7 +78,8 @@ pub fn build_streamer( profile: Profile, gpl: bool, root: Option, - reproducible: bool, + frozen: bool, + offline: bool, profiling: bool, keep_config: bool, ) { @@ -93,8 +96,10 @@ pub fn build_streamer( Profile::Release => common_flags.push("--release"), Profile::Debug => (), } - if reproducible { + if frozen { common_flags.push("--frozen"); + } + if offline { common_flags.push("--offline"); } @@ -275,7 +280,7 @@ pub fn build_streamer( } } -pub fn build_launcher(profile: Profile, reproducible: bool) { +pub fn build_launcher(profile: Profile, frozen: bool, offline: bool) { let sh = Shell::new().unwrap(); let mut common_flags = vec![]; @@ -287,8 +292,10 @@ pub fn build_launcher(profile: Profile, reproducible: bool) { Profile::Release => common_flags.push("--release"), Profile::Debug => (), } - if reproducible { + if frozen { common_flags.push("--frozen"); + } + if offline { common_flags.push("--offline"); } let common_flags_ref = &common_flags; diff --git a/alvr/xtask/src/main.rs b/alvr/xtask/src/main.rs index 89249ce043..d6dd446332 100644 --- a/alvr/xtask/src/main.rs +++ b/alvr/xtask/src/main.rs @@ -59,6 +59,9 @@ FLAGS: --all-targets For prepare-deps and build-client-lib subcommand, will build for all android supported ABI targets --meta-store For package-client subcommand, build for Meta Store --pico-store For package-client subcommand, build for Pico Store + --frozen Forces build subcommands to use locally cached dependencies. Useful for CI or reproducible builds. + --offline Forces build subcommands to fail if they try to use internet. + Note that xtask and cargo about are built and downloaded at build time. Useful for CI or reproducible builds. ARGS: --platform Can be one of: windows, linux, macos, android. Can be omitted @@ -186,7 +189,8 @@ fn main() { let keep_config = args.contains("--keep-config"); let link_stdcpp = !args.contains("--no-stdcpp"); let all_targets = args.contains("--all-targets"); - let reproducible: bool = args.contains("--reproducible"); + let frozen = args.contains("--frozen"); + let offline = args.contains("--offline"); let platform: Option = args.opt_value_from_str("--platform").unwrap(); let platform = platform.as_deref().map(|platform| match platform { @@ -235,11 +239,17 @@ fn main() { dependencies::download_server_deps(platform, for_ci, !no_nvidia) } "build-server-deps" => dependencies::build_server_deps(platform, !no_nvidia), - "build-streamer" => { - build::build_streamer(profile, gpl, None, reproducible, profiling, keep_config) - } - "build-launcher" => build::build_launcher(profile, reproducible), - "build-server-lib" => build::build_server_lib(profile, None, reproducible), + "build-streamer" => build::build_streamer( + profile, + gpl, + None, + frozen, + offline, + profiling, + keep_config, + ), + "build-launcher" => build::build_launcher(profile, frozen, offline), + "build-server-lib" => build::build_server_lib(profile, None, frozen, offline), "build-client" => build::build_android_client(profile), "build-client-lib" => { build::build_android_client_core_lib(profile, link_stdcpp, all_targets) @@ -253,7 +263,8 @@ fn main() { profile, gpl, None, - reproducible, + frozen, + offline, profiling, keep_config, ); @@ -262,7 +273,7 @@ fn main() { } "run-launcher" => { if !no_rebuild { - build::build_launcher(profile, reproducible); + build::build_launcher(profile, frozen, offline); } run_launcher(); } diff --git a/alvr/xtask/src/packaging.rs b/alvr/xtask/src/packaging.rs index bc6b694cc9..63b0c797de 100644 --- a/alvr/xtask/src/packaging.rs +++ b/alvr/xtask/src/packaging.rs @@ -61,7 +61,7 @@ pub fn package_streamer( dependencies::prepare_server_deps(platform, skip_admin_priv, enable_nvenc); - build::build_streamer(Profile::Distribution, gpl, root, true, false, false); + build::build_streamer(Profile::Distribution, gpl, root, true, false, false, false); include_licenses(&afs::streamer_build_dir(), gpl); @@ -77,7 +77,7 @@ pub fn package_launcher() { sh.remove_path(afs::launcher_build_dir()).ok(); - build::build_launcher(Profile::Distribution, true); + build::build_launcher(Profile::Distribution, true, false); include_licenses(&afs::launcher_build_dir(), false); From fb31f372122c35f683b5b8f69a19089e7a02f045 Mon Sep 17 00:00:00 2001 From: Meister1593 Date: Sat, 9 Aug 2025 10:28:37 +0200 Subject: [PATCH 10/14] change frozen to locked (frozen is unsuitable for online usage) --- alvr/xtask/src/build.rs | 18 +++++++++--------- alvr/xtask/src/main.rs | 12 ++++++------ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/alvr/xtask/src/build.rs b/alvr/xtask/src/build.rs index 398d85bbbc..2b46f5a251 100644 --- a/alvr/xtask/src/build.rs +++ b/alvr/xtask/src/build.rs @@ -27,7 +27,7 @@ impl Display for Profile { } } -pub fn build_server_lib(profile: Profile, root: Option, frozen: bool, offline: bool) { +pub fn build_server_lib(profile: Profile, root: Option, locked: bool, offline: bool) { let sh = Shell::new().unwrap(); let mut flags = vec![]; @@ -39,8 +39,8 @@ pub fn build_server_lib(profile: Profile, root: Option, frozen: bool, of Profile::Release => flags.push("--release"), Profile::Debug => (), } - if frozen { - flags.push("--frozen"); + if locked { + flags.push("--locked"); } if offline { flags.push("--offline"); @@ -78,7 +78,7 @@ pub fn build_streamer( profile: Profile, gpl: bool, root: Option, - frozen: bool, + locked: bool, offline: bool, profiling: bool, keep_config: bool, @@ -96,8 +96,8 @@ pub fn build_streamer( Profile::Release => common_flags.push("--release"), Profile::Debug => (), } - if frozen { - common_flags.push("--frozen"); + if locked { + common_flags.push("--locked"); } if offline { common_flags.push("--offline"); @@ -280,7 +280,7 @@ pub fn build_streamer( } } -pub fn build_launcher(profile: Profile, frozen: bool, offline: bool) { +pub fn build_launcher(profile: Profile, locked: bool, offline: bool) { let sh = Shell::new().unwrap(); let mut common_flags = vec![]; @@ -292,8 +292,8 @@ pub fn build_launcher(profile: Profile, frozen: bool, offline: bool) { Profile::Release => common_flags.push("--release"), Profile::Debug => (), } - if frozen { - common_flags.push("--frozen"); + if locked { + common_flags.push("--locked"); } if offline { common_flags.push("--offline"); diff --git a/alvr/xtask/src/main.rs b/alvr/xtask/src/main.rs index d6dd446332..ff5327f0cb 100644 --- a/alvr/xtask/src/main.rs +++ b/alvr/xtask/src/main.rs @@ -189,7 +189,7 @@ fn main() { let keep_config = args.contains("--keep-config"); let link_stdcpp = !args.contains("--no-stdcpp"); let all_targets = args.contains("--all-targets"); - let frozen = args.contains("--frozen"); + let locked = args.contains("--locked"); let offline = args.contains("--offline"); let platform: Option = args.opt_value_from_str("--platform").unwrap(); @@ -243,13 +243,13 @@ fn main() { profile, gpl, None, - frozen, + locked, offline, profiling, keep_config, ), - "build-launcher" => build::build_launcher(profile, frozen, offline), - "build-server-lib" => build::build_server_lib(profile, None, frozen, offline), + "build-launcher" => build::build_launcher(profile, locked, offline), + "build-server-lib" => build::build_server_lib(profile, None, locked, offline), "build-client" => build::build_android_client(profile), "build-client-lib" => { build::build_android_client_core_lib(profile, link_stdcpp, all_targets) @@ -263,7 +263,7 @@ fn main() { profile, gpl, None, - frozen, + locked, offline, profiling, keep_config, @@ -273,7 +273,7 @@ fn main() { } "run-launcher" => { if !no_rebuild { - build::build_launcher(profile, frozen, offline); + build::build_launcher(profile, locked, offline); } run_launcher(); } From 84e82a82d78f1f1ba65baa76eaf6c82e4f5bf767 Mon Sep 17 00:00:00 2001 From: Meister1593 Date: Sat, 9 Aug 2025 10:32:50 +0200 Subject: [PATCH 11/14] update help string --- alvr/xtask/src/main.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/alvr/xtask/src/main.rs b/alvr/xtask/src/main.rs index ff5327f0cb..57edddb579 100644 --- a/alvr/xtask/src/main.rs +++ b/alvr/xtask/src/main.rs @@ -59,9 +59,11 @@ FLAGS: --all-targets For prepare-deps and build-client-lib subcommand, will build for all android supported ABI targets --meta-store For package-client subcommand, build for Meta Store --pico-store For package-client subcommand, build for Pico Store - --frozen Forces build subcommands to use locally cached dependencies. Useful for CI or reproducible builds. + --locked Forces build subcommands to use only dependencies specified from Cargo.lock + --frozen Forces build subcommands to use locally cached dependencies specified in Cargo.lock + and fail if internet access was required during build --offline Forces build subcommands to fail if they try to use internet. - Note that xtask and cargo about are built and downloaded at build time. Useful for CI or reproducible builds. + Note that 'xtask' and 'cargo about' dependencies are downloaded and built during build of alvr ARGS: --platform Can be one of: windows, linux, macos, android. Can be omitted From c283a863ff74ee55f597ef20bc10f5311de1423c Mon Sep 17 00:00:00 2001 From: Meister1593 Date: Sat, 9 Aug 2025 10:36:40 +0200 Subject: [PATCH 12/14] add frozen flag back, separately --- alvr/xtask/src/build.rs | 9 ++++++++- alvr/xtask/src/main.rs | 7 +++++-- alvr/xtask/src/packaging.rs | 13 +++++++++++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/alvr/xtask/src/build.rs b/alvr/xtask/src/build.rs index 2b46f5a251..0b0f7bf13b 100644 --- a/alvr/xtask/src/build.rs +++ b/alvr/xtask/src/build.rs @@ -79,6 +79,7 @@ pub fn build_streamer( gpl: bool, root: Option, locked: bool, + frozen: bool, offline: bool, profiling: bool, keep_config: bool, @@ -99,6 +100,9 @@ pub fn build_streamer( if locked { common_flags.push("--locked"); } + if frozen { + common_flags.push("--frozen"); + } if offline { common_flags.push("--offline"); } @@ -280,7 +284,7 @@ pub fn build_streamer( } } -pub fn build_launcher(profile: Profile, locked: bool, offline: bool) { +pub fn build_launcher(profile: Profile, locked: bool, frozen: bool, offline: bool) { let sh = Shell::new().unwrap(); let mut common_flags = vec![]; @@ -295,6 +299,9 @@ pub fn build_launcher(profile: Profile, locked: bool, offline: bool) { if locked { common_flags.push("--locked"); } + if frozen { + common_flags.push("--frozen"); + } if offline { common_flags.push("--offline"); } diff --git a/alvr/xtask/src/main.rs b/alvr/xtask/src/main.rs index 57edddb579..a289eb33de 100644 --- a/alvr/xtask/src/main.rs +++ b/alvr/xtask/src/main.rs @@ -192,6 +192,7 @@ fn main() { let link_stdcpp = !args.contains("--no-stdcpp"); let all_targets = args.contains("--all-targets"); let locked = args.contains("--locked"); + let frozen = args.contains("--frozen"); let offline = args.contains("--offline"); let platform: Option = args.opt_value_from_str("--platform").unwrap(); @@ -246,11 +247,12 @@ fn main() { gpl, None, locked, + frozen, offline, profiling, keep_config, ), - "build-launcher" => build::build_launcher(profile, locked, offline), + "build-launcher" => build::build_launcher(profile, locked, frozen, offline), "build-server-lib" => build::build_server_lib(profile, None, locked, offline), "build-client" => build::build_android_client(profile), "build-client-lib" => { @@ -266,6 +268,7 @@ fn main() { gpl, None, locked, + frozen, offline, profiling, keep_config, @@ -275,7 +278,7 @@ fn main() { } "run-launcher" => { if !no_rebuild { - build::build_launcher(profile, locked, offline); + build::build_launcher(profile, locked, frozen, offline); } run_launcher(); } diff --git a/alvr/xtask/src/packaging.rs b/alvr/xtask/src/packaging.rs index 63b0c797de..6780fb1d60 100644 --- a/alvr/xtask/src/packaging.rs +++ b/alvr/xtask/src/packaging.rs @@ -61,7 +61,16 @@ pub fn package_streamer( dependencies::prepare_server_deps(platform, skip_admin_priv, enable_nvenc); - build::build_streamer(Profile::Distribution, gpl, root, true, false, false, false); + build::build_streamer( + Profile::Distribution, + gpl, + root, + true, + false, + false, + false, + false, + ); include_licenses(&afs::streamer_build_dir(), gpl); @@ -77,7 +86,7 @@ pub fn package_launcher() { sh.remove_path(afs::launcher_build_dir()).ok(); - build::build_launcher(Profile::Distribution, true, false); + build::build_launcher(Profile::Distribution, true, false, false); include_licenses(&afs::launcher_build_dir(), false); From fb900d1255d290cce46b1b1972e5fe8b83f2a851 Mon Sep 17 00:00:00 2001 From: Meister1593 Date: Sat, 9 Aug 2025 10:42:46 +0200 Subject: [PATCH 13/14] reformat --- alvr/xtask/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alvr/xtask/src/main.rs b/alvr/xtask/src/main.rs index a289eb33de..4c7109dbe5 100644 --- a/alvr/xtask/src/main.rs +++ b/alvr/xtask/src/main.rs @@ -278,7 +278,7 @@ fn main() { } "run-launcher" => { if !no_rebuild { - build::build_launcher(profile, locked, frozen, offline); + build::build_launcher(profile, locked, frozen, offline); } run_launcher(); } From d73503434ad652e96516957d06b167c3e4c504fc Mon Sep 17 00:00:00 2001 From: Meister1593 Date: Sat, 9 Aug 2025 11:00:54 +0200 Subject: [PATCH 14/14] move common build flags to separate struct to pass around --- alvr/xtask/src/build.rs | 34 +++++++++++++------------- alvr/xtask/src/main.rs | 48 ++++++++++++++++--------------------- alvr/xtask/src/packaging.rs | 16 +++++++++---- 3 files changed, 48 insertions(+), 50 deletions(-) diff --git a/alvr/xtask/src/build.rs b/alvr/xtask/src/build.rs index 0b0f7bf13b..1438a503fe 100644 --- a/alvr/xtask/src/build.rs +++ b/alvr/xtask/src/build.rs @@ -1,4 +1,4 @@ -use crate::command; +use crate::{CommonBuildFlags, command}; use alvr_filesystem::{self as afs, Layout}; use std::{ env, @@ -27,7 +27,11 @@ impl Display for Profile { } } -pub fn build_server_lib(profile: Profile, root: Option, locked: bool, offline: bool) { +pub fn build_server_lib( + profile: Profile, + root: Option, + common_build_flags: CommonBuildFlags, +) { let sh = Shell::new().unwrap(); let mut flags = vec![]; @@ -39,10 +43,10 @@ pub fn build_server_lib(profile: Profile, root: Option, locked: bool, of Profile::Release => flags.push("--release"), Profile::Debug => (), } - if locked { + if common_build_flags.locked { flags.push("--locked"); } - if offline { + if common_build_flags.offline { flags.push("--offline"); } let flags_ref = &flags; @@ -78,10 +82,7 @@ pub fn build_streamer( profile: Profile, gpl: bool, root: Option, - locked: bool, - frozen: bool, - offline: bool, - profiling: bool, + common_build_flags: CommonBuildFlags, keep_config: bool, ) { let sh = Shell::new().unwrap(); @@ -97,13 +98,13 @@ pub fn build_streamer( Profile::Release => common_flags.push("--release"), Profile::Debug => (), } - if locked { + if common_build_flags.locked { common_flags.push("--locked"); } - if frozen { + if common_build_flags.frozen { common_flags.push("--frozen"); } - if offline { + if common_build_flags.offline { common_flags.push("--offline"); } @@ -147,7 +148,7 @@ pub fn build_streamer( vec![] }; - let profiling_flag = if profiling { + let profiling_flag = if common_build_flags.profiling { vec!["--features", "alvr_server_core/trace-performance"] } else { vec![] @@ -284,7 +285,7 @@ pub fn build_streamer( } } -pub fn build_launcher(profile: Profile, locked: bool, frozen: bool, offline: bool) { +pub fn build_launcher(profile: Profile, common_build_flags: CommonBuildFlags) { let sh = Shell::new().unwrap(); let mut common_flags = vec![]; @@ -296,13 +297,10 @@ pub fn build_launcher(profile: Profile, locked: bool, frozen: bool, offline: boo Profile::Release => common_flags.push("--release"), Profile::Debug => (), } - if locked { + if common_build_flags.locked { common_flags.push("--locked"); } - if frozen { - common_flags.push("--frozen"); - } - if offline { + if common_build_flags.offline { common_flags.push("--offline"); } let common_flags_ref = &common_flags; diff --git a/alvr/xtask/src/main.rs b/alvr/xtask/src/main.rs index 4c7109dbe5..a7a1e80322 100644 --- a/alvr/xtask/src/main.rs +++ b/alvr/xtask/src/main.rs @@ -79,6 +79,14 @@ enum BuildPlatform { Android, } +#[derive(Default)] +pub struct CommonBuildFlags { + locked: bool, + frozen: bool, + offline: bool, + profiling: bool, +} + pub fn print_help_and_exit(message: &str) -> ! { eprintln!("\n{message}"); eprintln!("{HELP_STR}"); @@ -183,7 +191,6 @@ fn main() { } else { Profile::Debug }; - let profiling = args.contains("--profiling"); let gpl = args.contains("--gpl"); let is_nightly = args.contains("--nightly"); let no_rebuild = args.contains("--no-rebuild"); @@ -191,9 +198,12 @@ fn main() { let keep_config = args.contains("--keep-config"); let link_stdcpp = !args.contains("--no-stdcpp"); let all_targets = args.contains("--all-targets"); - let locked = args.contains("--locked"); - let frozen = args.contains("--frozen"); - let offline = args.contains("--offline"); + let common_build_flags = CommonBuildFlags { + locked: args.contains("--locked"), + frozen: args.contains("--frozen"), + offline: args.contains("--offline"), + profiling: args.contains("--profiling"), + }; let platform: Option = args.opt_value_from_str("--platform").unwrap(); let platform = platform.as_deref().map(|platform| match platform { @@ -242,18 +252,11 @@ fn main() { dependencies::download_server_deps(platform, for_ci, !no_nvidia) } "build-server-deps" => dependencies::build_server_deps(platform, !no_nvidia), - "build-streamer" => build::build_streamer( - profile, - gpl, - None, - locked, - frozen, - offline, - profiling, - keep_config, - ), - "build-launcher" => build::build_launcher(profile, locked, frozen, offline), - "build-server-lib" => build::build_server_lib(profile, None, locked, offline), + "build-streamer" => { + build::build_streamer(profile, gpl, None, common_build_flags, keep_config) + } + "build-launcher" => build::build_launcher(profile, common_build_flags), + "build-server-lib" => build::build_server_lib(profile, None, common_build_flags), "build-client" => build::build_android_client(profile), "build-client-lib" => { build::build_android_client_core_lib(profile, link_stdcpp, all_targets) @@ -263,22 +266,13 @@ fn main() { } "run-streamer" => { if !no_rebuild { - build::build_streamer( - profile, - gpl, - None, - locked, - frozen, - offline, - profiling, - keep_config, - ); + build::build_streamer(profile, gpl, None, common_build_flags, keep_config); } run_streamer(); } "run-launcher" => { if !no_rebuild { - build::build_launcher(profile, locked, frozen, offline); + build::build_launcher(profile, common_build_flags); } run_launcher(); } diff --git a/alvr/xtask/src/packaging.rs b/alvr/xtask/src/packaging.rs index 6780fb1d60..aeb6d324d5 100644 --- a/alvr/xtask/src/packaging.rs +++ b/alvr/xtask/src/packaging.rs @@ -65,10 +65,10 @@ pub fn package_streamer( Profile::Distribution, gpl, root, - true, - false, - false, - false, + crate::CommonBuildFlags { + locked: true, + ..Default::default() + }, false, ); @@ -86,7 +86,13 @@ pub fn package_launcher() { sh.remove_path(afs::launcher_build_dir()).ok(); - build::build_launcher(Profile::Distribution, true, false, false); + build::build_launcher( + Profile::Distribution, + crate::CommonBuildFlags { + locked: true, + ..Default::default() + }, + ); include_licenses(&afs::launcher_build_dir(), false);