a mega cool windows xp app

feat: add flake and basic program

dunkirk.sh 2401993a 38eff0a9

verified
.cache/clangd/index/main.cpp.47C66B394CD74271.idx

This is a binary file and will not be displayed.

+1
.envrc
···
+
use flake
+6
.gitignore
···
+
.crush
+
result
+
.direnv
+
.clangd
+
compile_commands.json
+
build/
+41
CMakeLists.txt
···
+
cmake_minimum_required(VERSION 3.16)
+
project(HelloWorldApp CXX)
+
+
# Generate compile_commands.json for editor support
+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+
+
# Target Windows XP compatibility
+
add_definitions(-DWINVER=0x0501)
+
add_definitions(-D_WIN32_WINNT=0x0501)
+
+
add_executable(HelloWorldApp WIN32 main.cpp)
+
target_link_libraries(HelloWorldApp user32 gdi32)
+
+
# Minimal static linking
+
target_link_options(HelloWorldApp PRIVATE
+
-static-libgcc
+
-static-libstdc++
+
-Wl,--subsystem,windows:5.01
+
)
+
+
# Configurable output directory
+
if(DEFINED OUTPUT_DIR)
+
set_target_properties(HelloWorldApp PROPERTIES
+
RUNTIME_OUTPUT_DIRECTORY "${OUTPUT_DIR}"
+
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${OUTPUT_DIR}"
+
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${OUTPUT_DIR}"
+
)
+
endif()
+
+
set_target_properties(HelloWorldApp PROPERTIES
+
OUTPUT_NAME "HelloWorld"
+
)
+
+
# Configurable output directory
+
if(DEFINED OUTPUT_DIR)
+
set_target_properties(HelloWorldApp PROPERTIES
+
RUNTIME_OUTPUT_DIRECTORY "${OUTPUT_DIR}"
+
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${OUTPUT_DIR}"
+
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${OUTPUT_DIR}"
+
)
+
endif()
+38 -1
README.md
···
## Install
-
You can download a pre-built binary from the releases or you can cross compile the app for windows xp; i'll add a nix way soonish
+
You can download a pre-built binary from the releases or build it yourself using the nix flake.
+
+
## Development
+
+
this project uses nix for cross-compilation to windows xp. the key was using an older nixpkgs (22.05) since newer mingw toolchains use windows apis that don't exist in xp.
+
+
### Quick Start
+
+
```bash
+
# enter the dev environment (or use direnv)
+
nix develop
+
+
# build the app
+
nix build
+
+
# deploy to my xp vm folder
+
deploy-to-xp
+
```
+
+
### Editor Setup (Zed)
+
+
to get proper intellisense for win32 apis in zed:
+
+
```bash
+
# generate .clangd config with proper mingw headers
+
setup-dev
+
+
# restart zed
+
```
+
+
this creates a `.clangd` file that points to the actual mingw-w64 headers and avoids gcc intrinsics that cause clang issues.
+
+
### Build Details
+
+
- uses mingw-w64 cross-compiler targeting i686-w64-mingw32
+
- statically links runtime to avoid dll dependencies
+
- targets windows xp (winver=0x0501) for maximum compatibility
+
- older nixpkgs (22.05) prevents "procedure entry point" errors on xp
~
+77
flake.lock
···
+
{
+
"nodes": {
+
"flake-parts": {
+
"inputs": {
+
"nixpkgs-lib": "nixpkgs-lib"
+
},
+
"locked": {
+
"lastModified": 1751413152,
+
"narHash": "sha256-Tyw1RjYEsp5scoigs1384gIg6e0GoBVjms4aXFfRssQ=",
+
"owner": "hercules-ci",
+
"repo": "flake-parts",
+
"rev": "77826244401ea9de6e3bac47c2db46005e1f30b5",
+
"type": "github"
+
},
+
"original": {
+
"owner": "hercules-ci",
+
"repo": "flake-parts",
+
"type": "github"
+
}
+
},
+
"nixpkgs": {
+
"locked": {
+
"lastModified": 1685573264,
+
"narHash": "sha256-Zffu01pONhs/pqH07cjlF10NnMDLok8ix5Uk4rhOnZQ=",
+
"owner": "NixOS",
+
"repo": "nixpkgs",
+
"rev": "380be19fbd2d9079f677978361792cb25e8a3635",
+
"type": "github"
+
},
+
"original": {
+
"owner": "NixOS",
+
"ref": "nixos-22.05",
+
"repo": "nixpkgs",
+
"type": "github"
+
}
+
},
+
"nixpkgs-lib": {
+
"locked": {
+
"lastModified": 1751159883,
+
"narHash": "sha256-urW/Ylk9FIfvXfliA1ywh75yszAbiTEVgpPeinFyVZo=",
+
"owner": "nix-community",
+
"repo": "nixpkgs.lib",
+
"rev": "14a40a1d7fb9afa4739275ac642ed7301a9ba1ab",
+
"type": "github"
+
},
+
"original": {
+
"owner": "nix-community",
+
"repo": "nixpkgs.lib",
+
"type": "github"
+
}
+
},
+
"root": {
+
"inputs": {
+
"flake-parts": "flake-parts",
+
"nixpkgs": "nixpkgs",
+
"systems": "systems"
+
}
+
},
+
"systems": {
+
"locked": {
+
"lastModified": 1681028828,
+
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+
"owner": "nix-systems",
+
"repo": "default",
+
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+
"type": "github"
+
},
+
"original": {
+
"owner": "nix-systems",
+
"repo": "default",
+
"type": "github"
+
}
+
}
+
},
+
"root": "root",
+
"version": 7
+
}
+141
flake.nix
···
+
{
+
description = "Win32 Hello World App with About dropdown";
+
+
inputs = {
+
nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.05";
+
flake-parts.url = "github:hercules-ci/flake-parts";
+
systems.url = "github:nix-systems/default";
+
};
+
+
outputs = inputs@{ flake-parts, systems, ... }:
+
flake-parts.lib.mkFlake { inherit inputs; } {
+
imports = [ ];
+
systems = import systems;
+
perSystem = { self', pkgs, ... }: {
+
packages = {
+
hello-world-app = pkgs.stdenv.mkDerivation {
+
name = "hello-world-app";
+
version = "1.0.0";
+
src = ./.;
+
+
nativeBuildInputs = with pkgs; [
+
cmake
+
pkgsCross.mingw32.buildPackages.gcc
+
];
+
+
buildInputs = with pkgs.pkgsCross.mingw32; [
+
windows.mingw_w64
+
];
+
+
configurePhase = ''
+
export CC=${pkgs.pkgsCross.mingw32.buildPackages.gcc}/bin/i686-w64-mingw32-gcc
+
export CXX=${pkgs.pkgsCross.mingw32.buildPackages.gcc}/bin/i686-w64-mingw32-g++
+
export CMAKE_SYSTEM_NAME=Windows
+
export CMAKE_C_COMPILER=$CC
+
export CMAKE_CXX_COMPILER=$CXX
+
'';
+
+
buildPhase = ''
+
cmake -DCMAKE_BUILD_TYPE=Release \
+
-DCMAKE_SYSTEM_NAME=Windows \
+
-DCMAKE_C_COMPILER=$CC \
+
-DCMAKE_CXX_COMPILER=$CXX .
+
make VERBOSE=1
+
'';
+
+
installPhase = ''
+
mkdir -p $out/bin
+
cp HelloWorld.exe $out/bin/
+
'';
+
};
+
+
deploy-to-xp = pkgs.writeShellScriptBin "deploy-to-xp" ''
+
XP_DIR="$HOME/Documents/xp-drive"
+
mkdir -p "$XP_DIR"
+
cp ${self'.packages.hello-world-app}/bin/HelloWorld.exe "$XP_DIR/"
+
echo "Deployed HelloWorld.exe to $XP_DIR"
+
'';
+
+
setup-dev = pkgs.writeShellScriptBin "setup-dev" ''
+
echo "Setting up development environment for Zed..."
+
+
# Get the proper MinGW headers - use the known path from our build
+
MINGW_MAIN_INCLUDE="/nix/store/hhbkp872dkayzd2qxfhkdc4rgn393g52-mingw-w64-i686-w64-mingw32-9.0.0-dev/include"
+
+
# Verify it exists, if not try to find it dynamically
+
if [ ! -f "$MINGW_MAIN_INCLUDE/windows.h" ]; then
+
echo "Static path not found, searching dynamically..."
+
MINGW_MAIN_INCLUDE=$(i686-w64-mingw32-gcc -v -E - < /dev/null 2>&1 | sed -n '/mingw-w64.*-dev\/include/p' | head -1 | awk '{print $2}')
+
+
if [ -z "$MINGW_MAIN_INCLUDE" ] || [ ! -f "$MINGW_MAIN_INCLUDE/windows.h" ]; then
+
echo "Error: Could not find proper MinGW headers with windows.h"
+
exit 1
+
fi
+
fi
+
+
# Create simplified .clangd config to avoid intrinsics issues
+
cat > .clangd << EOF
+
CompileFlags:
+
Add:
+
- -target
+
- i686-w64-mingw32
+
- -DWINVER=0x0501
+
- -D_WIN32_WINNT=0x0501
+
- -DWIN32_LEAN_AND_MEAN
+
- -D_WIN32
+
- -DWIN32
+
- -std=c++17
+
- -fno-builtin
+
- -D__NO_INLINE__
+
- -isystem
+
- $MINGW_MAIN_INCLUDE
+
Remove:
+
- -I*/gcc/*/include
+
EOF
+
+
# Create simplified compile_commands.json
+
cat > compile_commands.json << EOF
+
[
+
{
+
"directory": "$(pwd)",
+
"command": "clang++ -target i686-w64-mingw32 -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 -DWIN32_LEAN_AND_MEAN -D_WIN32 -DWIN32 -fno-builtin -isystem \"$MINGW_MAIN_INCLUDE\" -std=c++17 -c main.cpp",
+
"file": "main.cpp"
+
}
+
]
+
EOF
+
+
echo "Generated simplified .clangd config and compile_commands.json"
+
echo "Using MinGW headers: $MINGW_MAIN_INCLUDE"
+
echo ""
+
echo "This avoids GCC intrinsics that cause clang issues"
+
echo "Restart Zed for the changes to take effect"
+
'';
+
+
default = self'.packages.hello-world-app;
+
};
+
+
devShells = {
+
default = pkgs.mkShell {
+
buildInputs = with pkgs; [
+
cmake
+
pkgsCross.mingw32.buildPackages.gcc
+
self'.packages.deploy-to-xp
+
self'.packages.setup-dev
+
];
+
+
shellHook = ''
+
echo "Win32 development environment loaded (older toolchain)"
+
echo "Available commands:"
+
echo " nix build - Build the application"
+
echo " deploy-to-xp - Deploy to XP VM folder"
+
echo " setup-dev - Generate compile_commands.json for Zed editor"
+
echo ""
+
echo "For Zed editor support:"
+
echo " 1. Run 'setup-dev' to generate compile_commands.json"
+
echo " 2. Open project in Zed for IntelliSense support"
+
'';
+
};
+
};
+
};
+
};
+
}
+100
main.cpp
···
+
#include <windows.h>
+
+
#define ID_ABOUT 1001
+
#define ID_EXIT 1002
+
+
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) {
+
const char* CLASS_NAME = "HelloWorldWindow";
+
+
WNDCLASS wc = {};
+
wc.lpfnWndProc = WindowProc;
+
wc.hInstance = hInstance;
+
wc.lpszClassName = CLASS_NAME;
+
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+
+
RegisterClass(&wc);
+
+
HWND hwnd = CreateWindow(
+
CLASS_NAME,
+
"Hello World App",
+
WS_OVERLAPPEDWINDOW,
+
CW_USEDEFAULT, CW_USEDEFAULT, 400, 300,
+
NULL,
+
NULL,
+
hInstance,
+
NULL
+
);
+
+
if (hwnd == NULL) {
+
return 0;
+
}
+
+
// Create menu
+
HMENU hMenu = CreateMenu();
+
HMENU hSubMenu = CreatePopupMenu();
+
+
AppendMenu(hSubMenu, MF_STRING, ID_ABOUT, "&About");
+
AppendMenu(hSubMenu, MF_SEPARATOR, 0, NULL);
+
AppendMenu(hSubMenu, MF_STRING, ID_EXIT, "E&xit");
+
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT_PTR)hSubMenu, "&Help");
+
+
SetMenu(hwnd, hMenu);
+
+
ShowWindow(hwnd, nCmdShow);
+
UpdateWindow(hwnd);
+
+
MSG msg = {};
+
while (GetMessage(&msg, NULL, 0, 0)) {
+
TranslateMessage(&msg);
+
DispatchMessage(&msg);
+
}
+
+
return 0;
+
}
+
+
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
+
switch (uMsg) {
+
case WM_DESTROY:
+
PostQuitMessage(0);
+
return 0;
+
+
case WM_PAINT: {
+
PAINTSTRUCT ps;
+
HDC hdc = BeginPaint(hwnd, &ps);
+
+
RECT rect;
+
GetClientRect(hwnd, &rect);
+
+
// Center the text
+
SetTextAlign(hdc, TA_CENTER);
+
SetBkMode(hdc, TRANSPARENT);
+
TextOut(hdc, rect.right / 2, rect.bottom / 2 - 10, "Hello World!", 12);
+
+
EndPaint(hwnd, &ps);
+
return 0;
+
}
+
+
case WM_COMMAND:
+
switch (LOWORD(wParam)) {
+
case ID_ABOUT: {
+
const char* aboutText = "Hello World App\n\n"
+
"Version: 1.0.0\n"
+
"Built by: Kieran Klukas\n\n"
+
"A simple Win32 application\n"
+
"compatible with Windows XP";
+
MessageBox(hwnd, aboutText, "About Hello World App",
+
MB_OK | MB_ICONINFORMATION);
+
break;
+
}
+
case ID_EXIT:
+
PostQuitMessage(0);
+
break;
+
}
+
return 0;
+
}
+
+
return DefWindowProc(hwnd, uMsg, wParam, lParam);
+
}