summaryrefslogtreecommitdiffhomepage
path: root/windows-installer/build.rs
blob: df3855e1096e38143edcf3679e8fa0484a756e36 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
use anyhow::Context;
use std::{io, path::Path};

const IDB_X64EXE: usize = 1;
const IDB_ARM64EXE: usize = 2;

fn main() -> anyhow::Result<()> {
    if !std::env::var("TARGET")
        .context("missing TARGET")?
        .as_str()
        .starts_with("x86_64-pc-windows-")
    {
        // This crate only makes sense on x64 Windows
        return Ok(());
    }

    build_resource_rust_header().context("failed to write resource.rs")?;

    let (Ok(x64_installer), Ok(arm64_installer)) = (
        std::env::var("WIN_X64_INSTALLER"),
        std::env::var("WIN_ARM64_INSTALLER"),
    ) else {
        eprintln!("Not building resource.rc - WIN_X64_INSTALLER and WIN_ARM64_INSTALLER not set");
        // Linking must fail if the resource file isn't built
        println!("cargo:rustc-link-lib=dylib=resource");
        return Ok(());
    };

    let mut res = winres::WindowsResource::new();
    res.append_rc_content(&format!(
        r#"
#define IDB_X64EXE {IDB_X64EXE}
#define IDB_ARM64EXE {IDB_ARM64EXE}

IDB_X64EXE BINARY "{x64_installer}"
IDB_ARM64EXE BINARY "{arm64_installer}"
"#
    ));

    res.set("ProductVersion", mullvad_version::VERSION);
    res.set_icon("../dist-assets/icon.ico");
    res.set_language(make_lang_id(
        windows_sys::Win32::System::SystemServices::LANG_ENGLISH as u16,
        windows_sys::Win32::System::SystemServices::SUBLANG_ENGLISH_US as u16,
    ));

    println!("cargo:rerun-if-changed=windows-installer.manifest");
    res.set_manifest_file("windows-installer.manifest");
    res.set("FileDescription", "Mullvad VPN installer");

    res.compile().context("Failed to compile resources")
}

fn build_resource_rust_header() -> io::Result<()> {
    let resource_header = Path::new(&std::env::var("OUT_DIR").unwrap()).join("resource.rs");
    std::fs::write(
        resource_header,
        format!(
            "pub const IDB_X64EXE: usize = {IDB_X64EXE};\n
pub const IDB_ARM64EXE: usize = {IDB_ARM64EXE};\n"
        ),
    )
}

// Sourced from winnt.h: https://learn.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-makelangid
fn make_lang_id(p: u16, s: u16) -> u16 {
    (s << 10) | p
}