Skip to content

build: support Windows and CGO_ENABLED=0 targets#12

Merged
psycep merged 4 commits intomainfrom
windows-build
Apr 22, 2026
Merged

build: support Windows and CGO_ENABLED=0 targets#12
psycep merged 4 commits intomainfrom
windows-build

Conversation

@psycep
Copy link
Copy Markdown
Collaborator

@psycep psycep commented Apr 22, 2026

Summary

Finishes what #5 started. Makes go build ./... succeed on Windows (GOOS=windows CGO_ENABLED=0) and on Linux with CGO_ENABLED=0, without forcing users through WSL. Pairs with the -proxy flag from #10 so Windows and cgo-off users have a proxy path at all.

Builds on the direct_portable.go scaffolding already landed in #10, which provides the pure-Go dialer non-cgo / Windows builds fall back to. This PR just tags the three tools that can't follow that path, gives them stubs, teaches the installer about the new targets, and updates the README accordingly.

Changes

  • Build tags on the three affected tools:

    • tools/sniff/main.go, tools/split/main.go: tagged !windows && cgo (they import github.com/google/gopacket/pcap, which needs libpcap via cgo). New main_stub.go tagged windows || !cgo.
    • tools/sniffer/main.go: tagged !windows (Unix raw sockets via syscall.Socket + IP_HDRINCL, no cgo dependency). New main_windows.go tagged windows.
    • Each stub prints a one-line "not supported on this build" message and exits 1, so go build ./... always produces a binary and the install layout stays consistent across platforms.
  • install.sh gets a --target flag:

    • --target native (default): today's flow, Linux/macOS cgo, install to /usr/local/bin.
    • --target portable: CGO_ENABLED=0 for the host OS, output in ./dist/portable/.
    • --target windows: GOOS=windows CGO_ENABLED=0, .exe output in ./dist/windows/.
    • --target all: build every target in one run.
    • When run with no flags and a TTY on stdin, the installer prints an interactive menu explaining each target briefly (tool set, proxy path, output location). Non-TTY invocations (CI, pipes) default silently to native so existing automation keeps working.
  • README updates:

    • Installation section gains example --target invocations.
    • New "Platform Support" table shows the three build configurations, which tools are available in each, and which proxy path works.
    • Dropped a stale #9 section-number reference in the Proxy Support section.

Not changed

  • install.sh's libpcap check stays for the native target. Cross-compile targets skip it (the stubs handle the absence). The existing sniff/split skip-when-libpcap-missing behavior is preserved for native builds.
  • pkg/third_party/smb2 handles its own platform concerns; no tags needed from us.
  • The cross-compile binaries use raw tool names (ping.exe, net.exe, etc). These collide with Windows built-ins when run from the same directory in cmd.exe. The native install already prefixes with gopacket-; doing the same for cross-compile outputs is queued as a follow-up.

Test plan

  • go build ./... clean (default, cgo=1 Linux)
  • CGO_ENABLED=0 go build ./... clean
  • GOOS=windows CGO_ENABLED=0 go build ./... clean
  • go vet ./... clean across all three configurations
  • go test ./pkg/transport/ passes, 13/13
  • CGO_ENABLED=0 go test ./pkg/transport/ passes, 13/13, exercising the portable directDial path end-to-end
  • Live Windows smoke test against a small single-DC AD lab. Cross-compiled .exe binaries confirmed working: DumpNTLMInfo (SMB2 negotiate + NTLM info), lookupsid (SAMR over SMB named pipe), samrdump (SAMR user/group enum), rpcdump (RPC epmapper, 435 endpoints listed). Four different protocol stacks exercised via the pure-Go net.Dialer path on Windows.

psycep added 4 commits April 22, 2026 10:46
Enables clean builds under GOOS=windows CGO_ENABLED=0 and under
CGO_ENABLED=0 on Linux. The three tools that can't be built in those
configurations now substitute a stub that prints a clear message
and exits 1, so go build ./... succeeds across all target platforms.

- tools/sniff: tagged !windows && cgo (needs libpcap via cgo).
  Stub (main_stub.go) covers windows || !cgo.
- tools/split: same tags as sniff (also pcap).
- tools/sniffer: tagged !windows (uses Unix raw sockets directly via
  syscall, not cgo). Stub (main_windows.go) covers Windows.

Verified:
- go build ./... clean (default, cgo=1 Linux)
- CGO_ENABLED=0 go build ./... clean (portable Linux)
- GOOS=windows CGO_ENABLED=0 go build ./... clean (Windows)
- go vet clean across all three configurations
- All 13 pkg/transport tests pass under CGO_ENABLED=0, confirming
  direct_portable.go's directDial path is correct.
Replaces the "Linux/macOS only, use WSL on Windows" note with a
table showing the three supported build configurations (default cgo,
CGO_ENABLED=0 Linux, Windows), which tools are available in each,
and which proxy path works. Also drops a stray reference to a
specific KNOWN_ISSUES section number that will drift over time.
Extends the installer to produce CGO_ENABLED=0 static Linux binaries
and GOOS=windows .exe cross-compiles, not just the default native
cgo build. New flag:

  --target native    (default) Linux/macOS cgo + install (today's flow)
  --target portable  CGO_ENABLED=0, host OS, output to ./dist/portable/
  --target windows   GOOS=windows amd64, output to ./dist/windows/
  --target all       build every target in one run

When run with no --target and a TTY on stdin, the installer prints an
interactive menu that explains each target briefly (tool set, proxy
path, output location). Non-TTY invocations (CI, pipes) default
silently to native so existing automation keeps working unchanged.

Cross-compile targets never install to /usr/local/bin. They drop
binaries in ./dist/<target>/ for the user to copy to the right host.
The libpcap check and GCC check are now conditional: required for the
native target, skipped for portable/windows since those paths use
build-tag stubs for libpcap/raw-socket tools.
The Platform Support table already described the three build targets
but the Installation block still only showed the default invocation.
A reader could see that a windows target existed without knowing how
to actually build it. Adds example --target invocations for portable,
windows, and all, and softens the dependency paragraph since GCC and
libpcap are only required for the native target.
@psycep psycep merged commit 38474ef into main Apr 22, 2026
2 checks passed
@psycep psycep deleted the windows-build branch April 22, 2026 17:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant