1use crate::errors::*;
2use crate::project;
3use crate::project::{rec_copy, Project};
4use crate::utils::copy_and_sync_file;
5use crate::Build;
6use crate::BuildBundle;
7use fs_err as fs;
8use log::debug;
9use std::path::Path;
10
11pub fn make_remote_app(project: &Project, build: &Build) -> Result<BuildBundle> {
12 make_remote_app_with_name(project, build, None)
13}
14
15pub fn make_remote_app_with_name(
16 project: &Project,
17 build: &Build,
18 bundle_name: Option<&str>,
19) -> Result<BuildBundle> {
20 fn is_sysroot_library(path: &Path) -> bool {
21 path.ancestors()
22 .find(|ancestor_path| ancestor_path.ends_with("sysroot/usr/lib"))
23 .is_some()
24 && (!path
25 .file_name()
26 .unwrap()
27 .to_str()
28 .unwrap()
29 .eq_ignore_ascii_case("libc++_shared.so")
30 && !path.to_str().unwrap().contains("android"))
31 }
32
33 let root_dir = build.target_path.join("dinghy").join(build.runnable.id.clone());
34 let bundle_path = match bundle_name {
35 Some(name) => root_dir.join(&build.runnable.package_name).join(name),
36 None => root_dir.join(&build.runnable.package_name),
37 };
38 let bundle_libs_path = root_dir.join("overlay");
39 let bundle_target_path = &bundle_path;
40 let bundle_exe_path = bundle_target_path.join(format!("_dinghy_{}", &build.runnable.id));
41
42 debug!("Removing previous bundle {:?}", bundle_path);
43 let _ = fs::remove_dir_all(&bundle_path);
44 let _ = fs::remove_dir_all(&bundle_libs_path);
45 let _ = fs::remove_dir_all(&bundle_target_path);
46
47 debug!("Making bundle {:?}", bundle_path);
48 fs::create_dir_all(&bundle_path)?;
49 fs::create_dir_all(&bundle_libs_path)?;
50 fs::create_dir_all(&bundle_target_path)?;
51
52 debug!(
53 "Copying exe {:?} to bundle {:?}",
54 &build.runnable.exe, bundle_exe_path
55 );
56 copy_and_sync_file(&build.runnable.exe, &bundle_exe_path).with_context(|| {
57 format!(
58 "Couldn't copy {} to {}",
59 &build.runnable.exe.display(),
60 &bundle_exe_path.display()
61 )
62 })?;
63
64 debug!("Copying dynamic libs to bundle");
65 for src_lib_path in &build.dynamic_libraries {
66 let target_lib_path = bundle_libs_path.join(
67 src_lib_path
68 .file_name()
69 .ok_or_else(|| anyhow!("Invalid file name {:?}", src_lib_path.file_name()))?,
70 );
71 if !is_sysroot_library(&src_lib_path) {
72 debug!(
73 "Copying dynamic lib {} to {}",
74 src_lib_path.display(),
75 target_lib_path.display()
76 );
77 copy_and_sync_file(&src_lib_path, &target_lib_path).with_context(|| {
78 format!(
79 "Couldn't copy {} to {}",
80 src_lib_path.display(),
81 &target_lib_path.display()
82 )
83 })?;
84 } else {
85 debug!(
86 "Dynamic lib {} will not be copied as it is a sysroot library",
87 src_lib_path.display()
88 );
89 }
90 }
91
92 for file_in_run_args in &build.files_in_run_args {
93 let dst = bundle_target_path.join(
94 file_in_run_args
95 .file_name()
96 .ok_or_else(|| anyhow!("no file name"))?,
97 );
98 if file_in_run_args.is_dir() {
99 rec_copy(file_in_run_args, dst, true)?;
100 } else {
101 copy_and_sync_file(&file_in_run_args, &dst).with_context(|| {
102 format!(
103 "Couldn't copy {} to {}",
104 file_in_run_args.display(),
105 &root_dir.display()
106 )
107 })?;
108 }
109 }
110
111 if !build.runnable.skip_source_copy {
112 debug!(
113 "Copying src {} to bundle {}",
114 build.runnable.source.display(),
115 bundle_path.display()
116 );
117 project::rec_copy_excl(
118 &build.runnable.source,
119 &bundle_path,
120 false,
121 &[build.runnable.source.join("target")],
122 )?;
123 } else {
124 debug!("Skipping source copy to bundle {}", bundle_path.display());
125 }
126
127 debug!("Copying test_data to bundle {}", bundle_path.display());
128 project.copy_test_data(&bundle_path)?;
129
130 Ok(BuildBundle {
131 id: build.runnable.id.clone(),
132 bundle_dir: bundle_path.to_path_buf(),
133 bundle_exe: bundle_exe_path.to_path_buf(),
134 lib_dir: bundle_libs_path.to_path_buf(),
135 root_dir,
136 app_id: None,
137 })
138}