mirror of
https://github.com/zed-industries/zed.git
synced 2026-05-24 21:59:04 +00:00
Fix Windows icon resource for bin zed.exe (#54738)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
## Summary Fixes the missing Windows icon and version resource metadata for the executable installed as `bin\zed.exe`. On Windows, the bundling process builds `cli.exe` and installs it as `bin\zed.exe`. The root `Zed.exe` already embeds the Zed Windows icon and version metadata through `crates/zed/build.rs`, but the CLI executable did not embed equivalent Windows resources. As a result, Windows integrations that discover or display Zed through `bin\zed.exe` may show a missing/default application icon. This change adds Windows resource embedding to the `cli` crate and uses the same release-channel icon selection as the main Zed executable. Fixes #51154 ## Testing - Built the Windows CLI executable: ```powershell cargo build --release --package cli --target x86_64-pc-windows-msvc --locked --offline ``` - Verified `target\x86_64-pc-windows-msvc\release\cli.exe` contains: - `FileDescription = Zed` - `ProductName = Zed` - Verified the executable displays the Zed icon in Windows Explorer. - Confirmed the Windows bundling script installs `cli.exe` as `bin\zed.exe`. - Started a full Windows bundle build and confirmed it passed license generation and progressed into executable builds. The local full bundle build could not be completed because the machine is missing the VS Spectre-mitigated C++ libraries. ## Release Notes - N/A ## Notes This change is limited to Windows executable resource metadata for the CLI binary. It does not change Zed runtime behavior. --------- Co-authored-by: John Tur <john-tur@outlook.com>
This commit is contained in:
parent
1581a08c49
commit
9155bf4e17
12 changed files with 173 additions and 42 deletions
12
Cargo.lock
generated
12
Cargo.lock
generated
|
|
@ -1268,7 +1268,7 @@ dependencies = [
|
|||
"simplelog",
|
||||
"tempfile",
|
||||
"windows 0.61.3",
|
||||
"winresource",
|
||||
"windows_resources",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2946,6 +2946,7 @@ dependencies = [
|
|||
"util",
|
||||
"walkdir",
|
||||
"windows 0.61.3",
|
||||
"windows_resources",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -21417,6 +21418,13 @@ version = "0.53.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
|
||||
|
||||
[[package]]
|
||||
name = "windows_resources"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"embed-resource",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
|
|
@ -22512,7 +22520,7 @@ dependencies = [
|
|||
"web_search_providers",
|
||||
"which_key",
|
||||
"windows 0.61.3",
|
||||
"winresource",
|
||||
"windows_resources",
|
||||
"workspace",
|
||||
"zed-reqwest",
|
||||
"zed_actions",
|
||||
|
|
|
|||
|
|
@ -225,6 +225,7 @@ members = [
|
|||
"crates/x_ai",
|
||||
"crates/zed",
|
||||
"crates/zed_actions",
|
||||
"crates/windows_resources",
|
||||
"crates/zed_credentials_provider",
|
||||
"crates/zed_env_vars",
|
||||
"crates/zeta_prompt",
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ windows.workspace = true
|
|||
[target.'cfg(target_os = "windows")'.dev-dependencies]
|
||||
tempfile.workspace = true
|
||||
|
||||
[target.'cfg(target_os = "windows")'.build-dependencies]
|
||||
winresource = "0.1"
|
||||
[build-dependencies]
|
||||
windows_resources = { path = "../windows_resources" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-pc-windows-msvc"]
|
||||
|
|
|
|||
|
|
@ -1,15 +1,9 @@
|
|||
fn main() {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
println!("cargo:rerun-if-changed=manifest.xml");
|
||||
println!("cargo:rerun-if-env-changed=RELEASE_CHANNEL");
|
||||
println!("cargo:rerun-if-env-changed=GITHUB_RUN_NUMBER");
|
||||
|
||||
let mut res = winresource::WindowsResource::new();
|
||||
res.set_manifest_file("manifest.xml");
|
||||
res.set_icon("app-icon.ico");
|
||||
|
||||
if let Err(e) = res.compile() {
|
||||
eprintln!("{}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
windows_resources::compile(true).expect("failed to compile Windows resources");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,3 +52,6 @@ plist = "1.3"
|
|||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
windows.workspace = true
|
||||
|
||||
[build-dependencies]
|
||||
windows_resources = { path = "../windows_resources" }
|
||||
|
|
|
|||
|
|
@ -26,4 +26,12 @@ fn main() {
|
|||
if let Some(build_identifier) = option_env!("GITHUB_RUN_NUMBER") {
|
||||
println!("cargo:rustc-env=ZED_BUILD_ID={build_identifier}");
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
println!("cargo:rerun-if-env-changed=RELEASE_CHANNEL");
|
||||
println!("cargo:rerun-if-env-changed=GITHUB_RUN_NUMBER");
|
||||
|
||||
windows_resources::compile(false).expect("failed to compile Windows resources");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
16
crates/windows_resources/Cargo.toml
Normal file
16
crates/windows_resources/Cargo.toml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
[package]
|
||||
name = "windows_resources"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
publish.workspace = true
|
||||
license = "GPL-3.0-or-later"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[lib]
|
||||
path = "src/windows_resources.rs"
|
||||
doctest = false
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
embed-resource = "3.0"
|
||||
1
crates/windows_resources/LICENSE-GPL
Symbolic link
1
crates/windows_resources/LICENSE-GPL
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../LICENSE-GPL
|
||||
125
crates/windows_resources/src/windows_resources.rs
Normal file
125
crates/windows_resources/src/windows_resources.rs
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
#![allow(
|
||||
clippy::disallowed_methods,
|
||||
reason = "build helper used only from build scripts"
|
||||
)]
|
||||
#![cfg(target_os = "windows")]
|
||||
|
||||
use std::process::Command;
|
||||
|
||||
fn git_sha() -> Option<String> {
|
||||
if let Ok(sha) = std::env::var("ZED_COMMIT_SHA") {
|
||||
return Some(sha);
|
||||
}
|
||||
|
||||
Command::new("git")
|
||||
.args(["rev-parse", "HEAD"])
|
||||
.output()
|
||||
.ok()
|
||||
.filter(|output| output.status.success())
|
||||
.map(|output| String::from_utf8_lossy(&output.stdout).trim().to_string())
|
||||
}
|
||||
|
||||
fn product_version() -> String {
|
||||
let commit_sha = git_sha();
|
||||
let pkg_version = std::env::var("CARGO_PKG_VERSION").unwrap_or_default();
|
||||
let channel = std::env::var("RELEASE_CHANNEL").unwrap_or_else(|_| "dev".into());
|
||||
let build_id = std::env::var("GITHUB_RUN_NUMBER").ok();
|
||||
|
||||
let mut metadata = channel;
|
||||
if let Some(build_id) = &build_id {
|
||||
metadata.push('.');
|
||||
metadata.push_str(build_id);
|
||||
}
|
||||
if let Some(sha) = &commit_sha {
|
||||
metadata.push('.');
|
||||
metadata.push_str(sha);
|
||||
}
|
||||
|
||||
format!("{pkg_version}+{metadata}")
|
||||
}
|
||||
|
||||
const ICON_DIR: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../zed/resources/windows");
|
||||
const MANIFEST_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/resources/manifest.xml");
|
||||
|
||||
pub fn compile(manifest: bool) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let channel = option_env!("RELEASE_CHANNEL").unwrap_or("dev");
|
||||
let (icon_filename, product_name) = match channel {
|
||||
"stable" => ("app-icon.ico", "Zed"),
|
||||
"preview" => ("app-icon-preview.ico", "Zed Preview"),
|
||||
"nightly" => ("app-icon-nightly.ico", "Zed Nightly"),
|
||||
_ => ("app-icon-dev.ico", "Zed Dev"),
|
||||
};
|
||||
let icon = std::path::PathBuf::from(ICON_DIR).join(icon_filename);
|
||||
let icon_escaped = icon.to_string_lossy().replace('\\', "\\\\");
|
||||
|
||||
let manifest_line = if manifest {
|
||||
let escaped = MANIFEST_PATH.replace('\\', "\\\\");
|
||||
format!("1 24 \"{escaped}\"")
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
let pkg_version = std::env::var("CARGO_PKG_VERSION").unwrap_or_default();
|
||||
let product_version = product_version();
|
||||
let mut version_parts = pkg_version
|
||||
.split('.')
|
||||
.map(|part| part.parse::<u16>().unwrap_or(0))
|
||||
.chain(std::iter::repeat(0));
|
||||
let file_version = format!(
|
||||
"{},{},{},{}",
|
||||
version_parts.next().unwrap_or(0),
|
||||
version_parts.next().unwrap_or(0),
|
||||
version_parts.next().unwrap_or(0),
|
||||
version_parts.next().unwrap_or(0),
|
||||
);
|
||||
|
||||
let rc_content = format!(
|
||||
r#"1 ICON "{icon_escaped}"
|
||||
{manifest_line}
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION {file_version}
|
||||
PRODUCTVERSION {file_version}
|
||||
FILEFLAGSMASK 0x3fL
|
||||
FILEFLAGS 0x0L
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "FileDescription", "{product_name}\0"
|
||||
VALUE "FileVersion", "{pkg_version}\0"
|
||||
VALUE "ProductName", "{product_name}\0"
|
||||
VALUE "ProductVersion", "{product_version}\0"
|
||||
VALUE "CompanyName", "Zed Industries, Inc.\0"
|
||||
VALUE "LegalCopyright", "Copyright 2022 - 2025 Zed Industries, Inc.\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x0409, 1200
|
||||
END
|
||||
END
|
||||
"#
|
||||
);
|
||||
|
||||
let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR")?);
|
||||
let rc_path = out_dir.join("zed_resources.rc");
|
||||
std::fs::write(&rc_path, rc_content)?;
|
||||
|
||||
if let Ok(toolkit_path) = std::env::var("ZED_RC_TOOLKIT_PATH") {
|
||||
let rc_exe = std::path::Path::new(&toolkit_path).join("rc.exe");
|
||||
unsafe {
|
||||
std::env::set_var("RC", rc_exe);
|
||||
}
|
||||
}
|
||||
|
||||
embed_resource::compile(&rc_path, embed_resource::NONE)
|
||||
.manifest_optional()
|
||||
.unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -233,8 +233,8 @@ gpui = { workspace = true, features = [
|
|||
"windows-manifest",
|
||||
] }
|
||||
|
||||
[target.'cfg(target_os = "windows")'.build-dependencies]
|
||||
winresource = "0.1"
|
||||
[build-dependencies]
|
||||
windows_resources = { path = "../windows_resources" }
|
||||
|
||||
[target.'cfg(any(target_os = "linux", target_os = "freebsd"))'.dependencies]
|
||||
gpui = { workspace = true, features = [
|
||||
|
|
|
|||
|
|
@ -202,37 +202,12 @@ fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
let release_channel = option_env!("RELEASE_CHANNEL").unwrap_or("dev");
|
||||
let icon = match release_channel {
|
||||
"stable" => "resources/windows/app-icon.ico",
|
||||
"preview" => "resources/windows/app-icon-preview.ico",
|
||||
"nightly" => "resources/windows/app-icon-nightly.ico",
|
||||
"dev" => "resources/windows/app-icon-dev.ico",
|
||||
_ => "resources/windows/app-icon-dev.ico",
|
||||
};
|
||||
let icon = std::path::Path::new(icon);
|
||||
|
||||
println!("cargo:rerun-if-env-changed=RELEASE_CHANNEL");
|
||||
println!("cargo:rerun-if-changed={}", icon.display());
|
||||
println!("cargo:rerun-if-env-changed=GITHUB_RUN_NUMBER");
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
let mut res = winresource::WindowsResource::new();
|
||||
|
||||
// Depending on the security applied to the computer, winresource might fail
|
||||
// fetching the RC path. Therefore, we add a way to explicitly specify the
|
||||
// toolkit path, allowing winresource to use a valid RC path.
|
||||
if let Some(explicit_rc_toolkit_path) = std::env::var("ZED_RC_TOOLKIT_PATH").ok() {
|
||||
res.set_toolkit_path(explicit_rc_toolkit_path.as_str());
|
||||
}
|
||||
res.set_icon(icon.to_str().unwrap());
|
||||
res.set("FileDescription", "Zed");
|
||||
res.set("ProductName", "Zed");
|
||||
|
||||
if let Err(e) = res.compile() {
|
||||
eprintln!("{}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
windows_resources::compile(false).expect("failed to compile Windows resources");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue