mirror of
https://github.com/enso-org/enso.git
synced 2024-12-30 00:51:52 +03:00
a4f56e92aa
This PR introduces a new installer and uninstaller for the Windows platform. Both are written in Rust and compiled to a single executable. The executable has no dependencies (other than what is included in the Windows), links the C++ runtime statically if needed. The change is motivated by numerous issues with with the `electron-builder`-generated installers. The new installer should behave better, not have issues with long paths and unblock the `electron-builder` upgrade (which will significantly simplify the workflow definitions). To build an installer, one needs to provide the unpacked application (generated by `electron-builder`) and the `electron-builder` configuration (with a few minor extensions). Code signing is also supported.
94 lines
3.5 KiB
Rust
94 lines
3.5 KiB
Rust
//! The build script of crate that is dependency of both the installer and the uninstaller.
|
|
//!
|
|
//! Currently, it is used to include the resources (icons, manifests, version information) into the
|
|
//! installer and uninstaller binaries.
|
|
|
|
use enso_install_config::prelude::*;
|
|
|
|
use enso_install_config::embed_resource_from_file;
|
|
use enso_install_config::sanitize_and_expose_electron_builder_config;
|
|
use enso_install_config::ResourceType;
|
|
use enso_install_config::ENSO_ICON_ID;
|
|
use ide_ci::programs::cargo::build_env::OUT_DIR;
|
|
|
|
|
|
|
|
/// Build-script-time function that tries to embed the icon into the binary.
|
|
///
|
|
/// Works only on Windows, on other platforms this is effectively a no-op.
|
|
fn try_embedding_icon() -> Result {
|
|
let config = enso_install_config::electron_builder_config_from_env()?;
|
|
embed_resource_from_file(ENSO_ICON_ID, ResourceType::Icon, &config.win.icon)
|
|
}
|
|
|
|
fn main() {
|
|
setup_logging().ok();
|
|
// Ignore error, not compiling the icon is not a big deal, especially if we compile to check, to
|
|
// not generate final package. (Obtaining icon is a bit of a hassle, as it is generated
|
|
// temporarily by the enso-build.)
|
|
if let Err(err) = try_embedding_icon() {
|
|
// We do not use `cargo:warning` here, as we do not want to pollute the output if the icon
|
|
// is not available. Still, to enable debugging, we print to stderr, which is captured by
|
|
// the cargo and stored in `target/debug/build/<pkg>/output`.
|
|
eprintln!("Failed to embed icon: {err:?}");
|
|
}
|
|
|
|
let config = sanitize_and_expose_electron_builder_config();
|
|
if let Ok(config) = config {
|
|
// Content on the rc file with the version information.
|
|
let version_rc = format!(
|
|
r#"
|
|
#include "winres.h"
|
|
#define IDS_VERSION_INFO 1
|
|
|
|
VS_VERSION_INFO VERSIONINFO
|
|
FILEVERSION {major},{minor},{patch},0
|
|
PRODUCTVERSION {major},{minor},{patch},0
|
|
FILEOS 0x4
|
|
FILETYPE 0x1
|
|
BEGIN
|
|
BLOCK "StringFileInfo"
|
|
BEGIN
|
|
BLOCK "040904e4"
|
|
BEGIN
|
|
VALUE "CompanyName", "{company}"
|
|
VALUE "FileVersion", "{version}"
|
|
VALUE "LegalCopyright", "{copyright}"
|
|
VALUE "ProductName", "{name}"
|
|
VALUE "ProductVersion", "{version}"
|
|
END
|
|
END
|
|
BLOCK "VarFileInfo"
|
|
BEGIN
|
|
VALUE "Translation", 0x409, 1252
|
|
END
|
|
END
|
|
"#,
|
|
major = config.extra_metadata.version.major,
|
|
minor = config.extra_metadata.version.minor,
|
|
patch = config.extra_metadata.version.patch,
|
|
company = config.copyright,
|
|
name = config.product_name,
|
|
version = config.extra_metadata.version,
|
|
copyright = config.copyright
|
|
);
|
|
let path = OUT_DIR.get().unwrap().join("version.rc");
|
|
ide_ci::fs::write_if_different(&path, version_rc).unwrap();
|
|
embed_resource::compile(&path, embed_resource::NONE);
|
|
}
|
|
|
|
// Embed the manifest file.
|
|
// Necessary to avoid the issue with `GetWindowSubclass`. See:
|
|
// * https://github.com/gabdube/native-windows-gui/issues/251
|
|
// * https://github.com/microsoft/windows-rs/issues/1294
|
|
let manifest_path = Path::new("enso-install.manifest");
|
|
assert!(manifest_path.exists(), "Manifest file does not exist: {}", manifest_path.display());
|
|
let rc_path = OUT_DIR.get().unwrap().join("manifest.rc");
|
|
ide_ci::fs::write_if_different(
|
|
&rc_path,
|
|
format!("#define RT_MANIFEST 24\n1 RT_MANIFEST \"{}\"", manifest_path.display()),
|
|
)
|
|
.unwrap();
|
|
embed_resource::compile(&rc_path, embed_resource::NONE);
|
|
}
|