1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-22 22:42:48 +03:00
wezterm/wezterm-gui/build.rs

186 lines
6.3 KiB
Rust
Raw Normal View History

fn main() {
println!("cargo:rerun-if-changed=build.rs");
#[cfg(windows)]
{
use anyhow::Context as _;
use std::io::Write;
2020-10-02 21:50:50 +03:00
use std::path::Path;
let profile = std::env::var("PROFILE").unwrap();
2020-10-06 03:13:50 +03:00
let repo_dir = std::env::current_dir()
.ok()
.and_then(|cwd| cwd.parent().map(|p| p.to_path_buf()))
.unwrap();
let exe_output_dir = repo_dir.join("target").join(profile);
let windows_dir = repo_dir.join("assets").join("windows");
Windows: prefer to use Direct3D11 via ANGLE This is similar in spirit to the work in 4d71a7913a2ed6461b46a59e77d532ba5ae2a7a2 but for Windows. This commit adds ANGLE binaries built from https://chromium.googlesource.com/angle/angle/+/07ea804e620132517b6af0ef92fe85ea737d0c27 to the repo. The build and packaging will copy those into the same directory as wezterm.exe so that they can be resolved at runtime. By default, `prefer_egl = true`, which will cause the window crate to first try to load an EGL implementation. If that fails, or if `prefer_egl = false`, then the window crate will perform the usual WGL initialization. The practical effect of this change is that Direct3D11 is used for the underlying render, which avoids problematic OpenGL drivers and means that the process can survive graphics drivers being updated. It may also increase the chances that the GPU will really be used in an RDP session rather than the pessimised use of the software renderer. The one downside that I've noticed is that the resize behavior feels a little janky in comparison to WGL (frames can render with mismatched surface/window sizes which makes the window contents feel like they're zooming/rippling slightly as the window is live resized). I think this is specific to the ANGLE D3D implementation as EGL on other platforms feels more solid. I'm a little on the fence about making this the default; I think it makes sense to prefer something that won't quit unexpectedly while a software update is in progress, so that's a strong plus in favor of EGL as the default, but I'm not sure how much the resize wobble is going to set people off. If you prefer WGL and are fine with the risk of a drive update killing wezterm, then you can set this in your config: ```lua return { prefer_egl = false, } ``` refs: https://github.com/wez/wezterm/issues/265 closes: https://github.com/wez/wezterm/issues/156
2020-10-18 05:08:16 +03:00
let conhost_dir = windows_dir.join("conhost");
for name in &["conpty.dll", "OpenConsole.exe"] {
let dest_name = exe_output_dir.join(name);
let src_name = conhost_dir.join(name);
if !dest_name.exists() {
std::fs::copy(&src_name, &dest_name)
.context(format!(
"copy {} -> {}",
src_name.display(),
dest_name.display()
))
.unwrap();
}
}
Windows: prefer to use Direct3D11 via ANGLE This is similar in spirit to the work in 4d71a7913a2ed6461b46a59e77d532ba5ae2a7a2 but for Windows. This commit adds ANGLE binaries built from https://chromium.googlesource.com/angle/angle/+/07ea804e620132517b6af0ef92fe85ea737d0c27 to the repo. The build and packaging will copy those into the same directory as wezterm.exe so that they can be resolved at runtime. By default, `prefer_egl = true`, which will cause the window crate to first try to load an EGL implementation. If that fails, or if `prefer_egl = false`, then the window crate will perform the usual WGL initialization. The practical effect of this change is that Direct3D11 is used for the underlying render, which avoids problematic OpenGL drivers and means that the process can survive graphics drivers being updated. It may also increase the chances that the GPU will really be used in an RDP session rather than the pessimised use of the software renderer. The one downside that I've noticed is that the resize behavior feels a little janky in comparison to WGL (frames can render with mismatched surface/window sizes which makes the window contents feel like they're zooming/rippling slightly as the window is live resized). I think this is specific to the ANGLE D3D implementation as EGL on other platforms feels more solid. I'm a little on the fence about making this the default; I think it makes sense to prefer something that won't quit unexpectedly while a software update is in progress, so that's a strong plus in favor of EGL as the default, but I'm not sure how much the resize wobble is going to set people off. If you prefer WGL and are fine with the risk of a drive update killing wezterm, then you can set this in your config: ```lua return { prefer_egl = false, } ``` refs: https://github.com/wez/wezterm/issues/265 closes: https://github.com/wez/wezterm/issues/156
2020-10-18 05:08:16 +03:00
let angle_dir = windows_dir.join("angle");
for name in &["libEGL.dll", "libGLESv2.dll"] {
let dest_name = exe_output_dir.join(name);
let src_name = angle_dir.join(name);
if !dest_name.exists() {
std::fs::copy(&src_name, &dest_name)
.context(format!(
"copy {} -> {}",
src_name.display(),
dest_name.display()
))
.unwrap();
}
}
{
let dest_mesa = exe_output_dir.join("mesa");
let _ = std::fs::create_dir(&dest_mesa);
let dest_name = dest_mesa.join("opengl32.dll");
let src_name = windows_dir.join("mesa").join("opengl32.dll");
if !dest_name.exists() {
std::fs::copy(&src_name, &dest_name)
.context(format!(
"copy {} -> {}",
src_name.display(),
dest_name.display()
))
.unwrap();
}
}
2020-10-02 21:50:50 +03:00
// If a file named `.tag` is present, we'll take its contents for the
// version number that we report in wezterm -h.
let mut ci_tag = String::new();
if let Ok(tag) = std::fs::read("../.tag") {
if let Ok(s) = String::from_utf8(tag) {
ci_tag = s.trim().to_string();
println!("cargo:rerun-if-changed=../.tag");
2020-10-02 21:50:50 +03:00
}
}
let version = if ci_tag.is_empty() {
let mut cmd = std::process::Command::new("git");
cmd.args(&[
"-c",
"core.abbrev=8",
"show",
"-s",
"--format=%cd-%h",
"--date=format:%Y%m%d-%H%M%S",
]);
if let Ok(output) = cmd.output() {
if output.status.success() {
String::from_utf8_lossy(&output.stdout).trim().to_owned()
} else {
"UNKNOWN".to_owned()
}
} else {
"UNKNOWN".to_owned()
}
} else {
ci_tag
};
let rcfile_name = Path::new(&std::env::var_os("OUT_DIR").unwrap()).join("resource.rc");
let mut rcfile = std::fs::File::create(&rcfile_name).unwrap();
println!("cargo:rerun-if-changed=../assets/windows/terminal.ico");
write!(
rcfile,
r#"
#include <winres.h>
// This ID is coupled with code in window/src/os/windows/window.rs
#define IDI_ICON 0x101
1 RT_MANIFEST "{win}\\manifest.manifest"
2020-05-26 02:48:49 +03:00
IDI_ICON ICON "{win}\\terminal.ico"
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,0
PRODUCTVERSION 1,0,0,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
BEGIN
VALUE "CompanyName", "Wez Furlong\0"
VALUE "FileDescription", "WezTerm - Wez's Terminal Emulator\0"
VALUE "FileVersion", "{version}\0"
VALUE "LegalCopyright", "Wez Furlong, MIT licensed\0"
VALUE "InternalName", "\0"
VALUE "OriginalFilename", "\0"
VALUE "ProductName", "WezTerm\0"
VALUE "ProductVersion", "{version}\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END
"#,
2020-05-26 02:48:49 +03:00
win = windows_dir.display().to_string().replace("\\", "\\\\"),
version = version,
)
.unwrap();
drop(rcfile);
// Obtain MSVC environment so that the rc compiler can find the right headers.
// https://github.com/nabijaczleweli/rust-embed-resource/issues/11#issuecomment-603655972
let target = std::env::var("TARGET").unwrap();
if let Some(tool) = cc::windows_registry::find_tool(target.as_str(), "cl.exe") {
for (key, value) in tool.env() {
std::env::set_var(key, value);
}
}
embed_resource::compile(rcfile_name);
}
#[cfg(target_os = "macos")]
{
use anyhow::Context as _;
let profile = std::env::var("PROFILE").unwrap();
let repo_dir = std::env::current_dir()
.ok()
.and_then(|cwd| cwd.parent().map(|p| p.to_path_buf()))
.unwrap();
// We need to copy the plist to avoid the UNUserNotificationCenter asserting
// due to not finding the application bundle
let src_plist = repo_dir
.join("assets")
.join("macos")
.join("WezTerm.app")
.join("Contents")
.join("Info.plist");
let build_target_dir = std::env::var("CARGO_TARGET_DIR")
.and_then(|s| Ok(std::path::PathBuf::from(s)))
.unwrap_or(repo_dir.join("target").join(profile));
let dest_plist = build_target_dir.join("Info.plist");
println!("cargo:rerun-if-changed=assets/macos/WezTerm.app/Contents/Info.plist");
std::fs::copy(&src_plist, &dest_plist)
.context(format!(
"copy {} -> {}",
src_plist.display(),
dest_plist.display()
))
.unwrap();
}
}