Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
9af432a
Add Windows/MinGW support
claude Jan 28, 2026
86e9376
Add Windows CI workflows for test and release
claude Jan 28, 2026
e11582f
Add Windows support to interpreter FFI
claude Jan 28, 2026
2eaae6d
Fix Windows build: add cross-platform executable path helper
claude Jan 28, 2026
0058de0
Fix Windows build: add platform-specific includes across codebase
claude Jan 28, 2026
fe29693
Fix Windows build: rename TokenType to HmlTokenType
claude Jan 28, 2026
6f8ce17
Fix Windows build: update remaining TokenType references in core.c
claude Jan 28, 2026
5737e1b
Fix Windows build: remove conflicting ssize_t typedef
claude Jan 28, 2026
e3213b9
Fix Windows build: guard POSIX signal masking in concurrency.c
claude Jan 28, 2026
b39b0fc
Fix Windows build: add realpath implementation for context.c
claude Jan 28, 2026
615fb48
Fix Windows build: add getline implementation
claude Jan 28, 2026
1d491d2
Fix Windows build: add nanosleep and usleep implementations
claude Jan 28, 2026
a3cf994
Fix Windows build: add HML_WINDOWS support to runtime Makefile
claude Jan 28, 2026
fc4cb17
Fix Windows build: remove conflicting nanosleep/timespec definitions
claude Jan 28, 2026
8cfcbf3
Fix Windows build: remove conflicting usleep definition
claude Jan 28, 2026
601423e
Fix Windows build: use platform-agnostic directory functions
claude Jan 28, 2026
089cb23
Fix Windows build: add Windows compatibility for env.c
claude Jan 28, 2026
796ee72
Fix Windows build: remove duplicate macros and add fcntl.h
claude Jan 28, 2026
a8f0e84
Fix Windows build: remove MinGW-conflicting definitions
claude Jan 28, 2026
040d3df
Fix Windows build: add Windows compatibility for net.c
claude Jan 28, 2026
c829cbd
Fix Windows build: setsockopt pointer type compatibility
claude Jan 28, 2026
c0b4349
Fix Windows build: add Windows compatibility for os.c
claude Jan 28, 2026
bb0a023
Fix Windows build: add Windows stubs for regex.c
claude Jan 28, 2026
d562e46
Fix Windows build: wrap poll.h include in registration.c
claude Jan 28, 2026
673bb6f
Fix Windows build: comprehensive runtime and interpreter fixes
claude Jan 28, 2026
197f011
Fix Windows build: add Windows implementation for time_ms()
claude Jan 28, 2026
5b2ab3d
Fix Windows build: add getline compatibility to interpreter internal.h
claude Jan 28, 2026
cee8a89
Fix Windows build: fix include order and remove duplicate getline
claude Jan 28, 2026
ffe0c51
Fix Windows build: add Windows compatibility for runtime process func…
claude Jan 28, 2026
97b7aae
Fix Windows build: add strndup compatibility to LSP handlers.c
claude Jan 29, 2026
d5f4e17
Fix Windows build: add socket compatibility to LSP server
claude Jan 29, 2026
fc40c97
Fix Windows build: setsockopt cast and winsock include order
claude Jan 29, 2026
37818f6
Fix Windows build: add strndup compatibility to LSP protocol.c
claude Jan 29, 2026
13225b9
Fix Windows build: add realpath compatibility to bundler
claude Jan 30, 2026
e586adb
Fix Windows build: add realpath compatibility to formatter
claude Jan 30, 2026
5c57ed4
get it working lol
nbeerbower Jan 30, 2026
fd3cfbc
Fix Windows build: setsockopt cast in runtime socket
claude Jan 30, 2026
fb337af
Fix test runner: use printf instead of echo for error output
claude Jan 30, 2026
5052711
Fix Windows networking: proper error messages and WinSock init
claude Jan 30, 2026
9cd07e6
fix hemlockc
nbeerbower Feb 1, 2026
8ad6041
Merge origin/main into Windows support branch
nbeerbower Feb 7, 2026
a973f8c
Fix Windows path handling and add ECDSA version check
nbeerbower Feb 11, 2026
a7affe0
Merge main into Windows support branch
nbeerbower Feb 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"permissions": {
"allow": [
"Bash(make clean:*)",
"Bash(make:*)",
"Bash(./hemlock.exe:*)",
"Bash(./hemlockc.exe:*)",
"Bash(timeout 60 bash:*)",
"Bash(git pull:*)",
"Bash(gcc:*)",
"Bash(./hemlockc_debug.exe:*)",
"Bash(gdb:*)"
]
}
}
80 changes: 79 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,69 @@ jobs:
name: hemlock-macos-arm64
path: hemlock-macos-arm64.tar.gz

build-windows:
runs-on: windows-latest
defaults:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v4

- name: Setup MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
update: true
install: >-
mingw-w64-x86_64-gcc
mingw-w64-x86_64-make
mingw-w64-x86_64-libffi
mingw-w64-x86_64-openssl
mingw-w64-x86_64-zlib
make
bash
coreutils
findutils
zip

- name: Build runtime library
run: make runtime

- name: Build release binaries
run: make

- name: Build compiler
run: make compiler

- name: Run basic tests
run: |
echo 'print("Hello from Hemlock on Windows!");' > /tmp/test.hml
./hemlock.exe /tmp/test.hml

- name: Package
run: |
mkdir -p hemlock-windows-x86_64
cp hemlock.exe hemlock-windows-x86_64/
cp hemlockc.exe hemlock-windows-x86_64/
cp libhemlock_runtime.a hemlock-windows-x86_64/
cp -r stdlib hemlock-windows-x86_64/
mkdir -p hemlock-windows-x86_64/include
cp -r runtime/include/* hemlock-windows-x86_64/include/ 2>/dev/null || true
cp README.md LICENSE hemlock-windows-x86_64/ 2>/dev/null || cp README.md hemlock-windows-x86_64/
# Copy MinGW runtime DLLs that may be needed
cp /mingw64/bin/libgcc_s_seh-1.dll hemlock-windows-x86_64/ 2>/dev/null || true
cp /mingw64/bin/libwinpthread-1.dll hemlock-windows-x86_64/ 2>/dev/null || true
cp /mingw64/bin/libffi-8.dll hemlock-windows-x86_64/ 2>/dev/null || true
zip -r hemlock-windows-x86_64.zip hemlock-windows-x86_64

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: hemlock-windows-x86_64
path: hemlock-windows-x86_64.zip

release:
needs: [build-linux, build-macos-intel, build-macos-arm]
needs: [build-linux, build-macos-intel, build-macos-arm, build-windows]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -173,6 +234,8 @@ jobs:
The compiler is a portable code generator that produces native binaries.

### Quick Start

**Linux/macOS:**
```bash
# One-line install
curl -fsSL https://raw.githubusercontent.com/hemlang/hemlock/main/install.sh | bash
Expand All @@ -188,12 +251,27 @@ jobs:
./hemlockc your_script.hml -o your_program
```

**Windows:**
```powershell
# Download and extract
Expand-Archive hemlock-windows-x86_64.zip -DestinationPath .
cd hemlock-windows-x86_64

# Run interpreter
.\hemlock.exe your_script.hml

# Compile to native binary
.\hemlockc.exe your_script.hml -o your_program.exe
```

### Platform Notes
- **Linux x86_64**: Both binaries work on any glibc-based distro (Ubuntu, Debian, Fedora, etc.)
- **macOS x86_64/arm64**: Both binaries work out of the box
- **Windows x86_64**: Built with MinGW-w64, includes required runtime DLLs. Some POSIX features have limited support (see docs/WINDOWS_SUPPORT.md).
files: |
artifacts/hemlock-linux-x86_64/hemlock-linux-x86_64.tar.gz
artifacts/hemlock-macos-x86_64/hemlock-macos-x86_64.tar.gz
artifacts/hemlock-macos-arm64/hemlock-macos-arm64.tar.gz
artifacts/hemlock-windows-x86_64/hemlock-windows-x86_64.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
101 changes: 101 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -236,3 +236,104 @@ jobs:
name: scan-build-reports
path: scan-build-reports/
if-no-files-found: ignore

# Windows tests using MSYS2/MinGW
windows-test:
runs-on: windows-latest
defaults:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v4

- name: Setup MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
update: true
install: >-
mingw-w64-x86_64-gcc
mingw-w64-x86_64-make
mingw-w64-x86_64-libffi
mingw-w64-x86_64-openssl
mingw-w64-x86_64-zlib
make
bash
coreutils
findutils

- name: Build interpreter
run: make clean && make

- name: Run tests
run: |
# Run tests with Windows-incompatible tests automatically skipped
./tests/run_tests.sh

# Windows compiler build test
windows-compiler:
runs-on: windows-latest
defaults:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v4

- name: Setup MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
update: true
install: >-
mingw-w64-x86_64-gcc
mingw-w64-x86_64-make
mingw-w64-x86_64-libffi
mingw-w64-x86_64-openssl
mingw-w64-x86_64-zlib
make
bash
coreutils
findutils

- name: Build compiler
run: make compiler

- name: Run basic compiler test
run: |
echo 'print("Hello from Windows!");' > /tmp/test.hml
./hemlockc /tmp/test.hml -o /tmp/test.exe
/tmp/test.exe

# Windows parity tests
windows-parity:
runs-on: windows-latest
timeout-minutes: 15
defaults:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v4

- name: Setup MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
update: true
install: >-
mingw-w64-x86_64-gcc
mingw-w64-x86_64-make
mingw-w64-x86_64-libffi
mingw-w64-x86_64-openssl
mingw-w64-x86_64-zlib
make
bash
coreutils
findutils

- name: Build interpreter and compiler
run: |
make clean && make
make compiler

- name: Run parity tests
run: make parity
40 changes: 35 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
CC = gcc
# Use _DARWIN_C_SOURCE on macOS for BSD types, _POSIX_C_SOURCE on Linux
# Platform detection
UNAME := $(shell uname 2>/dev/null || echo Windows)

# Use platform-specific flags
ifeq ($(shell uname),Darwin)
CFLAGS = -Wall -Wextra -std=c11 -O3 -g -D_DARWIN_C_SOURCE -Iinclude -Isrc -Isrc/frontend -Isrc/backends -Isrc/shared $(EXTRA_CFLAGS)
PLATFORM = macos
else ifeq ($(findstring MINGW,$(UNAME)),MINGW)
CFLAGS = -Wall -Wextra -std=c11 -O3 -g -DHML_WINDOWS -Iinclude -Isrc -Isrc/frontend -Isrc/backends -Isrc/shared $(EXTRA_CFLAGS)
PLATFORM = windows
else ifeq ($(findstring MSYS,$(UNAME)),MSYS)
CFLAGS = -Wall -Wextra -std=c11 -O3 -g -DHML_WINDOWS -Iinclude -Isrc -Isrc/frontend -Isrc/backends -Isrc/shared $(EXTRA_CFLAGS)
PLATFORM = windows
else
CFLAGS = -Wall -Wextra -std=c11 -O3 -g -D_POSIX_C_SOURCE=200809L -D_DEFAULT_SOURCE -Iinclude -Isrc -Isrc/frontend -Isrc/backends -Isrc/shared $(EXTRA_CFLAGS)
PLATFORM = linux
endif
SRC_DIR = src
BUILD_DIR = build

# Detect libffi, OpenSSL, and libwebsockets (Homebrew on macOS puts them in non-standard locations)
ifeq ($(shell uname),Darwin)
# Detect libffi, OpenSSL, and libwebsockets (platform-specific detection)
ifeq ($(PLATFORM),macos)
# On macOS, prefer Homebrew's libffi (system pkg-config points to SDK without headers)
BREW_LIBFFI := $(shell brew --prefix libffi 2>/dev/null)
ifneq ($(BREW_LIBFFI),)
Expand All @@ -35,6 +46,23 @@ ifeq ($(shell uname),Darwin)
else
HAS_LIBWEBSOCKETS := 0
endif
# macOS base libraries
LDFLAGS_BASE = -lm -lpthread -lffi -ldl -lz -lcrypto

else ifeq ($(PLATFORM),windows)
# On Windows/MinGW, use pkg-config if available
LIBFFI_CFLAGS := $(shell pkg-config --cflags libffi 2>/dev/null)
LIBFFI_LIBS := $(shell pkg-config --libs-only-L libffi 2>/dev/null)
ifneq ($(LIBFFI_CFLAGS),)
CFLAGS += $(LIBFFI_CFLAGS)
LDFLAGS_LIBFFI = $(LIBFFI_LIBS)
endif
LDFLAGS_OPENSSL =
LDFLAGS_LIBWEBSOCKETS =
HAS_LIBWEBSOCKETS := 0
# Windows base libraries (no -ldl, add -lws2_32 for Winsock)
LDFLAGS_BASE = -lm -lpthread -lffi -lz -lcrypto -lws2_32

else
# On Linux, use pkg-config if available
LIBFFI_CFLAGS := $(shell pkg-config --cflags libffi 2>/dev/null)
Expand All @@ -48,10 +76,12 @@ else

# Check if libwebsockets is available on Linux
HAS_LIBWEBSOCKETS := $(shell pkg-config --exists libwebsockets 2>/dev/null && echo 1 || (test -f /usr/include/libwebsockets.h && echo 1 || echo 0))
# Linux base libraries
LDFLAGS_BASE = -lm -lpthread -lffi -ldl -lz -lcrypto
endif

# Base libraries (always required)
LDFLAGS = $(LDFLAGS_LIBFFI) $(LDFLAGS_OPENSSL) -lm -lpthread -lffi -ldl -lz -lcrypto $(EXTRA_LDFLAGS)
# Combine LDFLAGS
LDFLAGS = $(LDFLAGS_LIBFFI) $(LDFLAGS_OPENSSL) $(LDFLAGS_BASE) $(EXTRA_LDFLAGS)

# Conditionally add libwebsockets
ifeq ($(HAS_LIBWEBSOCKETS),1)
Expand Down
Loading
Loading