diff --git a/scripts/build_libsurvive.sh b/scripts/build_libsurvive.sh index c3a8776..92c11f1 100755 --- a/scripts/build_libsurvive.sh +++ b/scripts/build_libsurvive.sh @@ -4,11 +4,25 @@ set -ev REPO_DIR=$1 +PREFIX=$2 + +if [[ -z $REPO_DIR ]] || [[ -z $PREFIX ]]; then + echo "Usage: $0 REPO_DIR PREFIX" + exit 1 +fi + "$(dirname -- "$0")/_clone_or_pull.sh" "https://github.com/cntools/libsurvive" "$REPO_DIR" cd "$REPO_DIR" mkdir -p build cd build -cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_api_example=OFF -DCMAKE_SKIP_INSTALL_RPATH=YES -Wno-dev .. +cmake -DCMAKE_BUILD_TYPE=Release \ + -DENABLE_api_example=OFF \ + -DCMAKE_SKIP_INSTALL_RPATH=YES \ + -Wno-dev \ + -DCMAKE_INSTALL_PREFIX="${PREFIX}" \ + -DCMAKE_INSTALL_LIBDIR="${PREFIX}/lib" \ + .. make clean make -j$(nproc) +make install diff --git a/scripts/build_monado.sh b/scripts/build_monado.sh index 55b73b9..c51cf95 100755 --- a/scripts/build_monado.sh +++ b/scripts/build_monado.sh @@ -6,11 +6,23 @@ set -ev REPO_DIR=$1 -"$(dirname -- "$0")/_clone_or_pull.sh" "https://github.com/cntools/libsurvive" "$REPO_DIR" +PREFIX=$2 + +if [[ -z $REPO_DIR ]] || [[ -z $PREFIX ]]; then + echo "Usage: $0 REPO_DIR PREFIX" + exit 1 +fi + +"$(dirname -- "$0")/_clone_or_pull.sh" "https://gitlab.freedesktop.org/monado/monado" "$REPO_DIR" cd "$REPO_DIR" mkdir -p build cd build -cmake -DCMAKE_BUILD_TYPE=Release .. +export PKG_CONFIG_PATH="${PREFIX}/lib/pkgconfig" +cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_LIBDIR="${PREFIX}/lib" \ + -DCMAKE_INSTALL_PREFIX="${PREFIX}" \ + .. make clean make -j$(nproc) +make install diff --git a/src/builders/build_libsurvive.rs b/src/builders/build_libsurvive.rs index d13aee9..83a9530 100644 --- a/src/builders/build_libsurvive.rs +++ b/src/builders/build_libsurvive.rs @@ -5,9 +5,12 @@ pub fn get_build_libsurvive_runner(profile: Profile) -> Runner { let runner = Runner::new( None, "./scripts/build_libsurvive.sh".into(), - vec![profile - .libsurvive_path - .expect_dialog("Missing libsurvive path for given profile")], + vec![ + profile + .libsurvive_path + .expect_dialog("Missing libsurvive path for given profile"), + profile.prefix, + ], ); runner } diff --git a/src/builders/build_monado.rs b/src/builders/build_monado.rs index bc093e9..ca7da4a 100644 --- a/src/builders/build_monado.rs +++ b/src/builders/build_monado.rs @@ -6,7 +6,8 @@ pub fn get_build_monado_runner(profile: Profile) -> Runner { None, "./scripts/build_monado.sh".into(), vec![ - profile.monado_path + profile.monado_path, + profile.prefix, ] ); runner diff --git a/src/main.rs b/src/main.rs index 85ab14d..f1dd2cc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,7 @@ pub mod profile; pub mod profiles; pub mod runner; pub mod ui; +pub mod runner_pipeline; fn main() { let app = RelmApp::new(APP_ID); diff --git a/src/profile.rs b/src/profile.rs index 1363432..1e1a4a1 100644 --- a/src/profile.rs +++ b/src/profile.rs @@ -16,6 +16,8 @@ pub struct Profile { pub basalt_enabled: bool, pub mercury_enabled: bool, pub environment: HashMap, + /** Install prefix */ + pub prefix: String, } impl Display for Profile { @@ -47,6 +49,7 @@ mod tests { assert_eq!(profile.name, "Demo profile"); assert_eq!(profile.monado_path, "/home/user/monado"); assert_eq!(profile.openovr_path, "/home/user/openovr"); + assert_eq!(profile.prefix, "/home/user/rex2prefix"); assert_eq!( profile.libsurvive_path.as_deref(), Some("/home/user/libsurvive") @@ -81,6 +84,7 @@ mod tests { basalt_enabled: false, mercury_enabled: false, environment: env, + prefix: String::from("/home/user/rex2prefix") }; let fpath = String::from("./target/testout/testprofile.json"); dump_profile(p, &fpath); diff --git a/src/profiles/valve_index.rs b/src/profiles/valve_index.rs index 930ad89..fb6b7f1 100644 --- a/src/profiles/valve_index.rs +++ b/src/profiles/valve_index.rs @@ -3,11 +3,13 @@ use std::collections::HashMap; pub fn valve_index_profile() -> Profile { let data_dir = get_data_dir(); + let prefix = format!("{data}/prefixes/valve_index_default", data = data_dir); let mut environment: HashMap = HashMap::new(); environment.insert("XRT_COMPOSITOR_SCALE_PERCENTAGE".into(), "140".into()); environment.insert("XRT_COMPOSITOR_COMPUTE".into(), "1".into()); environment.insert("SURVIVE_GLOBALSCENESOLVER".into(), "0".into()); environment.insert("SURVIVE_TIMECODE_OFFSET_MS".into(), "-6.94".into()); + environment.insert("LD_LIBRARY_PATH".into(), format!("{pfx}/lib", pfx = prefix)); Profile { name: format!("Valve Index - {name} Default", name = APP_NAME), monado_path: format!("{data}/monado", data = data_dir), @@ -19,5 +21,6 @@ pub fn valve_index_profile() -> Profile { basalt_enabled: false, mercury_enabled: false, environment, + prefix, } } diff --git a/src/runner.rs b/src/runner.rs index 30fe330..16baf1c 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -87,11 +87,11 @@ impl Runner { } pub fn monado_runner_from_profile(profile: Profile) -> Self { - let mut path = profile.monado_path; - if !path.starts_with("/usr") { - path += "/build/src/xrt/targets/service/monado-service"; - } - Self::new(Some(profile.environment), path, vec![]) + Self::new( + Some(profile.environment), + format!("{pfx}/bin/monado-service", pfx = profile.prefix), + vec![], + ) } pub fn start(&mut self) { @@ -157,14 +157,18 @@ impl Runner { } } - pub fn get_output(&mut self) -> String { + pub fn consume_output(&mut self) -> String { self.receive_output(); - self.output.concat() + let res = self.output.concat(); + self.output.clear(); + res } - pub fn get_rows(&mut self) -> Vec { + pub fn consume_rows(&mut self) -> Vec { self.receive_output(); - self.output.clone() + let res = self.output.clone(); + self.output.clear(); + res } fn save_log(path_s: String, log: &Vec) -> Result<(), std::io::Error> { @@ -199,7 +203,7 @@ mod tests { sleep(time::Duration::from_millis(10)); runner.terminate(); assert_eq!(runner.status(), RunnerStatus::Stopped); - let out = runner.get_output(); + let out = runner.consume_output(); assert_eq!(out, "REX2TEST: Lorem ipsum dolor\n"); } @@ -222,8 +226,6 @@ mod tests { #[test] fn can_create_from_profile() { - Runner::monado_runner_from_profile( - load_profile(&"./test/files/profile.json".to_string()), - ); + Runner::monado_runner_from_profile(load_profile(&"./test/files/profile.json".to_string())); } } diff --git a/src/runner_pipeline.rs b/src/runner_pipeline.rs new file mode 100644 index 0000000..39540e2 --- /dev/null +++ b/src/runner_pipeline.rs @@ -0,0 +1,79 @@ +use std::{cell::RefCell, borrow::BorrowMut}; + +use crate::runner::{Runner, RunnerStatus}; + +pub struct RunnerPipeline { + runners: Vec>, + current_index: usize, + has_started: bool, + pub log: Vec, +} + +impl RunnerPipeline { + pub fn new(runners: Vec) -> Self { + let mut c_runners: Vec> = vec![]; + for runner in runners { + c_runners.push(RefCell::new(runner)); + } + Self { + runners: c_runners, + current_index: 0, + has_started: false, + log: vec![], + } + } + + pub fn get_current_runner(&self) -> Option<&RefCell> { + self.runners.get(self.current_index) + } + + pub fn start(&mut self) { + if self.has_started { + return; + } + self.has_started = true; + match self.get_current_runner() { + None => { return; }, + Some(runner) => { + runner.borrow_mut().start(); + } + } + } + + pub fn update(&mut self) { + if !self.has_started { + return; + } + + match self.get_current_runner() { + None => {}, + Some(c_runner) => { + let (status, log) = { + let mut runner = c_runner.borrow_mut(); + (runner.status(), runner.consume_rows()) + }; + self.log.extend(log); + match status { + RunnerStatus::Running => {}, + RunnerStatus::Stopped => { + self.current_index += 1; + match self.get_current_runner() { + None => {}, + Some(c_runner) => { + c_runner.borrow_mut().start(); + } + } + } + } + } + } + } + + pub fn get_log(&self) -> String { + self.log.concat() + } + + pub fn is_running(&self) -> bool { + self.get_current_runner().is_some() + } +} diff --git a/src/ui/app.rs b/src/ui/app.rs index fdebf16..6c26653 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -1,5 +1,6 @@ use std::time::Duration; +use crate::builders::build_libsurvive::get_build_libsurvive_runner; use crate::builders::build_monado::get_build_monado_runner; use crate::config::{get_config, save_config, Config}; use crate::constants::APP_NAME; @@ -8,6 +9,7 @@ use crate::dependencies::monado_deps::{check_monado_deps, get_missing_monado_dep use crate::profile::Profile; use crate::profiles::valve_index::valve_index_profile; use crate::runner::{Runner, RunnerStatus}; +use crate::runner_pipeline::RunnerPipeline; use crate::ui::build_window::BuildWindowMsg; use crate::ui::debug_view::DebugViewInit; use crate::ui::main_view::{MainView, MainViewInit, MainViewOutMsg}; @@ -45,7 +47,9 @@ pub struct App { #[tracker::do_not_track] monado_runner: Option, #[tracker::do_not_track] - build_runner: Option, + monado_log: Vec, + #[tracker::do_not_track] + build_pipeline: Option, #[tracker::do_not_track] profiles: Vec, } @@ -75,6 +79,7 @@ impl App { } pub fn start_monado(&mut self) { + self.monado_log.clear(); let mut runner = Runner::monado_runner_from_profile(self.get_selected_profile().clone()); runner.start(); self.monado_runner = Some(runner); @@ -131,22 +136,24 @@ impl SimpleComponent for App { None => {} Some(runner) => match runner.status() { RunnerStatus::Running => { + self.monado_log.extend(runner.consume_rows()); self.debug_view .sender() - .emit(DebugViewMsg::LogUpdated(runner.get_rows())); + .emit(DebugViewMsg::LogUpdated(self.monado_log.clone())); } _ => {} }, }; - match &mut self.build_runner { + match &mut self.build_pipeline { None => {} - Some(runner) => match runner.status() { - RunnerStatus::Running => { + Some(pipeline) => match pipeline.is_running() { + true => { + pipeline.update(); self.build_window .sender() - .emit(BuildWindowMsg::UpdateContent(runner.get_output())); - } - RunnerStatus::Stopped => { + .emit(BuildWindowMsg::UpdateContent(pipeline.get_log())); + }, + false => { self.build_window .sender() .emit(BuildWindowMsg::UpdateCanClose(true)); @@ -196,15 +203,20 @@ impl SimpleComponent for App { Msg::BuildProfile => { let profile = self.get_selected_profile(); let mut missing_deps = get_missing_monado_deps(); + let mut runners: Vec = vec![]; if profile.libsurvive_enabled { missing_deps.extend(get_missing_libsurvive_deps()); + runners.push(get_build_libsurvive_runner(profile.clone())); } // if profile.basalt_enabled { // missing_deps.extend(get_missing_basalt_deps()); + // runners.push(get_build_basalt_runner(profile.clone())); // } // if profile.mercury_enabled { // missing_deps.extend(get_missing_mercury_deps()); + // runners.push(get_build_mercury_runner(profile.clone())); // } + runners.push(get_build_monado_runner(profile.clone())); if !missing_deps.is_empty() { self.dependencies_dialog.set_body( missing_deps @@ -221,15 +233,15 @@ impl SimpleComponent for App { .sender() .send(BuildWindowMsg::Present) .unwrap(); - let mut runner = get_build_monado_runner(profile.clone()); - runner.start(); + let mut pipeline = RunnerPipeline::new(runners); + pipeline.start(); self.build_window .sender() .emit(BuildWindowMsg::UpdateTitle("Building Monado".into())); self.build_window .sender() .emit(BuildWindowMsg::UpdateCanClose(false)); - self.build_runner = Some(runner); + self.build_pipeline = Some(pipeline); } Msg::ProfileSelected(prof_name) => { self.config.selected_profile_name = prof_name; @@ -284,7 +296,8 @@ impl SimpleComponent for App { tracker: 0, profiles, monado_runner: None, - build_runner: None, + monado_log: vec![], + build_pipeline: None, }; let widgets = view_output!(); diff --git a/test/files/profile.json b/test/files/profile.json index f2b552d..fe19b82 100644 --- a/test/files/profile.json +++ b/test/files/profile.json @@ -12,5 +12,6 @@ "XRT_COMPOSITOR_SCALE_PERCENTAGE": "140", "XRT_COMPOSITOR_COMPUTE": "1", "SURVIVE_GLOBALSCENESOLVER": "0" - } + }, + "prefix": "/home/user/rex2prefix" }