From fc70b4fc03cbd887d1470b32fd222588cce90902 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Fri, 16 Jul 2021 22:50:13 +0200 Subject: [PATCH] feat(core): factor out windows build steps to be reused --- Makefile.toml | 7 ++- scripts/build_windows_portable.rs | 66 +++++--------------------- scripts/build_windows_resources.rs | 76 ++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 56 deletions(-) create mode 100644 scripts/build_windows_resources.rs diff --git a/Makefile.toml b/Makefile.toml index 3df1d92..27c4073 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -28,10 +28,15 @@ dependencies = ["build-binary"] # Windows +[tasks.build-windows-resources] +script_runner = "@rust" +script = { file = "scripts/build_windows_resources.rs" } +dependencies = ["build-binary"] + [tasks.build-windows-portable] script_runner = "@rust" script = { file = "scripts/build_windows_portable.rs" } -dependencies = ["build-binary"] +dependencies = ["build-windows-resources"] # macOS diff --git a/scripts/build_windows_portable.rs b/scripts/build_windows_portable.rs index 28ae17c..a98e61a 100644 --- a/scripts/build_windows_portable.rs +++ b/scripts/build_windows_portable.rs @@ -1,18 +1,18 @@ //! ```cargo //! [dependencies] -//! cc = "1.0.66" //! glob = "0.3.0" //! envmnt = "*" +//! fs_extra = "1.2.0" //! ``` -use std::process::Command; use std::path::PathBuf; const TARGET_DIR: &str = "target/windows/portable"; +const RESOURCE_DIR: &str = "target/windows/resources"; fn main() { // Clean the target directory - std::fs::remove_dir_all(TARGET_DIR); + let _ = std::fs::remove_dir_all(TARGET_DIR); // Create the target directory std::fs::create_dir_all(TARGET_DIR).expect("unable to create target directory"); let target_dir = PathBuf::from(TARGET_DIR); @@ -20,60 +20,16 @@ fn main() { panic!("expected target directory, found none"); } - // We first need to find all the DLLs to redistribute with the binary - // These are found inside the MSVC compiler directory, usually in a place like: - // C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Redist\MSVC\14.28.29910\x64\Microsoft.VC142.CRT - // and they include files like vcruntime140.dll and msvcp140.dll - - // First, we try to find the directory containing the various versions: - // C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Redist\MSVC\ - let tool = cc::windows_registry::find_tool("msvc", "msbuild") - .expect("unable to locate MSVC compiler, did you install Visual Studio?"); - let mut versions_dir = None; - let mut current_root = tool.path(); - while let Some(parent) = current_root.parent() { - let target = parent.join("VC").join("Redist").join("MSVC"); - if target.exists() { - versions_dir = Some(target); - break; - } - current_root = parent; + let resources_dir = PathBuf::from(RESOURCE_DIR); + if !resources_dir.is_dir() { + panic!("expected resources dir, found none"); } - let versions_dir = versions_dir.expect( - r"unable to find path: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Redist\MSVC", - ); - // Then we try to find a suitable directory containing the required DLLs - // C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Redist\MSVC\14.28.29910\x64\Microsoft.VC142.CRT - let glob_pattern = format!( - r"{}\*\x64\Microsoft.*\vcruntime140_1.dll", - versions_dir.to_string_lossy().to_string() - ); - println!("glob_pattern: {}", glob_pattern); - let mut target_file = glob::glob(&glob_pattern) - .expect("failed to read glob pattern") - .next() - .expect("unable to find vcruntime140_1.dll file") - .expect("unable to extract path of vcruntime140_1.dll file"); - - // Copy the DLLs in the target directory - let parent_dir = target_file.parent().expect("unable to obtain directory containing DLLs"); - for entry in glob::glob(&format!(r"{}\*.dll", parent_dir.to_string_lossy().to_string())).expect("unable to glob over DLLs") { - let entry = entry.expect("unable to unwrap DLL entry"); - let filename = entry.file_name().expect("unable to obtain filename"); - std::fs::copy(&entry, target_dir.join(filename)); - } - - // Copy the executable - let exec_path = envmnt::get_or_panic("EXEC_PATH"); - let exec_file = PathBuf::from(&format!("{}.exe", exec_path)); - if !exec_file.is_file() { - panic!("expected espanso binary, found none in {:?}", exec_file); - } - std::fs::copy(exec_file, target_dir.join("espansod.exe")); - - // Create the CLI wrapper - std::fs::write(target_dir.join("espanso.cmd"), r#"@"%~dp0espansod.exe" %*"#).unwrap(); + // Copy all the resources + fs_extra::dir::copy(&resources_dir, &target_dir, &fs_extra::dir::CopyOptions { + content_only: true, + ..Default::default() + }).expect("unable to copy resources"); // Create the launcher std::fs::write(target_dir.join("START_ESPANSO.bat"), r#"start espansod.exe launcher"#).unwrap(); diff --git a/scripts/build_windows_resources.rs b/scripts/build_windows_resources.rs new file mode 100644 index 0000000..0c11750 --- /dev/null +++ b/scripts/build_windows_resources.rs @@ -0,0 +1,76 @@ +//! ```cargo +//! [dependencies] +//! cc = "1.0.66" +//! glob = "0.3.0" +//! envmnt = "*" +//! ``` + +use std::path::PathBuf; + +const TARGET_DIR: &str = "target/windows/resources"; + +fn main() { + // Clean the target directory + let _ = std::fs::remove_dir_all(TARGET_DIR); + // Create the target directory + std::fs::create_dir_all(TARGET_DIR).expect("unable to create target directory"); + let target_dir = PathBuf::from(TARGET_DIR); + if !target_dir.is_dir() { + panic!("expected target directory, found none"); + } + + // We first need to find all the DLLs to redistribute with the binary + // These are found inside the MSVC compiler directory, usually in a place like: + // C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Redist\MSVC\14.28.29910\x64\Microsoft.VC142.CRT + // and they include files like vcruntime140.dll and msvcp140.dll + + // First, we try to find the directory containing the various versions: + // C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Redist\MSVC\ + let tool = cc::windows_registry::find_tool("msvc", "msbuild") + .expect("unable to locate MSVC compiler, did you install Visual Studio?"); + let mut versions_dir = None; + let mut current_root = tool.path(); + while let Some(parent) = current_root.parent() { + let target = parent.join("VC").join("Redist").join("MSVC"); + if target.exists() { + versions_dir = Some(target); + break; + } + current_root = parent; + } + let versions_dir = versions_dir.expect( + r"unable to find path: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Redist\MSVC", + ); + + // Then we try to find a suitable directory containing the required DLLs + // C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Redist\MSVC\14.28.29910\x64\Microsoft.VC142.CRT + let glob_pattern = format!( + r"{}\*\x64\Microsoft.*\vcruntime140_1.dll", + versions_dir.to_string_lossy().to_string() + ); + println!("glob_pattern: {}", glob_pattern); + let target_file = glob::glob(&glob_pattern) + .expect("failed to read glob pattern") + .next() + .expect("unable to find vcruntime140_1.dll file") + .expect("unable to extract path of vcruntime140_1.dll file"); + + // Copy the DLLs in the target directory + let parent_dir = target_file.parent().expect("unable to obtain directory containing DLLs"); + for entry in glob::glob(&format!(r"{}\*.dll", parent_dir.to_string_lossy().to_string())).expect("unable to glob over DLLs") { + let entry = entry.expect("unable to unwrap DLL entry"); + let filename = entry.file_name().expect("unable to obtain filename"); + std::fs::copy(&entry, target_dir.join(filename)).expect("unable to copy DLL"); + } + + // Copy the executable + let exec_path = envmnt::get_or_panic("EXEC_PATH"); + let exec_file = PathBuf::from(&format!("{}.exe", exec_path)); + if !exec_file.is_file() { + panic!("expected espanso binary, found none in {:?}", exec_file); + } + std::fs::copy(exec_file, target_dir.join("espansod.exe")).unwrap(); + + // Create the CLI wrapper + std::fs::write(target_dir.join("espanso.cmd"), r#"@"%~dp0espansod.exe" %*"#).unwrap(); +}