summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJasperVanEsveld <J.M.vanEsveld@student.tudelft.nl>2023-07-28 17:46:26 +0200
committerGitHub <noreply@github.com>2023-07-28 18:46:26 +0300
commit0ec4feaee7a2dd442fc8955036999b550c9959ac (patch)
tree0ed00be3167c9b73ae7ad5ea60f44e3209cd9dd6
parenta9951e360cf9937c84bb884ccfefbbd304b401e3 (diff)
feat(compile): Add `--no-terminal` to compile command (#17991)
-rw-r--r--cli/args/flags.rs13
-rw-r--r--cli/standalone/binary.rs58
-rw-r--r--cli/tools/compile.rs2
3 files changed, 71 insertions, 2 deletions
diff --git a/cli/args/flags.rs b/cli/args/flags.rs
index 3f4498dac..c80b2cdbc 100644
--- a/cli/args/flags.rs
+++ b/cli/args/flags.rs
@@ -64,6 +64,7 @@ pub struct CompileFlags {
pub output: Option<PathBuf>,
pub args: Vec<String>,
pub target: Option<String>,
+ pub no_terminal: bool,
pub include: Vec<String>,
}
@@ -1031,6 +1032,12 @@ supported in canary.
"aarch64-apple-darwin",
]),
)
+ .arg(
+ Arg::new("no-terminal")
+ .long("no-terminal")
+ .help("Hide terminal on Windows")
+ .action(ArgAction::SetTrue),
+ )
.arg(executable_ext_arg())
})
}
@@ -2645,6 +2652,7 @@ fn compile_parse(flags: &mut Flags, matches: &mut ArgMatches) {
let args = script.collect();
let output = matches.remove_one::<PathBuf>("output");
let target = matches.remove_one::<String>("target");
+ let no_terminal = matches.get_flag("no-terminal");
let include = match matches.remove_many::<String>("include") {
Some(f) => f.collect(),
None => vec![],
@@ -2656,6 +2664,7 @@ fn compile_parse(flags: &mut Flags, matches: &mut ArgMatches) {
output,
args,
target,
+ no_terminal,
include,
});
}
@@ -6508,6 +6517,7 @@ mod tests {
output: None,
args: vec![],
target: None,
+ no_terminal: false,
include: vec![]
}),
type_check_mode: TypeCheckMode::Local,
@@ -6519,7 +6529,7 @@ mod tests {
#[test]
fn compile_with_flags() {
#[rustfmt::skip]
- let r = flags_from_vec(svec!["deno", "compile", "--import-map", "import_map.json", "--no-remote", "--config", "tsconfig.json", "--no-check", "--unsafely-ignore-certificate-errors", "--reload", "--lock", "lock.json", "--lock-write", "--cert", "example.crt", "--cached-only", "--location", "https:foo", "--allow-read", "--allow-net", "--v8-flags=--help", "--seed", "1", "--output", "colors", "https://deno.land/std/examples/colors.ts", "foo", "bar"]);
+ let r = flags_from_vec(svec!["deno", "compile", "--import-map", "import_map.json", "--no-remote", "--config", "tsconfig.json", "--no-check", "--unsafely-ignore-certificate-errors", "--reload", "--lock", "lock.json", "--lock-write", "--cert", "example.crt", "--cached-only", "--location", "https:foo", "--allow-read", "--allow-net", "--v8-flags=--help", "--seed", "1", "--no-terminal", "--output", "colors", "https://deno.land/std/examples/colors.ts", "foo", "bar"]);
assert_eq!(
r.unwrap(),
Flags {
@@ -6528,6 +6538,7 @@ mod tests {
output: Some(PathBuf::from("colors")),
args: svec!["foo", "bar"],
target: None,
+ no_terminal: true,
include: vec![]
}),
import_map_path: Some("import_map.json".to_string()),
diff --git a/cli/standalone/binary.rs b/cli/standalone/binary.rs
index a2fe7e916..4d964215c 100644
--- a/cli/standalone/binary.rs
+++ b/cli/standalone/binary.rs
@@ -1,6 +1,7 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use std::collections::BTreeMap;
+use std::env::consts;
use std::env::current_exe;
use std::io::Read;
use std::io::Seek;
@@ -10,6 +11,7 @@ use std::path::Path;
use std::path::PathBuf;
use deno_ast::ModuleSpecifier;
+use deno_core::anyhow::bail;
use deno_core::anyhow::Context;
use deno_core::error::AnyError;
use deno_core::futures::io::AllowStdIo;
@@ -383,9 +385,24 @@ impl<'a> DenoCompileBinaryWriter<'a> {
cli_options: &CliOptions,
) -> Result<(), AnyError> {
// Select base binary based on target
- let original_binary =
+ let mut original_binary =
self.get_base_binary(compile_flags.target.clone()).await?;
+ let target = compile_flags
+ .target
+ .clone()
+ .unwrap_or(consts::OS.to_string());
+
+ if compile_flags.no_terminal {
+ if target != "x86_64-pc-windows-msvc" && target != "windows" {
+ println!("{}", target);
+ bail!(
+ "The `--no-terminal` flag is only available when targeting Windows"
+ )
+ }
+ set_windows_binary_to_gui(&mut original_binary)?;
+ }
+
self
.write_standalone_binary(
writer,
@@ -559,3 +576,42 @@ impl<'a> DenoCompileBinaryWriter<'a> {
}
}
}
+
+/// This function sets the subsystem field in the PE header to 2 (GUI subsystem)
+/// For more information about the PE header: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format
+fn set_windows_binary_to_gui(bin: &mut [u8]) -> Result<(), AnyError> {
+ // Get the PE header offset located in an i32 found at offset 60
+ // See: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#ms-dos-stub-image-only
+ let start_pe = u32::from_le_bytes((bin[60..64]).try_into()?);
+
+ // Get image type (PE32 or PE32+) indicates whether the binary is 32 or 64 bit
+ // The used offset and size values can be found here:
+ // https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#optional-header-image-only
+ let start_32 = start_pe as usize + 28;
+ let magic_32 =
+ u16::from_le_bytes(bin[(start_32)..(start_32 + 2)].try_into()?);
+
+ let start_64 = start_pe as usize + 24;
+ let magic_64 =
+ u16::from_le_bytes(bin[(start_64)..(start_64 + 2)].try_into()?);
+
+ // Take the standard fields size for the current architecture (32 or 64 bit)
+ // This is the ofset for the Windows-Specific fields
+ let standard_fields_size = if magic_32 == 0x10b {
+ 28
+ } else if magic_64 == 0x20b {
+ 24
+ } else {
+ bail!("Could not find a matching magic field in the PE header")
+ };
+
+ // Set the subsystem field (offset 68) to 2 (GUI subsystem)
+ // For all possible options, see: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#optional-header-windows-specific-fields-image-only
+ let subsystem_offset = 68;
+ let subsystem_start =
+ start_pe as usize + standard_fields_size + subsystem_offset;
+ let subsystem: u16 = 2;
+ bin[(subsystem_start)..(subsystem_start + 2)]
+ .copy_from_slice(&subsystem.to_le_bytes());
+ Ok(())
+}
diff --git a/cli/tools/compile.rs b/cli/tools/compile.rs
index c53ae4e02..d925b0ea3 100644
--- a/cli/tools/compile.rs
+++ b/cli/tools/compile.rs
@@ -212,6 +212,7 @@ mod test {
output: Some(PathBuf::from("./file")),
args: Vec::new(),
target: Some("x86_64-unknown-linux-gnu".to_string()),
+ no_terminal: false,
include: vec![],
},
&std::env::current_dir().unwrap(),
@@ -234,6 +235,7 @@ mod test {
args: Vec::new(),
target: Some("x86_64-pc-windows-msvc".to_string()),
include: vec![],
+ no_terminal: false,
},
&std::env::current_dir().unwrap(),
)