diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index b7100c7a..61d4b71a 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -21,6 +21,8 @@ jobs: - run: | nix build .#windows -L cp result/bin/*.exe . + nix build .#codchiw-windows -L + cp result/bin/*.exe . nix build .#store-wsl.config.build.tarball -L cp result store.tar.gz nix build .#machine-wsl.config.build.tarball -L diff --git a/codchi/.msvc_manifest.json b/build/.msvc_manifest.json similarity index 100% rename from codchi/.msvc_manifest.json rename to build/.msvc_manifest.json diff --git a/build/build-rust-package.nix b/build/build-rust-package.nix new file mode 100644 index 00000000..d16a095c --- /dev/null +++ b/build/build-rust-package.nix @@ -0,0 +1,224 @@ +{ self +, runCommand +, runCommandLocal +, runtimeShell +, writeShellScript +, writeShellScriptBin +, fetchFromGitHub + +, lib + +, store-lxd-tarball +, machine-lxd-tarball +, platform + +, makeRustPlatform +, rust-bin + +, makeWrapper +, pkg-config +, gtk3 +, libayatana-appindicator + +, llvmPackages +, cargo-xwin +, wine64 + +, installShellFiles +, pandoc +, ... +}: + +args: + +let + rustConfig = { + extensions = [ + "rust-src" + "rust-analyzer" + ]; + targets = [ + "x86_64-unknown-linux-gnu" + "x86_64-pc-windows-msvc" + "wasm32-wasi" + ]; + }; + # rustOrig = rust-bin.stable.latest.default.override rustConfig; + rustOrig = rust-bin.selectLatestNightlyWith (toolchain: toolchain.default.override rustConfig); + rustPlatformOrig = makeRustPlatform { cargo = rustOrig; rustc = rustOrig; }; + xwin = rustPlatformOrig.buildRustPackage rec { + name = "xwin"; + src = fetchFromGitHub { + owner = "Jake-Shadle"; + repo = "xwin"; + rev = "0.5.0"; + sha256 = "sha256-qHlh1PjEzm8nJW3IemikCaaxLtUCZRQccGQg/DgnJ4k="; + }; + checkPhase = ":"; + cargoLock.lockFile = "${src}/Cargo.lock"; + }; + nix-git = writeShellScriptBin "nix-git-commit" '' + echo ${self.rev or self.dirtyRev or "dirty"} + ''; + + native = { + win = rec { + passthru = { + inherit xwin nix-git; + splatted = runCommand "splat" + { + nativeBuildInputs = [ passthru.xwin ]; + outputHashMode = "recursive"; + outputHashAlgo = "sha256"; + outputHash = "sha256-5ZZeEBuemx+lRmc9PczMfd13JwTvI6qMNvNmHdtK+1U="; + } + '' + mkdir -p $out/xwin + xwin --accept-license --manifest ${./.msvc_manifest.json} splat --output $out/xwin --copy + ''; + + # wrap cargo by checking and injecting xwin where it is needed + rust = (runCommandLocal "cargo-xwinize" { } '' + cp -r ${rustOrig} $out + chmod +w $out/bin + mv $out/bin/cargo $out/bin/.cargo + cat << EOF > $out/bin/cargo + #!${runtimeShell} + case "\$1" in + build|check|clippy|run|rustc|test) + # replace linux target with msvc + if [ -z "\$CARGO_ENCODED_RUSTFLAGS" ]; then + args=() + prev_was_target= + for i in "\$@"; do + if [ -n "\$prev_was_target" ]; then + args+=("${CARGO_BUILD_TARGET}"); + prev_was_target= + continue + fi + case "\$i" in + --target) + prev_was_target=1 + ;; + --) + # duplicate '--' to satisfy xwin test + if [ "\$1" = "test" ]; then + args+=("\$i"); + fi + ;; + esac + args+=("\$i"); + done + exec -a "\$0" $out/bin/.cargo xwin "\''${args[@]}" + fi + ;; + esac + exec -a "\$0" $out/bin/.cargo "\$@" + EOF + chmod +x $out/bin/cargo + '') + // + { inherit (rustOrig) meta; }; + rustPlatform = makeRustPlatform { cargo = passthru.rust; rustc = passthru.rust; }; + + setupXWin = topDir: /* bash */ '' + if [ ! -d "${topDir}" ]; then + mkdir -p "${topDir}" + fi + export WINEPREFIX="${topDir}/.wine" + export XWIN_ARCH="x86_64" + export XWIN_CACHE_DIR="${topDir}/.xwin" + if [ ! -d $XWIN_CACHE_DIR ]; then + mkdir -p $XWIN_CACHE_DIR + cp -r ${passthru.splatted}/xwin $XWIN_CACHE_DIR + chmod -R +w $XWIN_CACHE_DIR + echo "x86_64" > $XWIN_CACHE_DIR/xwin/DONE + fi + ''; + }; + + auditable = false; # disable cargo auditable + + CARGO_BUILD_TARGET = "x86_64-pc-windows-msvc"; + CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_RUNNER = writeShellScript "wine-wsl" '' + if ! command -v /bin/wslpath &> /dev/null; then + ${wine64}/bin/wine64 "$@" + else + "$@" + fi + ''; + + # On Windows MSVC, statically link the C runtime so that the resulting EXE does + # not depend on the vcruntime DLL. + RUSTFLAGS = "-C target-feature=+crt-static"; + + nativeBuildInputs = [ + llvmPackages.llvm + llvmPackages.bintools + llvmPackages.clang + llvmPackages.lld + cargo-xwin + nix-git + pandoc + ]; + + preConfigure = passthru.setupXWin "$(mktemp -d)"; + + installPhase = '' + mkdir -p $out/bin + cp target/${CARGO_BUILD_TARGET}/*/*.exe $out/bin + ''; + + CODCHI_WSL_VERSION_MIN = "2.0.14"; + CODCHI_WSL_VERSION_MAX = "2.3.26"; + + }; + linux = rec { + CARGO_BUILD_TARGET = "x86_64-unknown-linux-gnu"; + + CODCHI_LXD_CONTAINER_STORE = store-lxd-tarball; + CODCHI_LXD_CONTAINER_MACHINE = machine-lxd-tarball; + + passthru = { + inherit xwin nix-git; + rust = rustOrig; + rustPlatform = rustPlatformOrig; + }; + nativeBuildInputs = [ + pkg-config + nix-git + makeWrapper + pandoc + installShellFiles + ]; + buildInputs = [ + gtk3 + libayatana-appindicator.out + ]; + + outputs = [ "out" "docs" ]; + + postInstall = '' + installManPage ./target/codchi/man/* + installShellCompletion --cmd codchi \ + --bash ./target/codchi/completions/codchi.bash \ + --fish ./target/codchi/completions/codchi.fish \ + --zsh ./target/codchi/completions/_codchi + + mkdir -p $docs + cp -r ./target/codchi/md $docs/usage + ''; + + postFixup = '' + patchelf "$out/bin/codchi" \ + --add-rpath ${lib.makeLibraryPath buildInputs} + wrapProgram "$out/bin/codchi" \ + --set CODCHI_LXD_CONTAINER_STORE $CODCHI_LXD_CONTAINER_STORE \ + --set CODCHI_LXD_CONTAINER_MACHINE $CODCHI_LXD_CONTAINER_MACHINE + ''; + }; + }.${platform}; + + +in +native.passthru.rustPlatform.buildRustPackage (lib.recursiveUpdate args native) diff --git a/build/msix/AppxManifest.xml b/build/msix/AppxManifest.xml index 8d8f66e0..64ea17c1 100755 --- a/build/msix/AppxManifest.xml +++ b/build/msix/AppxManifest.xml @@ -51,7 +51,14 @@ - + + + + + + diff --git a/codchi/default.nix b/codchi/default.nix index 4e8c73dc..0034aebc 100644 --- a/codchi/default.nix +++ b/codchi/default.nix @@ -1,226 +1,13 @@ -{ self -, runCommand -, runCommandLocal -, runtimeShell -, writeShellScript -, writeShellScriptBin -, fetchFromGitHub - +{ callPackage , lib - -, store-lxd-tarball -, machine-lxd-tarball +, self , platform - -, makeRustPlatform -, rust-bin - -, makeWrapper -, pkg-config -, gtk3 -, libayatana-appindicator - -, llvmPackages -, cargo-xwin -, wine64 - -, installShellFiles -, pandoc -, ... }: let Cargo = builtins.fromTOML (builtins.readFile ./Cargo.toml); - - rustConfig = { - extensions = [ - "rust-src" - "rust-analyzer" - ]; - targets = [ - "x86_64-unknown-linux-gnu" - "x86_64-pc-windows-msvc" - "wasm32-wasi" - ]; - }; - # rustOrig = rust-bin.stable.latest.default.override rustConfig; - rustOrig = rust-bin.selectLatestNightlyWith (toolchain: toolchain.default.override rustConfig); - rustPlatformOrig = makeRustPlatform { cargo = rustOrig; rustc = rustOrig; }; - xwin = rustPlatformOrig.buildRustPackage rec { - name = "xwin"; - src = fetchFromGitHub { - owner = "Jake-Shadle"; - repo = "xwin"; - rev = "0.5.0"; - sha256 = "sha256-qHlh1PjEzm8nJW3IemikCaaxLtUCZRQccGQg/DgnJ4k="; - }; - checkPhase = ":"; - cargoLock.lockFile = "${src}/Cargo.lock"; - }; - nix-git = writeShellScriptBin "nix-git-commit" '' - echo ${self.rev or self.dirtyRev or "dirty"} - ''; - - native = { - win = rec { - passthru = { - inherit xwin; - splatted = runCommand "splat" - { - nativeBuildInputs = [ passthru.xwin ]; - outputHashMode = "recursive"; - outputHashAlgo = "sha256"; - outputHash = "sha256-5ZZeEBuemx+lRmc9PczMfd13JwTvI6qMNvNmHdtK+1U="; - } - '' - mkdir -p $out/xwin - xwin --accept-license --manifest ${./.msvc_manifest.json} splat --output $out/xwin --copy - ''; - - # wrap cargo by checking and injecting xwin where it is needed - rust = (runCommandLocal "cargo-xwinize" { } '' - cp -r ${rustOrig} $out - chmod +w $out/bin - mv $out/bin/cargo $out/bin/.cargo - cat << EOF > $out/bin/cargo - #!${runtimeShell} - case "\$1" in - build|check|clippy|run|rustc|test) - # replace linux target with msvc - if [ -z "\$CARGO_ENCODED_RUSTFLAGS" ]; then - args=() - prev_was_target= - for i in "\$@"; do - if [ -n "\$prev_was_target" ]; then - args+=("${CARGO_BUILD_TARGET}"); - prev_was_target= - continue - fi - case "\$i" in - --target) - prev_was_target=1 - ;; - --) - # duplicate '--' to satisfy xwin test - if [ "\$1" = "test" ]; then - args+=("\$i"); - fi - ;; - esac - args+=("\$i"); - done - exec -a "\$0" $out/bin/.cargo xwin "\''${args[@]}" - fi - ;; - esac - exec -a "\$0" $out/bin/.cargo "\$@" - EOF - chmod +x $out/bin/cargo - '') - // - { inherit (rustOrig) meta; }; - rustPlatform = makeRustPlatform { cargo = passthru.rust; rustc = passthru.rust; }; - - setupXWin = topDir: /* bash */ '' - if [ ! -d "${topDir}" ]; then - mkdir -p "${topDir}" - fi - export WINEPREFIX="${topDir}/.wine" - export XWIN_ARCH="x86_64" - export XWIN_CACHE_DIR="${topDir}/.xwin" - if [ ! -d $XWIN_CACHE_DIR ]; then - mkdir -p $XWIN_CACHE_DIR - cp -r ${passthru.splatted}/xwin $XWIN_CACHE_DIR - chmod -R +w $XWIN_CACHE_DIR - echo "x86_64" > $XWIN_CACHE_DIR/xwin/DONE - fi - ''; - }; - - auditable = false; # disable cargo auditable - - CARGO_BUILD_TARGET = "x86_64-pc-windows-msvc"; - CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_RUNNER = writeShellScript "wine-wsl" '' - if ! command -v /bin/wslpath &> /dev/null; then - ${wine64}/bin/wine64 "$@" - else - "$@" - fi - ''; - - # On Windows MSVC, statically link the C runtime so that the resulting EXE does - # not depend on the vcruntime DLL. - RUSTFLAGS = "-C target-feature=+crt-static"; - - nativeBuildInputs = [ - llvmPackages.llvm - llvmPackages.bintools - llvmPackages.clang - llvmPackages.lld - cargo-xwin - nix-git - pandoc - ]; - - preConfigure = passthru.setupXWin "$(mktemp -d)"; - - installPhase = '' - mkdir -p $out/bin - cp target/${CARGO_BUILD_TARGET}/*/*.exe $out/bin - ''; - - CODCHI_WSL_VERSION_MIN = "2.0.14"; - CODCHI_WSL_VERSION_MAX = "2.3.26"; - - }; - linux = rec { - CARGO_BUILD_TARGET = "x86_64-unknown-linux-gnu"; - - CODCHI_LXD_CONTAINER_STORE = store-lxd-tarball; - CODCHI_LXD_CONTAINER_MACHINE = machine-lxd-tarball; - - passthru = { - inherit xwin; - rust = rustOrig; - rustPlatform = rustPlatformOrig; - }; - nativeBuildInputs = [ - pkg-config - nix-git - makeWrapper - pandoc - installShellFiles - ]; - buildInputs = [ - gtk3 - libayatana-appindicator.out - ]; - - outputs = [ "out" "docs" ]; - - postInstall = '' - installManPage ./target/codchi/man/* - installShellCompletion --cmd codchi \ - --bash ./target/codchi/completions/codchi.bash \ - --fish ./target/codchi/completions/codchi.fish \ - --zsh ./target/codchi/completions/_codchi - - mkdir -p $docs - cp -r ./target/codchi/md $docs/usage - ''; - - postFixup = '' - patchelf "$out/bin/codchi" \ - --add-rpath ${lib.makeLibraryPath buildInputs} - wrapProgram "$out/bin/codchi" \ - --set CODCHI_LXD_CONTAINER_STORE $CODCHI_LXD_CONTAINER_STORE \ - --set CODCHI_LXD_CONTAINER_MACHINE $CODCHI_LXD_CONTAINER_MACHINE - ''; - }; - }.${platform}; - - in -native.passthru.rustPlatform.buildRustPackage (lib.recursiveUpdate +callPackage ../build/build-rust-package.nix +{ inherit self platform; } { pname = "codchi"; inherit (Cargo.package) version; @@ -229,7 +16,6 @@ native.passthru.rustPlatform.buildRustPackage (lib.recursiveUpdate "^src.*$" "^assets.*$" "^Cargo\..*" - "^\.msvc_manifest.json$" "^build.*$" ]; cargoLock.lockFile = ./Cargo.lock; @@ -237,7 +23,4 @@ native.passthru.rustPlatform.buildRustPackage (lib.recursiveUpdate # "tray-icon-0.16.0" = "sha256-LxkEP31myIiWh6FDOzr9rZ8KAWISbja0jmEx0E2lM44="; # "clap-4.5.19" = "sha256-YRuZlp7jk05QLI551shgcVftcqKytTkxHlKbVejT1eE="; }; - - passthru = { inherit nix-git; }; } - native) diff --git a/codchi/src/cli.rs b/codchi/src/cli.rs index 4a60acb2..29e7c944 100644 --- a/codchi/src/cli.rs +++ b/codchi/src/cli.rs @@ -22,9 +22,6 @@ pub static DEBUG: LazyLock = LazyLock::new(|| { .unwrap() >= Level::Debug }); -#[cfg(target_os = "windows")] -pub static TERMINAL: LazyLock = - LazyLock::new(|| CLI_ARGS.get().and_then(|cli| cli.terminal) != Some(false)); type DefaultLogLevel = InfoLevel; @@ -81,11 +78,6 @@ pub struct Cli { #[arg(long, global = true)] pub json: bool, - /// Hide or show console window on Windows. Used when launching GUI apps via shortcuts. - #[cfg(target_os = "windows")] - #[arg(long, hide = true, default_value = "true")] - pub terminal: Option, - #[command(subcommand)] pub command: Option, } diff --git a/codchi/src/main.rs b/codchi/src/main.rs index 7c731dde..af65713b 100644 --- a/codchi/src/main.rs +++ b/codchi/src/main.rs @@ -34,30 +34,8 @@ fn main() -> anyhow::Result<()> { logging::init(cli.verbose.log_level_filter())?; - #[cfg(target_os = "windows")] - { - // https://github.com/rust-lang/cargo/issues/1721 - use util::dbg_duration; - use windows::Win32::{ - System::Console::GetConsoleWindow, - UI::WindowsAndMessaging::{self, ShowWindow}, - }; - if cli.terminal == Some(false) { - dbg_duration("hide console", || { - let window = unsafe { GetConsoleWindow() }; - if !window.0.is_null() { - if let Err(err) = - unsafe { ShowWindow(window, WindowsAndMessaging::SW_HIDE).ok() } - { - log::error!("Failed to hide console window. Reason: {err}"); - } - println!(); - } - }); - } - } - log::trace!("Started codchi with args: {:?}", cli); + // preload config let cfg = CodchiConfig::get(); diff --git a/codchi/src/platform/windows/host.rs b/codchi/src/platform/windows/host.rs index 291f8feb..0c4403fe 100644 --- a/codchi/src/platform/windows/host.rs +++ b/codchi/src/platform/windows/host.rs @@ -31,6 +31,10 @@ impl Host for HostImpl { .cleanup_and_get()?; let codchi_exe = env::current_exe()?; + let codchiw_exe = codchi_exe + .parent() + .with_context(|| format!("Missing parent of {codchi_exe:?}"))? + .join("codchiw.exe"); for DesktopEntry { app_name, @@ -40,16 +44,17 @@ impl Host for HostImpl { is_terminal, } in apps { - let mut lnk = ShellLink::new(codchi_exe.clone())?; + let mut lnk = ShellLink::new(if *is_terminal { + codchi_exe.clone() + } else { + codchiw_exe.clone() + })?; if let Some(ico_path) = icon { let target = ico_folder.join(format!("{app_name}.ico")); fs::copy(ico_path, &target)?; lnk.set_icon_location(Some(target.to_string_lossy().to_string())); } - // lnk.set_name(Some(name.clone())); - lnk.set_arguments(Some(format!( - "--terminal {is_terminal} exec {machine_name} {exec}" - ))); + lnk.set_arguments(Some(format!("exec {machine_name} {exec}"))); lnk.set_working_dir( get_known_folder_path(KnownFolder::Profile) .map(|p| p.to_string_lossy().to_string()), diff --git a/codchiw/.gitignore b/codchiw/.gitignore new file mode 100644 index 00000000..eb5a316c --- /dev/null +++ b/codchiw/.gitignore @@ -0,0 +1 @@ +target diff --git a/codchiw/Cargo.lock b/codchiw/Cargo.lock new file mode 100644 index 00000000..5fe83541 --- /dev/null +++ b/codchiw/Cargo.lock @@ -0,0 +1,180 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" + +[[package]] +name = "codchiw" +version = "0.1.0" +dependencies = [ + "anyhow", + "windows", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "2.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core", + "windows-targets", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-strings", + "windows-targets", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/codchiw/Cargo.toml b/codchiw/Cargo.toml new file mode 100644 index 00000000..69609a17 --- /dev/null +++ b/codchiw/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "codchiw" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = "1.0.93" +windows = { version = "0.58.0", features = ["Win32_Foundation", "Win32_System_Console", "Win32_System_Threading", "Win32_UI_WindowsAndMessaging"] } diff --git a/codchiw/default.nix b/codchiw/default.nix new file mode 100644 index 00000000..62b64125 --- /dev/null +++ b/codchiw/default.nix @@ -0,0 +1,22 @@ +{ callPackage +, lib +, self +, platform +, ... +}: +let + Cargo = builtins.fromTOML (builtins.readFile ./Cargo.toml); +in +callPackage + ../build/build-rust-package.nix +{ inherit self platform; } +{ + pname = "codchiw"; + inherit (Cargo.package) version; + src = lib.sourceByRegex ./. [ + "^src.*$" + "^Cargo\..*" + ]; + cargoLock.lockFile = ./Cargo.lock; + passthru = { }; +} diff --git a/codchiw/src/main.rs b/codchiw/src/main.rs new file mode 100644 index 00000000..32cd4803 --- /dev/null +++ b/codchiw/src/main.rs @@ -0,0 +1,51 @@ +#![windows_subsystem = "windows"] + +use std::{ + env, + os::windows::process::CommandExt, + process::{Command, Stdio}, +}; +use windows::Win32::{ + Foundation::HWND, + System::Threading::CREATE_NO_WINDOW, + UI::WindowsAndMessaging::{MessageBoxW, MB_ICONERROR, MB_OK}, +}; + +fn main() { + let result = (|| { + let args: Vec = env::args().skip(1).collect(); + let codchi_exe = env::current_exe()?.parent().unwrap().join("codchi.exe"); + + let child_output = Command::new(codchi_exe) + .args(args) + .creation_flags(CREATE_NO_WINDOW.0) + .stderr(Stdio::piped()) + .output()?; + + if !child_output.status.success() { + let stderr = String::from_utf8_lossy(&child_output.stderr); + anyhow::bail!("{stderr}"); + } + anyhow::Ok(()) + })(); + + if let Err(e) = result { + fn show_message_box(title: &str, message: &str) { + use windows::core::PCWSTR; + + let title_wide: Vec = title.encode_utf16().chain(std::iter::once(0)).collect(); + let message_wide: Vec = message.encode_utf16().chain(std::iter::once(0)).collect(); + + unsafe { + MessageBoxW( + HWND::default(), + PCWSTR(message_wide.as_ptr()), + PCWSTR(title_wide.as_ptr()), + MB_OK | MB_ICONERROR, + ); + } + } + + show_message_box("Codchi had an error", &e.to_string()); + } +} diff --git a/flake.nix b/flake.nix index 77daf6df..0dde19e4 100644 --- a/flake.nix +++ b/flake.nix @@ -24,6 +24,7 @@ (self: _: { codchi = self.callPackage ./codchi { inherit (inputs) self; platform = "linux"; }; codchi-windows = self.callPackage ./codchi { inherit (inputs) self; platform = "win"; }; + codchiw-windows = self.callPackage ./codchiw { inherit (inputs) self; platform = "win"; }; codchi-utils = self.callPackage ./utils { }; mkContainer = type: driver: (import ./nix/container @@ -89,6 +90,7 @@ inherit (pkgs) store-lxd store-wsl machine-lxd machine-wsl codchi-utils; default = pkgs.codchi; windows = pkgs.codchi-windows; + inherit (pkgs) codchiw-windows; # editor = pkgs.nixvim.makeNixvim (import ./editor.nix); };