diff --git a/.github/workflows/queue.yml b/.github/workflows/queue.yml index 2f3c251e..8dab6658 100644 --- a/.github/workflows/queue.yml +++ b/.github/workflows/queue.yml @@ -28,10 +28,10 @@ jobs: sudo apt-get update sudo apt-get install libfuse2 build-essential pkg-config nasm libva-dev libdrm-dev libvulkan-dev libx264-dev libx265-dev cmake libasound2-dev libjack-jackd2-dev libxrandr-dev libunwind-dev libgtk-3-dev libpipewire-0.3-dev libspa-0.2-dev - - name: Prepare deps + - name: Build deps env: RUST_BACKTRACE: 1 - run: cargo xtask prepare-deps --platform linux + run: cargo xtask build-server-deps - run: cargo xtask ci-clippy @@ -50,9 +50,9 @@ jobs: sudo apt update sudo apt install build-essential pkg-config nasm libva-dev libdrm-dev libvulkan-dev libx264-dev libasound2-dev libxrandr-dev libunwind-dev libgtk-3-dev libpipewire-0.3-dev libspa-0.2-dev - - name: Prepare deps + - name: Build deps env: RUST_BACKTRACE: 1 - run: cargo xtask prepare-deps --platform linux + run: cargo xtask build-server-deps - run: cargo xtask check-msrv diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index b814b5cf..f783ac36 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -27,10 +27,10 @@ jobs: sudo apt update sudo apt install build-essential pkg-config nasm libva-dev libdrm-dev libvulkan-dev libx264-dev libasound2-dev libxrandr-dev libunwind-dev libgtk-3-dev libpipewire-0.3-dev libspa-0.2-dev - - name: Prepare deps + - name: Build deps env: RUST_BACKTRACE: 1 - run: cargo xtask prepare-deps --platform linux + run: cargo xtask build-server-deps - run: cargo xtask ci-clippy diff --git a/.gitignore b/.gitignore index 9e5d8b6a..b7a61016 100644 --- a/.gitignore +++ b/.gitignore @@ -55,8 +55,8 @@ dist .DS_Store .ccls-cache -# dependencies installed by xtask -deps +# dependencies built by xtask +**/nanvr_build # dependencies installed by node node_modules diff --git a/.gitmodules b/.gitmodules index 6d2a35ce..3d698ae8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,21 @@ [submodule "openvr"] - path = openvr + path = thirdparty/openvr url = https://github.com/ValveSoftware/openvr.git shallow = true + ignore = dirty +[submodule "x264"] + path = thirdparty/x264 + url = https://code.videolan.org/videolan/x264.git + shallow = true + ignore = dirty +[submodule "FFmpeg"] + path = thirdparty/ffmpeg + url = https://code.ffmpeg.org/FFmpeg/FFmpeg.git + branch = release/6.0 + shallow = true + ignore = dirty +[submodule "nv-codec-headers"] + path = thirdparty/nv-codec-headers + url = https://code.ffmpeg.org/FFmpeg/nv-codec-headers.git + shallow = true + ignore = dirty \ No newline at end of file diff --git a/nanvr/configuration/build.rs b/nanvr/configuration/build.rs index aaff0fbe..ab4a0931 100644 --- a/nanvr/configuration/build.rs +++ b/nanvr/configuration/build.rs @@ -2,9 +2,10 @@ use regex::Regex; use std::{env, fmt::Write, fs, path::PathBuf}; fn main() { - let openvr_driver_header_string = - fs::read_to_string(filepaths::workspace_dir().join("openvr/headers/openvr_driver.h")) - .expect("Missing openvr header files, did you clone the submodule?\n"); + let openvr_driver_header_string = fs::read_to_string( + filepaths::workspace_dir().join("thirdparty/openvr/headers/openvr_driver.h"), + ) + .expect("Missing openvr header files, did you clone the submodule?\n"); let property_finder = Regex::new( r"\tProp_([A-Za-z\d_]+)_(Bool|Int32|Uint64|Float|String|Vector3)[\t ]+= ([0-9]+)", diff --git a/nanvr/server_openvr/build.rs b/nanvr/server_openvr/build.rs index 034e6a01..21ba4881 100644 --- a/nanvr/server_openvr/build.rs +++ b/nanvr/server_openvr/build.rs @@ -2,12 +2,12 @@ use std::{env, path::PathBuf}; use shared::{NANVR_HIGH_NAME, NANVR_LOW_NAME}; -fn get_ffmpeg_path() -> PathBuf { - filepaths::deps_dir().join("linux/ffmpeg/nanvr_build") +fn get_ffmpeg_build_path() -> PathBuf { + filepaths::workspace_dir().join("thirdparty/ffmpeg/nanvr_build") } -fn get_linux_x264_path() -> PathBuf { - filepaths::deps_dir().join("linux/x264/nanvr_build") +fn get_linux_x264_build_path() -> PathBuf { + filepaths::workspace_dir().join("thirdparty/x264/nanvr_build") } fn main() { @@ -45,18 +45,18 @@ fn main() { .cpp(true) .std("c++17") .files(source_files_paths) - .include(filepaths::workspace_dir().join("openvr/headers")) + .include(filepaths::workspace_dir().join("thirdparty/openvr/headers")) .include("cpp"); #[cfg(debug_assertions)] build.define(&format!("{NANVR_HIGH_NAME}_DEBUG_LOG"), None); - let ffmpeg_path = get_ffmpeg_path(); + let ffmpeg_path = get_ffmpeg_build_path(); assert!(ffmpeg_path.join("include").exists()); build.include(ffmpeg_path.join("include")); - let x264_path = get_linux_x264_path(); + let x264_path = get_linux_x264_build_path(); assert!(x264_path.join("include").exists()); build.include(x264_path.join("include")); @@ -65,7 +65,7 @@ fn main() { build.compile("bindings"); - let x264_path = get_linux_x264_path(); + let x264_path = get_linux_x264_build_path(); let x264_lib_path = x264_path.join("lib"); println!( @@ -93,7 +93,7 @@ fn main() { .unwrap(); // ffmpeg - let ffmpeg_path = get_ffmpeg_path(); + let ffmpeg_path = get_ffmpeg_build_path(); let ffmpeg_lib_path = ffmpeg_path.join("lib"); assert!(ffmpeg_lib_path.exists()); @@ -134,7 +134,7 @@ fn main() { println!( "cargo:rustc-link-search=native={}", filepaths::workspace_dir() - .join("openvr/lib/linux64") + .join("thirdparty/openvr/lib/linux64") .to_string_lossy() ); println!("cargo:rustc-link-lib=openvr_api"); diff --git a/nanvr/xtask/flatpak/com.valvesoftware.Steam.Utility.nanvr.json b/nanvr/xtask/flatpak/com.valvesoftware.Steam.Utility.nanvr.json index 35e569f6..6ccbfe3a 100644 --- a/nanvr/xtask/flatpak/com.valvesoftware.Steam.Utility.nanvr.json +++ b/nanvr/xtask/flatpak/com.valvesoftware.Steam.Utility.nanvr.json @@ -36,7 +36,7 @@ "build-commands": [ "mkdir -p /app/utils/nanvr/bin", "cd nanvr/launcher", - "cargo xtask prepare-deps --platform linux", + "cargo xtask build-server-deps", "cargo xtask build-launcher --profile release", "mv '/run/build/nanvr/build/nanvr_launcher/NaNVR Launcher' /app/utils/nanvr/bin/nanvr_launcher", " # get read-only errors from following lines - because this is an extension - so leave as comments until someone figures this out", diff --git a/nanvr/xtask/src/build.rs b/nanvr/xtask/src/build.rs index 0325cc79..b2f89171 100644 --- a/nanvr/xtask/src/build.rs +++ b/nanvr/xtask/src/build.rs @@ -195,7 +195,7 @@ pub fn build_streamer( .unwrap(); sh.copy_file( - filepaths::workspace_dir().join("openvr/bin/linux64/libopenvr_api.so"), + filepaths::workspace_dir().join("thirdparty/openvr/bin/linux64/libopenvr_api.so"), build_layout.openvr_driver_lib_dir(), ) .unwrap(); diff --git a/nanvr/xtask/src/command.rs b/nanvr/xtask/src/command.rs index cc9b7530..d2c1373e 100644 --- a/nanvr/xtask/src/command.rs +++ b/nanvr/xtask/src/command.rs @@ -10,10 +10,6 @@ pub fn unzip(sh: &Shell, source: &Path, destination: &Path) -> Result<(), xshell cmd!(sh, "unzip {source} -d {destination}").run() } -pub fn untar(sh: &Shell, source: &Path, destination: &Path) -> Result<(), xshell::Error> { - cmd!(sh, "tar -xvf {source} -C {destination}").run() -} - pub fn targz(sh: &Shell, source: &Path) -> Result<(), xshell::Error> { let parent_dir = source.parent().unwrap(); let file_name = source.file_name().unwrap(); @@ -35,16 +31,6 @@ pub fn download_and_extract_zip(url: &str, destination: &Path) -> Result<(), xsh unzip(&sh, &zip_file, destination) } -pub fn download_and_extract_tar(url: &str, destination: &Path) -> Result<(), xshell::Error> { - let sh = Shell::new().unwrap(); - let temp_dir_guard = sh.create_temp_dir()?; - - let tar_file = temp_dir_guard.path().join("temp_download.tar"); - download(&sh, url, &tar_file)?; - - untar(&sh, &tar_file, destination) -} - pub fn date_utc_yyyymmdd(sh: &Shell) -> Result { cmd!(sh, "date -u +%Y.%m.%d").read() } diff --git a/nanvr/xtask/src/dependencies/linux.rs b/nanvr/xtask/src/dependencies/linux.rs index 2ada3791..6ab3fe45 100644 --- a/nanvr/xtask/src/dependencies/linux.rs +++ b/nanvr/xtask/src/dependencies/linux.rs @@ -1,108 +1,30 @@ -use crate::command; - -use std::fs; use xshell::{Shell, cmd}; -pub fn prepare_server_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 clean_and_build_server_deps(enable_nvenc: bool) { + clean_deps(); build_x264(); build_ffmpeg(enable_nvenc); } -pub fn download_server_deps(enable_nvenc: bool) { +fn clean_deps() { 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_server_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 { - filepaths::deps_dir().join("linux") + // Clean submodule folders from previous build directories and patches + let ffmpeg_command = "for p in thirdparty/*; do (cd $p; git reset --hard; git clean -df); done"; + cmd!(sh, "bash -c {ffmpeg_command}").run().unwrap(); } fn x264_path() -> std::path::PathBuf { - deps_path().join("x264") + filepaths::workspace_dir().join("thirdparty/x264") } fn ffmpeg_path() -> std::path::PathBuf { - deps_path().join("ffmpeg") + filepaths::workspace_dir().join("thirdparty/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(); + filepaths::workspace_dir().join("thirdparty/nv-codec-headers") } fn build_x264() { @@ -173,7 +95,7 @@ fn build_ffmpeg(enable_nvenc: bool) { 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 ../../../nanvr/xtask/patches/*; do patch -p1 < $p; done"; + let ffmpeg_command = "for p in ../../nanvr/xtask/patches/*; do patch -p1 < $p; done"; cmd!(sh, "bash -c {ffmpeg_command}").run().unwrap(); if enable_nvenc { @@ -187,7 +109,7 @@ fn build_ffmpeg(enable_nvenc: bool) { https://docs.nvidia.com/video-technologies/video-codec-sdk/ffmpeg-with-nvidia-gpu/#commonly-faced-issues-and-tips-to-resolve-them */ let nvenc_headers_path = nvenc_headers_path(); - let header_build_dir = nvenc_headers_path.join("build"); + let header_build_dir = nvenc_headers_path.join("nanvr_build"); sh.remove_path(&header_build_dir).ok(); { let make_header_cmd = format!("make install PREFIX='{}'", header_build_dir.display()); diff --git a/nanvr/xtask/src/main.rs b/nanvr/xtask/src/main.rs index 0bcc4617..dd63d789 100644 --- a/nanvr/xtask/src/main.rs +++ b/nanvr/xtask/src/main.rs @@ -24,7 +24,7 @@ struct Cli { } #[derive(Subcommand)] enum Commands { - /// Download and compile streamer or/and client external dependencies + /// Compile streamer or/and download client external dependencies PrepareDeps { /// If not specified, prepares server and android dependencies at the same time #[arg(long, value_enum)] @@ -36,12 +36,6 @@ enum Commands { #[arg(long)] enable_nvenc: bool, }, - /// Download streamer external dependencies - DownloadServerDeps { - /// Enables nvenc support on Linux - #[arg(long)] - enable_nvenc: bool, - }, /// Compile streamer external dependencies BuildServerDeps { /// Enables nvenc support on Linux @@ -226,19 +220,16 @@ fn main() { if matches!(platform, TargetBuildPlatform::Android) { dependencies::android::build_deps(all_targets, &OpenXRLoadersSelection::All); } else { - dependencies::linux::prepare_server_deps(enable_nvenc); + dependencies::linux::clean_and_build_server_deps(enable_nvenc); } } else { - dependencies::linux::prepare_server_deps(enable_nvenc); + dependencies::linux::clean_and_build_server_deps(enable_nvenc); dependencies::android::build_deps(all_targets, &OpenXRLoadersSelection::All); } } - Commands::DownloadServerDeps { enable_nvenc } => { - dependencies::linux::download_server_deps(enable_nvenc); - } Commands::BuildServerDeps { enable_nvenc } => { - dependencies::linux::build_server_deps(enable_nvenc); + dependencies::linux::clean_and_build_server_deps(enable_nvenc); } Commands::BuildStreamer { keep_config, diff --git a/nanvr/xtask/src/packaging.rs b/nanvr/xtask/src/packaging.rs index 328cb1f7..53f3c854 100644 --- a/nanvr/xtask/src/packaging.rs +++ b/nanvr/xtask/src/packaging.rs @@ -50,7 +50,7 @@ pub fn include_licenses(root_path: &Path) { pub fn package_streamer(enable_nvenc: bool, root: Option) { let sh = Shell::new().unwrap(); - dependencies::linux::prepare_server_deps(enable_nvenc); + dependencies::linux::clean_and_build_server_deps(enable_nvenc); build::build_streamer( Profile::Distribution, diff --git a/thirdparty/ffmpeg b/thirdparty/ffmpeg new file mode 160000 index 00000000..ea3d24bb --- /dev/null +++ b/thirdparty/ffmpeg @@ -0,0 +1 @@ +Subproject commit ea3d24bbe3c58b171e55fe2151fc7ffaca3ab3d2 diff --git a/thirdparty/nv-codec-headers b/thirdparty/nv-codec-headers new file mode 160000 index 00000000..1889e62e --- /dev/null +++ b/thirdparty/nv-codec-headers @@ -0,0 +1 @@ +Subproject commit 1889e62e2d35ff7aa9baca2bceb14f053785e6f1 diff --git a/openvr b/thirdparty/openvr similarity index 100% rename from openvr rename to thirdparty/openvr diff --git a/thirdparty/x264 b/thirdparty/x264 new file mode 160000 index 00000000..c1962404 --- /dev/null +++ b/thirdparty/x264 @@ -0,0 +1 @@ +Subproject commit c196240409e4d7c01b47448d93b1f9683aaa7cf7 diff --git a/wiki/Building-From-Source.md b/wiki/Building-From-Source.md index f4900ad7..16a95ffe 100644 --- a/wiki/Building-From-Source.md +++ b/wiki/Building-From-Source.md @@ -50,7 +50,7 @@ Install these additional packages: Move to the root directory of the project, then run this command (paying attention to the bullet points below): ```bash -cargo xtask prepare-deps --platform linux +cargo xtask build-server-deps ``` * Use the `--nvenc` flag if you have a Nvidia GPU. @@ -61,9 +61,9 @@ Next up is the proper build of the streamer. Run the following: cargo xtask build-streamer --release ``` -You can find the resulting package in `build/nanvr_streamer_[your platform]` +You can find the resulting package in `build/nanvr_streamer` -If you want to edit and rebuild the code, you can skip the `prepare-deps` command and run only the `build-streamer` command. +If you want to edit and rebuild the code, you can skip the `build-server-deps` command and run only the `build-streamer` command. ## Fedora CUDA installation