Migrate Windows build to MSYS2 UCRT64 (draft, in-progress)#22551
Migrate Windows build to MSYS2 UCRT64 (draft, in-progress)#22551vkalintiris wants to merge 81 commits into
Conversation
The Windows MSYS2/UCRT64 build path installs the Rust toolchain (mingw-w64-ucrt-x86_64-rust) and passes -DRust_COMPILER=/ucrt64/bin/rustc to CMake, but no actual Rust code is ever compiled there because every Rust-using plugin (OTEL/journal/NetFlow/signal-viewer) is disabled in packaging/windows/compile-on-windows.sh. That leaves us blind to whether the Windows toolchain can build Rust at all. This adds a tiny self-contained staticlib crate at src/crates/rust-demo exposing nd_rust_add() and nd_rust_version() via the C ABI, gated behind a new CMake option ENABLE_RUST_DEMO (default ON). The crate is linked into the main netdata target and called from netdata_main() right after the NETDATA STARTUP log line, so a draft PR through the existing packaging workflows will exercise the Rust toolchain on Windows. The crate is its own workspace root (no runtime dependencies, no cbindgen) to keep compile time and dependency surface minimal -- the goal is to test whether Rust can be built, not whether a heavy workspace builds. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The investigation in SOW-0032 showed the Windows build runs in the MSYS shell with /usr/bin/gcc linking against msys-2.0.dll (Cygwin POSIX emulation, LP64), while /ucrt64/bin/rustc produces UCRT-linked LLP64 objects. The mismatch is harmless for the trivial smoke crate but blocks any non-trivial in-process Rust use. Since the project intends to write "a lot of Rust code", the rwin worktree pivots from a one-shot smoke PR to the full UCRT64 migration: switch the C side to /ucrt64/bin/gcc so it shares the same C runtime and data model as Rust, drop the bundled MSYS2 root from the installer, and end with the smoke crate re-enabled on Windows to validate the migration. This commit only sets up the pivot: - packaging/windows/compile-on-windows.sh: pass -DENABLE_RUST_DEMO=Off so Windows CI is not noised by Rust-toolchain output while migration phases iterate. The override will be removed at the end of the migration (Phase 7 of SOW-0033). Linux/macOS keep the default-on smoke build. - CMakeLists.txt: clarify the smoke option's comment to point at the Windows opt-out path during the migration. - SOW-0032: status paused; sub-state explains the pivot and the resume condition. - SOW-0033: new, in-progress, with a filled pre-implementation gate and an 8-phase plan from shell switch through installer slim-down through final smoke re-enable. Implementation gated on user confirmation of phase sequencing. No source code is migrated in this commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Windows MSYS2 shell defaults to MSYSTEM=MSYS, which makes the C side
of the agent link against msys-2.0.dll (Cygwin POSIX emulation, LP64).
The Rust toolchain at /ucrt64/bin/rustc produces UCRT-linked LLP64
objects. The mismatch blocks in-process Rust FFI and forces the
installer to ship the entire MSYS2 root just to provide msys-2.0.dll.
This commit pins the Windows build to MSYSTEM=UCRT64. The C compiler
and all runtime DLLs now come from the UCRT64 toolchain, matching the
Rust toolchain. Other MSYS2 environments (MSYS, MINGW64, CLANG64) are
deliberately rejected with a FATAL_ERROR so the failure mode is loud
rather than silent.
Changes:
- packaging/windows/{build,install-dependencies,invoke-msys2,package}.ps1:
set $env:MSYSTEM = 'UCRT64' before invoking msysbash so /etc/profile
picks the UCRT64 PATH (adds /ucrt64/bin, /ucrt64/lib/pkgconfig, etc.)
- packaging/cmake/Modules/NetdataPlatform.cmake:
- drop CYGWIN and MSYS CMAKE_SYSTEM_NAME branches; only Windows now
- require MSYSTEM=UCRT64 at configure time, FATAL_ERROR otherwise
- collapse CLion include_directories branches to ucrt64 only
- packaging/windows/compile-on-windows.sh: drop the explicit
-DRust_COMPILER=/ucrt64/bin/rustc; Corrosion finds rustc/cargo on
PATH under UCRT64 (see Corrosion's FindRust.cmake)
- packaging/windows/clion-msys-{msys,mingw64}-environment.bat: deleted
- packaging/windows/clion-msys-ucrt64-environment.bat: added as the
sole supported CLion developer entry point
This commit does not migrate any C source code; the next CI run is
expected to fail on the cygwin_conv_path() call sites and POSIX header
mismatches. Those failures define the work for Phases 3 and 4 of
SOW-0033.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Linux developers need a local way to validate Windows builds without waiting on GitHub CI, especially while iterating on SOW-0033 (the UCRT64 migration) where many phases will produce expected breakage that needs to be observed and fixed in short cycles. packaging/windows/LOCAL_DEV_LINUX.md walks through: - Setting up a Windows 11 VM with quickemu/QEMU/KVM (one-time cost, ~1 hour to first boot). - One-time Windows tweaks (long paths, OpenSSH server, default-shell -> PowerShell, the admin authorized_keys ACL gotcha). - Installing MSYS2 inside the VM by running the repo's own install-dependencies.ps1 over SSH (one command from the host). - Mounting the host's worktree into the VM at Z:\ via SSHFS-Win, so the host editor and the VM build see the same files live and the VM's build artifacts land directly under the host's build/ dir. - Driving the VM from a Linux shell (or from an LLM assistant like Claude Code) via SSH, with a small wrapper script. - A .claude/settings.json snippet that allowlists the wrapper, so a coding assistant can run ./packaging/windows/dev-vm.sh build, read the resulting errors, edit on the host, and re-build -- the VM is just another subshell from the assistant's perspective. packaging/windows/dev-vm.sh is the wrapper the walkthrough references: - build, package, deps, shell -- canned actions that map to the existing .ps1 entry points in packaging/windows/. - run -- '<ps>' -- run an arbitrary PowerShell command. - msys -- '<sh>' -- run an arbitrary command in a UCRT64 login bash, matching what build.ps1 sets up. Defaults are overridable via VM_HOST and REPO_IN_VM env vars so each developer can target their own VM without editing the script. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
First CI run on draft PR #22535 surfaced two distinct failures unrelated to the C source migration: 1. Windows build: NetdataPlatform.cmake rejected CMAKE_SYSTEM_NAME=MSYS even with MSYSTEM=UCRT64 set, because packaging/windows/compile-on-windows.sh hard-coded /usr/bin/cmake -- which is the MSYS-runtime cmake and always self-reports as MSYS regardless of $MSYSTEM. Setting MSYSTEM=UCRT64 changed PATH for gcc/pkg-config but the absolute path to cmake bypassed it. 2. Linux source-tarball builds across all distros, plus the LibreSSL and Clang Checks jobs, failed with `rustc not found in PATH`. Root cause: the previous default ENABLE_RUST_DEMO=On in CMake forced Corrosion to require rustc in every build environment, including ones that never needed a Rust toolchain. Fixes: - packaging/windows/compile-on-windows.sh: /usr/bin/cmake -> cmake so PATH (with /ucrt64/bin in front under MSYSTEM=UCRT64) resolves to the UCRT64 cmake. - packaging/windows/msys2-dependencies.sh: install mingw-w64-ucrt-x86_64-cmake and mingw-w64-ucrt-x86_64-ninja so the UCRT64 build tools are actually present. - CMakeLists.txt: flip ENABLE_RUST_DEMO default to Off. The smoke crate stays in tree; opt in per build. compile-on-windows.sh still passes -DENABLE_RUST_DEMO=Off explicitly during the migration (will flip to =On at Phase 7 to validate Rust on Windows end-to-end). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous follow-up commit (bffb496) successfully switched the Windows build to the UCRT64 cmake, confirmed by CI: CMAKE_SYSTEM_NAME now reports Windows and _nd_windows_config() is reached. One step deeper, a new error surfaced: CMake Error at packaging/cmake/Modules/NetdataPlatform.cmake:16: CMAKE_INSTALL_PREFIX must be set to /opt/netdata, but it is set to C:/msys64/opt/netdata Root cause: the UCRT64 cmake is a native Windows binary; when given -DCMAKE_INSTALL_PREFIX=/opt/netdata on the command line, it interprets the path as MSYS2-mounted POSIX and canonicalises it to the equivalent native Windows path C:/msys64/opt/netdata. Both forms refer to the same on-disk install location -- only the string differs from what the MSYS-cmake would have kept verbatim. Fix: relax the equality check to accept either the exact /opt/netdata (Linux and MSYS-cmake) or anything ending in /opt/netdata (UCRT64-cmake canonical form). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
3 issues found across 20 files
Confidence score: 3/5
- There is a concrete regression risk in
packaging/windows/clion-msys-ucrt64-environment.bat: with UCRT64 paths ordered last, other toolchains can take precedence and cause incorrect Windows build/runtime behavior. - The other findings are documentation consistency issues in
.agents/sow/current/SOW-0032-20260522-rust-on-windows-smoke.mdand.agents/sow/current/SOW-0033-20260522-windows-ucrt64-migration.md; these are lower severity and mainly affect reader/operator clarity rather than runtime code paths. - Given one medium-severity, high-confidence environment issue plus minor docs drift, this sits at moderate merge risk rather than a hard blocker.
- Pay close attention to
packaging/windows/clion-msys-ucrt64-environment.bat- PATH precedence should put UCRT64 entries first to avoid toolchain override.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name=".agents/sow/current/SOW-0032-20260522-rust-on-windows-smoke.md">
<violation number="1" location=".agents/sow/current/SOW-0032-20260522-rust-on-windows-smoke.md:147">
P2: Doc says no Windows override, but same SOW says `-DENABLE_RUST_DEMO=Off` is active. State is conflicting. Update this section to match current paused migration behavior.</violation>
</file>
<file name=".agents/sow/current/SOW-0033-20260522-windows-ucrt64-migration.md">
<violation number="1" location=".agents/sow/current/SOW-0033-20260522-windows-ucrt64-migration.md:194">
P3: Pre-Implementation Gate status stale. It says `needs-user-decision` even though execution log shows decision made and implementation started. Mark this gate status as historical snapshot and point readers to Execution Log for current lifecycle state.
(Based on your team's feedback about treating Pre-Implementation Gate as a historical snapshot.) [FEEDBACK_USED]</violation>
</file>
<file name="packaging/windows/clion-msys-ucrt64-environment.bat">
<violation number="1" location="packaging/windows/clion-msys-ucrt64-environment.bat:18">
P2: PATH order wrong. UCRT64 bins come last, so other toolchains can override. Put UCRT64 paths first.</violation>
</file>
Architecture diagram
sequenceDiagram
participant Dev as Linux Dev (Host)
participant Repo as Git Repo (sshfs)
participant VM as Windows 11 VM
participant PS as PowerShell
participant MSYS as MSYS2 UCRT64 Shell
participant CMake as CMake (UCRT64)
participant Cargo as Cargo/Rustc
participant Netdata as netdata.exe
participant Logger as Agent Logger
Note over Dev,Logger: NEW: Rust FFI Smoke Test (rust-demo crate)
Dev->>Repo: Edit source files
Dev->>VM: dev-vm.sh build
VM->>PS: Invoke build.ps1
PS->>PS: Set MSYSTEM=UCRT64
PS->>MSYS: compile-on-windows.sh
MSYS->>CMake: cmake -DENABLE_RUST_DEMO=Off
CMake->>CMake: Verify MSYSTEM=UCRT64
alt MSYSTEM not UCRT64
CMake-->>MSYS: FATAL_ERROR (reject MSYS/MINGW64)
end
CMake->>Cargo: corrosion_import_crate(rust_demo)
Cargo-->>CMake: rust_demo staticlib
CMake->>CMake: target_compile_definitions(HAVE_RUST_DEMO)
CMake->>CMake: target_link_libraries(rust_demo)
MSYS-->>PS: Build complete
PS-->>VM: netdata.exe
Note over Dev,Logger: NEW: Rust FFI Execution (runtime)
Dev->>VM: Start netdata
VM->>Netdata: netdata_main()
Netdata->>Logger: "NETDATA STARTUP ..."
opt HAVE_RUST_DEMO defined
Netdata->>Netdata: nd_rust_add(2, 3)
Netdata->>Netdata: nd_rust_version()
Netdata->>Logger: "RUST FFI smoke: rust-demo 0.1.0 reports nd_rust_add(2, 3) = 5"
end
Note over Dev,VM: NEW: MSYS2 Dependency Changes
MSYS->>MSYS: Install ucrt64 cmake & ninja
MSYS->>MSYS: pacman -S mingw-w64-ucrt-x86_64-cmake
MSYS->>MSYS: pacman -S mingw-w64-ucrt-x86_64-ninja
Note over Dev,VM: CHANGED: CLion Dev Environment
Dev->>Dev: Use clion-msys-ucrt64-environment.bat (single UCRT64 variant)
Note over Dev: Removed MSYS & MINGW64 .bat files
Note over Dev,VM: CHANGED: Path Handling
CMake->>CMake: Accept /opt/netdata or C:/msys64/opt/netdata
CMake->>CMake: Only include ucrt64 header path (not msys/mingw64)
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
To accelerate the iteration loop on the UCRT64 migration (SOW-0033), this commit disables every CI job except 'Build Windows' (and its file-check dependency) for the duration of work on the rwin branch. This is a one-off change; revert (or simply drop this commit) before merging the PR. Mechanism: - packaging/cmake aside: same-repo PR #22551 means GitHub Actions uses the head-branch workflow files for pull_request events. Edits here apply to this PR only; master and other PRs are unaffected. build.yml changes: - Gate non-Windows jobs with `if: github.head_ref != 'rwin' && ...` on the entry-point jobs (build-dist, static-matrix, src-matrix, macos-build, windows-test). Downstream jobs (build-static, prepare-upload, artifact-verification-*, source-build) inherit the skip via their `needs:` dependency on a skipped job, per GitHub Actions' default cascade. All other PR-triggering workflows (checks, codeql, coverity, check-markdown, docker, go-tests, packaging, repoconfig-packages, review, snmp-topology-tests, tests): - Replace the existing `pull_request:` trigger with a path filter that can never match (`__SOW_0033_DISABLED__`). The workflow keeps its push / schedule / workflow_dispatch triggers; only PR events are silenced. Each block carries a TEMPORARY comment with the revert intent. Net effect: a push to rwin runs only 'Check Modified Files' and 'Build Windows'. Everything else is skipped. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
12 issues found across 12 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Continuing SOW-0033 Phase 2 follow-ups. - packaging/windows/msys2-dependencies.sh: install mingw-w64-ucrt-x86_64-libyaml so the UCRT64 cmake finds system libyaml instead of falling back to a bundled (and very old) cmake_minimum_required(< 3.5) yaml subproject. - packaging/windows/clion-msys-ucrt64-environment.bat: prepend UCRT64 bins to PATH instead of appending. Appending allowed an unrelated toolchain already on PATH (e.g. a system MinGW64 install) to win symbol resolution, which would defeat the whole point of the file. - packaging/windows/dev-vm.sh (`msys` subcommand): switch from `bash -lc "MSYSTEM=UCRT64 <cmd>"` to `msys2_shell.cmd -ucrt64 -here -no-start -defterm -c "<cmd>"`. Setting MSYSTEM inside the bash command string is too late: the login shell sources /etc/profile (which configures PATH for the current MSYSTEM) before running the command. msys2_shell.cmd sets MSYSTEM in the parent env before bash starts, which is what we need to match build.ps1's behaviour. - packaging/windows/compile-on-windows.sh: document why -DRust_COMPILER was dropped; under MSYSTEM=UCRT64, rustc/cargo are on PATH and Corrosion's FindRust discovers cargo next to rustc. - .github/workflows/build.yml: hoist the SOW-0033 iteration explanation into a single anchor comment above `jobs:` and shorten each per-job `if:` comment to point at the anchor. Document the cascade-skip contract (build-static, prepare-upload, artifact-verification-*, source-build inherit the skip from their `needs:` chain) and the revert procedure. - .agents/sow/current/SOW-0032-...md: sweep stale claims about the CMake option default. The original plan set ENABLE_RUST_DEMO=On by default; that was flipped to Off in bffb496 after CI showed it forced rustc onto every source-tarball build environment. The Acceptance Criteria, Risks, Implementation Plan, and Validation Plan sections now reflect the current default-Off / opt-in shape. The Execution Log and Implications-and-Decisions sections stay as the historical record. - .agents/sow/current/SOW-0033-...md: refresh Status sub-state to the actual current state (Phase 2 + 2 follow-ups committed, Phase 3 next); update an Acceptance Criterion that mentioned a no-longer-existing default-On state; annotate the historical Pre- Implementation Gate "Open decisions" with their later resolutions; add the revert-the-CI-disable item to the Followup section. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
@cubic-dev-ai please review again |
@vkalintiris I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
8 issues found across 32 files
Confidence score: 2/5
- Several workflow changes in
.github/workflows/docker.yml,.github/workflows/packaging.yml,.github/workflows/repoconfig-packages.yml, and.github/workflows/coverity.ymleffectively disable normalpull_requestchecks, which creates a clear regression risk by removing key CI and static-analysis gates before merge. - The most severe issue is user-impacting in process quality: Docker CI checks are skipped for typical PRs (7/10 severity, high confidence), so breakages are more likely to land undetected.
packaging/windows/LOCAL_DEV_LINUX.mdhas concrete setup problems (missingopenssh-serverprerequisite and incorrect SSHFS-Win UNC path format), so local Windows/Linux dev setup may fail end-to-end until corrected.- Pay close attention to
.github/workflows/docker.yml,.github/workflows/packaging.yml,.github/workflows/repoconfig-packages.yml,.github/workflows/coverity.yml, andpackaging/windows/LOCAL_DEV_LINUX.md- PR validation is being bypassed and dev setup instructions can break.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packaging/windows/LOCAL_DEV_LINUX.md">
<violation number="1" location="packaging/windows/LOCAL_DEV_LINUX.md:39">
P2: Missing SSH server package in prerequisites. Step 5 needs host `sshd`, but install list only adds client. Add `openssh-server` so setup works end to end.</violation>
<violation number="2" location="packaging/windows/LOCAL_DEV_LINUX.md:226">
P2: Path format wrong for SSHFS-Win UNC. `host_path` uses `/...` and builds `\/home/...`. Use backslash path components so `net use` targets the right folder.</violation>
</file>
<file name=".github/workflows/packaging.yml">
<violation number="1" location=".github/workflows/packaging.yml:5">
P2: This filter disables Packages workflow on all PRs. No PR packaging checks run. Restore normal PR trigger before merge.</violation>
</file>
<file name="packaging/cmake/Modules/NetdataPlatform.cmake">
<violation number="1" location="packaging/cmake/Modules/NetdataPlatform.cmake:21">
P2: Prefix check too loose. Suffix match allows unintended install roots. Tighten accepted Windows form so only canonicalized `/opt/netdata` paths pass.</violation>
</file>
<file name=".github/workflows/repoconfig-packages.yml">
<violation number="1" location=".github/workflows/repoconfig-packages.yml:8">
P2: PR trigger now effectively off. This workflow stops running for real repoconfig changes. Put real paths back so PR CI still catches breakage.</violation>
</file>
<file name=".agents/sow/current/SOW-0032-20260522-rust-on-windows-smoke.md">
<violation number="1" location=".agents/sow/current/SOW-0032-20260522-rust-on-windows-smoke.md:238">
P3: This decision line is stale against the rest of this SOW. Update it to the current default-Off state (or clearly mark it as historical) so later readers do not follow the wrong setting.</violation>
</file>
<file name=".github/workflows/coverity.yml">
<violation number="1" location=".github/workflows/coverity.yml:9">
P2: PR Coverity trigger effectively off. Static analysis stops running on normal PR changes. Re-enable real path filters before merge.</violation>
</file>
<file name=".github/workflows/docker.yml">
<violation number="1" location=".github/workflows/docker.yml:18">
P1: PR trigger now effectively off for normal changes. Docker CI checks get skipped. Re-enable default pull_request trigger.</violation>
</file>
Architecture diagram
sequenceDiagram
participant PS as PowerShell Scripts
participant MSYS as MSYS2 UCRT64 Shell
participant CMake as CMake (UCRT64)
participant Corrosion as Corrosion
participant Cargo as Rust Toolchain
participant CC as C Compiler (UCRT64)
participant Netdata as netdata.exe
participant CI as GitHub Actions (rwin)
Note over PS,CI: BUILD ORCHESTRATION
PS->>MSYS: Set MSYSTEM=UCRT64
MSYS->>CMake: cmake (UCRT64 binary, not /usr/bin/cmake)
CMake->>CMake: Validate MSYSTEM=UCRT64
CMake->>CMake: Accept CMAKE_INSTALL_PREFIX=C:/msys64/opt/netdata
CMake->>CMake: Add /ucrt64/include to include path
Note over CMake,Cargo: RUST SMOKE TEST (conditional)
alt ENABLE_RUST_DEMO=On
CMake->>Corrosion: Declare FetchContent(Corrosion)
Corrosion->>Cargo: corrosion_import_crate(rust_demo)
Cargo->>Cargo: Build src/crates/rust-demo/ as staticlib
Cargo-->>Corrosion: librust_demo.a
Corrosion-->>CMake: Static library reference
CMake->>Netdata: target_compile_definitions(HAVE_RUST_DEMO)
CMake->>Netdata: target_link_libraries(rust_demo)
else ENABLE_RUST_DEMO=Off (default)
CMake->>CMake: Skip Rust/Corrosion (unless other Rust plugins enabled)
end
Note over CC,Netdata: COMPILATION
CC->>Netdata: Compile src/daemon/main.c
Netdata->>Netdata: Include rust_demo.h (if HAVE_RUST_DEMO)
Netdata->>Netdata: Link librust_demo.a (if ENABLE_RUST_DEMO)
Note over CI: CI GATING (rwin branch only)
alt CI branch == rwin
CI->>CI: Skip non-Windows jobs (build-dist, static-matrix, etc.)
CI->>CI: Skip non-Windows workflow triggers (markdown, checks, etc.)
end
Note over Netdata: RUNTIME STARTUP
Netdata->>Netdata: Call nd_rust_add(2, 3)
Netdata->>Netdata: Call nd_rust_version()
alt HAVE_RUST_DEMO defined
Netdata->>Netdata: Log "RUST FFI smoke: rust-demo 0.1.0 reports nd_rust_add(2, 3) = 5"
end
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| pull_request: null | ||
| pull_request: # SOW-0033 iteration on rwin: disable non-Windows CI. Revert this block before merge. | ||
| paths: | ||
| - '__SOW_0033_DISABLED__' |
There was a problem hiding this comment.
P1: PR trigger now effectively off for normal changes. Docker CI checks get skipped. Re-enable default pull_request trigger.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/docker.yml, line 18:
<comment>PR trigger now effectively off for normal changes. Docker CI checks get skipped. Re-enable default pull_request trigger.</comment>
<file context>
@@ -13,7 +13,9 @@ on:
- pull_request: null
+ pull_request: # SOW-0033 iteration on rwin: disable non-Windows CI. Revert this block before merge.
+ paths:
+ - '__SOW_0033_DISABLED__'
workflow_dispatch:
inputs:
</file context>
| $mountpoint = "Z:" | ||
| $host_user = "vk" | ||
| $host_ip = "192.168.122.1" # host as seen from the VM | ||
| $host_path = "/home/vk/repos/nd/rwin" |
There was a problem hiding this comment.
P2: Path format wrong for SSHFS-Win UNC. host_path uses /... and builds \/home/.... Use backslash path components so net use targets the right folder.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packaging/windows/LOCAL_DEV_LINUX.md, line 226:
<comment>Path format wrong for SSHFS-Win UNC. `host_path` uses `/...` and builds `\/home/...`. Use backslash path components so `net use` targets the right folder.</comment>
<file context>
@@ -0,0 +1,378 @@
+$mountpoint = "Z:"
+$host_user = "vk"
+$host_ip = "192.168.122.1" # host as seen from the VM
+$host_path = "/home/vk/repos/nd/rwin"
+
+net use $mountpoint \\sshfs.r\${host_user}@${host_ip}\${host_path}
</file context>
| ```bash | ||
| sudo apt install qemu-system-x86 qemu-utils ovmf libvirt-clients \ | ||
| libvirt-daemon-system virt-manager \ | ||
| sshfs openssh-client \ |
There was a problem hiding this comment.
P2: Missing SSH server package in prerequisites. Step 5 needs host sshd, but install list only adds client. Add openssh-server so setup works end to end.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packaging/windows/LOCAL_DEV_LINUX.md, line 39:
<comment>Missing SSH server package in prerequisites. Step 5 needs host `sshd`, but install list only adds client. Add `openssh-server` so setup works end to end.</comment>
<file context>
@@ -0,0 +1,378 @@
+```bash
+sudo apt install qemu-system-x86 qemu-utils ovmf libvirt-clients \
+ libvirt-daemon-system virt-manager \
+ sshfs openssh-client \
+ quickemu quickget
+```
</file context>
| pull_request: # SOW-0033 iteration on rwin: disable non-Windows CI. Revert this block before merge. | ||
| paths: | ||
| - '__SOW_0033_DISABLED__' |
There was a problem hiding this comment.
P2: This filter disables Packages workflow on all PRs. No PR packaging checks run. Restore normal PR trigger before merge.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/packaging.yml, line 5:
<comment>This filter disables Packages workflow on all PRs. No PR packaging checks run. Restore normal PR trigger before merge.</comment>
<file context>
@@ -2,12 +2,9 @@
- - reopened
- - labeled
- - synchronize
+ pull_request: # SOW-0033 iteration on rwin: disable non-Windows CI. Revert this block before merge.
+ paths:
+ - '__SOW_0033_DISABLED__'
</file context>
| pull_request: # SOW-0033 iteration on rwin: disable non-Windows CI. Revert this block before merge. | |
| paths: | |
| - '__SOW_0033_DISABLED__' | |
| pull_request: | |
| types: | |
| - opened | |
| - reopened | |
| - labeled | |
| - synchronize |
| # C:/msys64/opt/netdata). Both refer to the same on-disk location, so | ||
| # accept either: the exact string, or anything ending in /opt/netdata. | ||
| if(NOT "${CMAKE_INSTALL_PREFIX}" STREQUAL "/opt/netdata" AND | ||
| NOT "${CMAKE_INSTALL_PREFIX}" MATCHES "/opt/netdata$") |
There was a problem hiding this comment.
P2: Prefix check too loose. Suffix match allows unintended install roots. Tighten accepted Windows form so only canonicalized /opt/netdata paths pass.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packaging/cmake/Modules/NetdataPlatform.cmake, line 21:
<comment>Prefix check too loose. Suffix match allows unintended install roots. Tighten accepted Windows form so only canonicalized `/opt/netdata` paths pass.</comment>
<file context>
@@ -12,10 +12,27 @@ include_guard()
+ # C:/msys64/opt/netdata). Both refer to the same on-disk location, so
+ # accept either: the exact string, or anything ending in /opt/netdata.
+ if(NOT "${CMAKE_INSTALL_PREFIX}" STREQUAL "/opt/netdata" AND
+ NOT "${CMAKE_INSTALL_PREFIX}" MATCHES "/opt/netdata$")
message(FATAL_ERROR "CMAKE_INSTALL_PREFIX must be set to /opt/netdata, but it is set to ${CMAKE_INSTALL_PREFIX}")
endif()
</file context>
| - packaging/repoconfig/** | ||
| - .github/workflows/repoconfig-packages.yml | ||
| - .github/data/distros.yml | ||
| - '__SOW_0033_DISABLED__' |
There was a problem hiding this comment.
P2: PR trigger now effectively off. This workflow stops running for real repoconfig changes. Put real paths back so PR CI still catches breakage.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/repoconfig-packages.yml, line 8:
<comment>PR trigger now effectively off. This workflow stops running for real repoconfig changes. Put real paths back so PR CI still catches breakage.</comment>
<file context>
@@ -3,11 +3,9 @@
- - packaging/repoconfig/**
- - .github/workflows/repoconfig-packages.yml
- - .github/data/distros.yml
+ - '__SOW_0033_DISABLED__'
push:
branches:
</file context>
| - '__SOW_0033_DISABLED__' | |
| - packaging/repoconfig/** | |
| - .github/workflows/repoconfig-packages.yml | |
| - .github/data/distros.yml |
| paths: | ||
| - .github/workflows/coverity.yml | ||
| - packaging/utils/coverity-scan.sh | ||
| - '__SOW_0033_DISABLED__' |
There was a problem hiding this comment.
P2: PR Coverity trigger effectively off. Static analysis stops running on normal PR changes. Re-enable real path filters before merge.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/coverity.yml, line 9:
<comment>PR Coverity trigger effectively off. Static analysis stops running on normal PR changes. Re-enable real path filters before merge.</comment>
<file context>
@@ -4,10 +4,9 @@ name: Coverity Scan
paths:
- - .github/workflows/coverity.yml
- - packaging/utils/coverity-scan.sh
+ - '__SOW_0033_DISABLED__'
env:
DISABLE_TELEMETRY: 1
</file context>
| member). Selected by user. Rationale: isolates the smoke test from | ||
| the heavy `src/crates` workspace deps; the goal is to prove the | ||
| toolchain works, not to prove the workspace builds on Windows. | ||
| 2. CMake gating: `ENABLE_RUST_DEMO` default ON. Selected by user. |
There was a problem hiding this comment.
P3: This decision line is stale against the rest of this SOW. Update it to the current default-Off state (or clearly mark it as historical) so later readers do not follow the wrong setting.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .agents/sow/current/SOW-0032-20260522-rust-on-windows-smoke.md, line 238:
<comment>This decision line is stale against the rest of this SOW. Update it to the current default-Off state (or clearly mark it as historical) so later readers do not follow the wrong setting.</comment>
<file context>
@@ -0,0 +1,372 @@
+ member). Selected by user. Rationale: isolates the smoke test from
+ the heavy `src/crates` workspace deps; the goal is to prove the
+ toolchain works, not to prove the workspace builds on Windows.
+2. CMake gating: `ENABLE_RUST_DEMO` default ON. Selected by user.
+ Rationale: easy to opt out for bisecting, but ON by default so the
+ smoke test runs everywhere.
</file context>
| 2. CMake gating: `ENABLE_RUST_DEMO` default ON. Selected by user. | |
| 2. CMake gating: originally `ENABLE_RUST_DEMO` defaulted ON (historical user decision), then was flipped to Off in commit `bffb496eec` during migration. |
There was a problem hiding this comment.
Pull request overview
This PR is a draft, in-progress migration of the Windows build to MSYS2 UCRT64 so the C toolchain/runtime matches the Rust toolchain’s UCRT/LLP64 model, unblocking in-process Rust FFI and enabling eventual removal of the bundled MSYS2 root from the installer. It also introduces an optional Rust “smoke” staticlib crate and adds local Linux→Windows VM build workflow documentation/scripts to speed iteration during the migration.
Changes:
- Add an opt-in
rust-demostaticlib crate and wire it into thenetdatabinary behindENABLE_RUST_DEMO/HAVE_RUST_DEMO. - Hard-cut the Windows build environment to
MSYSTEM=UCRT64across PowerShell entry points and enforce it inNetdataPlatform.cmake; update Windows dependency installation and build tooling to use UCRT64 CMake/Ninja. - Add Linux→Windows local dev walkthrough +
dev-vm.shwrapper; temporarily adjust CI workflow triggers/conditions to focus iteration.
Reviewed changes
Copilot reviewed 31 out of 32 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
src/daemon/main.c |
Calls the Rust FFI smoke functions at startup and logs the result under HAVE_RUST_DEMO. |
src/crates/rust-demo/Cargo.toml |
Defines the standalone Rust workspace/package for the smoke staticlib. |
src/crates/rust-demo/src/lib.rs |
Implements nd_rust_add / nd_rust_version exported via the C ABI. |
src/crates/rust-demo/rust_demo.h |
Hand-written C header for the two exported Rust FFI symbols. |
src/crates/rust-demo/Cargo.lock |
Lockfile for the standalone smoke crate workspace. |
CMakeLists.txt |
Adds ENABLE_RUST_DEMO, imports the crate via Corrosion when enabled, and links it into netdata. |
packaging/cmake/Modules/NetdataPlatform.cmake |
Enforces MSYSTEM=UCRT64 on Windows and relaxes CMAKE_INSTALL_PREFIX validation for native-UCRT64 CMake canonicalization. |
packaging/windows/build.ps1 |
Forces MSYSTEM=UCRT64 for Windows builds. |
packaging/windows/install-dependencies.ps1 |
Forces MSYSTEM=UCRT64 when installing MSYS2 dependencies. |
packaging/windows/invoke-msys2.ps1 |
Forces MSYSTEM=UCRT64 for generic MSYS2 invocation. |
packaging/windows/package.ps1 |
Forces MSYSTEM=UCRT64 for packaging. |
packaging/windows/msys2-dependencies.sh |
Adds UCRT64 CMake/Ninja/libyaml packages to support the new toolchain path. |
packaging/windows/compile-on-windows.sh |
Uses UCRT64 cmake from PATH and keeps ENABLE_RUST_DEMO=Off during migration. |
packaging/windows/clion-msys-ucrt64-environment.bat |
Consolidates CLion tooling to a single UCRT64 environment setup. |
packaging/windows/clion-msys-msys-environment.bat |
Removed legacy MSYS CLion environment. |
packaging/windows/clion-msys-mingw64-environment.bat |
Removed legacy MINGW64 CLion environment. |
packaging/windows/LOCAL_DEV_LINUX.md |
Documents a Linux-host workflow for driving Windows builds in a VM over SSH/sshfs. |
packaging/windows/dev-vm.sh |
Provides a host-side wrapper to run build/deps/package and ad-hoc commands in the Windows VM. |
.github/workflows/build.yml |
Adds temporary SOW-0033 gating commentary/conditions for iteration (needs correction per review). |
.github/workflows/tests.yml |
Temporarily disables PR trigger via a never-matching paths filter. |
.github/workflows/snmp-topology-tests.yml |
Temporarily disables PR trigger via a never-matching paths filter. |
.github/workflows/review.yml |
Temporarily disables PR trigger via a never-matching paths filter. |
.github/workflows/repoconfig-packages.yml |
Temporarily disables PR trigger via a never-matching paths filter. |
.github/workflows/packaging.yml |
Temporarily disables PR trigger via a never-matching paths filter. |
.github/workflows/go-tests.yml |
Temporarily disables PR trigger via a never-matching paths filter. |
.github/workflows/docker.yml |
Temporarily disables PR trigger via a never-matching paths filter. |
.github/workflows/coverity.yml |
Temporarily disables PR trigger via a never-matching paths filter. |
.github/workflows/codeql.yml |
Temporarily disables PR trigger via a never-matching paths filter. |
.github/workflows/checks.yml |
Temporarily disables PR trigger via a never-matching paths filter. |
.github/workflows/check-markdown.yml |
Temporarily disables PR trigger via a never-matching paths filter. |
.agents/sow/current/SOW-0032-20260522-rust-on-windows-smoke.md |
Documents the smoke crate SOW and the temporary Windows opt-out during migration. |
.agents/sow/current/SOW-0033-20260522-windows-ucrt64-migration.md |
Tracks the UCRT64 migration plan, phases, risks, and current execution status. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| int32_t rust_sum = nd_rust_add(2, 3); | ||
| const char *rust_ver = nd_rust_version(); | ||
| netdata_log_info("RUST FFI smoke: %s reports nd_rust_add(2, 3) = %d", | ||
| rust_ver ? rust_ver : "(null)", rust_sum); |
| # accept either: the exact string, or anything ending in /opt/netdata. | ||
| if(NOT "${CMAKE_INSTALL_PREFIX}" STREQUAL "/opt/netdata" AND | ||
| NOT "${CMAKE_INSTALL_PREFIX}" MATCHES "/opt/netdata$") |
| run) | ||
| shift | ||
| [ "${1:-}" = "--" ] && shift | ||
| ssh "$VM_HOST" "powershell -NoProfile -ExecutionPolicy Bypass -Command \"$*\"" | ||
| ;; |
| msys) | ||
| shift | ||
| [ "${1:-}" = "--" ] && shift | ||
| # Use msys2_shell.cmd -ucrt64 so MSYSTEM is set in the parent env | ||
| # before /etc/profile is sourced. Setting MSYSTEM inside the bash | ||
| # -c string is too late: the login shell already configured PATH | ||
| # for the default MSYS subsystem. | ||
| ssh "$VM_HOST" "C:\\msys64\\msys2_shell.cmd -ucrt64 -here -no-start -defterm -c \"$*\"" | ||
| ;; |
|
|
||
| [profile.release] | ||
| opt-level = 3 | ||
| lto = true |
| # Several jobs below carry `if: github.head_ref != 'rwin' && ...`. This | ||
| # gates them off for the duration of the UCRT64 migration so only | ||
| # `windows-build` and its `file-check` dependency run on rwin pushes. | ||
| # Cascade-skip: jobs that `needs:` a gated entry-point (build-dist, | ||
| # static-matrix, src-matrix, macos-build) -- e.g. build-static, | ||
| # prepare-upload, artifact-verification-*, source-build -- inherit the | ||
| # skip via GitHub Actions' default behaviour (skipped dependency = | ||
| # skipped dependent). | ||
| # | ||
| # Predicate is safe in this workflow's trigger context: | ||
| # - pull_request events: `head_ref` is set to the source branch. | ||
| # - push events: only fire on `master` (see `on:` above); head_ref is | ||
| # empty, condition is true, jobs run normally. | ||
| # - workflow_dispatch: jobs that run on this event have their own | ||
| # `if: github.event_name != 'workflow_dispatch'` filter. | ||
| # |
The OS_WINDOWS branch of netdata_detect_protobuf() hardcoded
PROTOBUF_PROTOC_EXECUTABLE="/bin/protoc". Under the previous
MSYS-cmake/MSYS-ninja stack that POSIX path resolved through the
msys-2.0.dll path-translation layer. Under the new UCRT64
cmake/ninja stack -- both native Windows binaries -- ninja sees
'/bin/protoc' as a literal filesystem path that does not exist,
and the build fails with:
ninja: error: '/bin/protoc', needed by
'src/aclk/aclk-schemas/proto/aclk/v1/lib.pb.cc', missing and no
known rule to make it
Replace the hardcoded fallback with find_program(PROTOBUF_PROTOC_EXECUTABLE
NAMES protoc.exe protoc). Under MSYSTEM=UCRT64 the shell PATH begins
with /ucrt64/bin, so find_program returns the Windows-canonical
form of /ucrt64/bin/protoc.exe which ninja can resolve. The
existing $ENV{PROTOBUF_PROTOC_EXECUTABLE} override still wins if
the user wants to point at a different protoc.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previous attempt at finding protoc via plain `find_program(NAMES
protoc.exe protoc)` returned NOTFOUND under MSYSTEM=UCRT64 even
though `mingw-w64-ucrt-x86_64-protobuf` was installed and provides
/ucrt64/bin/protoc.exe. PATH propagation from the bash login shell
through to the native-Windows cmake.exe binary is apparently not as
reliable as one might hope; the standard PATH-only search missed
the bin directory.
Add an explicit HINTS pointing at $ENV{MINGW_PREFIX}/bin. MSYS2's
/etc/profile sets MINGW_PREFIX to /ucrt64 under MSYSTEM=UCRT64,
and the UCRT64 cmake canonicalises that to the Windows-native
C:/msys64/ucrt64/bin form. Improve the FATAL_ERROR diagnostic to
include the searched HINTS and the value of MINGW_PREFIX so the
next failure (if any) gives us the actual bash->cmake env state
to debug.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous find_program attempt with HINTS at $MINGW_PREFIX/bin returned NOTFOUND even though the mingw-w64-ucrt-x86_64-protobuf 33.5-4 package archive demonstrably ships protoc.exe at exactly that location (verified by inspecting the .pkg.tar.zst contents: ucrt64/bin/protoc.exe is there alongside protoc-gen-upb.exe, libprotoc.dll, etc.). The MSYS2 ucrt64 cmake toolchain appears to configure CMAKE_FIND_ROOT_PATH_MODE_* in a way that masks /ucrt64/bin from find_program even when explicitly hinted there. Rather than fight find_program's filtering rules, just check the well-known path directly with set + EXISTS. The MINGW_PREFIX env var is set by MSYS2's /etc/profile to /ucrt64 (we already verified this from the previous FATAL_ERROR diagnostic in CI). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packaging/cmake/Modules/NetdataProtobuf.cmake">
<violation number="1" location="packaging/cmake/Modules/NetdataProtobuf.cmake:102">
P1: Direct env path here can stay POSIX-shaped (`/ucrt64/...`) and break native cmake/ninja tool execution. Resolve protoc with `find_program(... NO_CMAKE_FIND_ROOT_PATH)` so the executable path is Windows-canonical.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
| # ucrt64 cmake toolchain configures CMAKE_FIND_ROOT_PATH_* | ||
| # in ways that mask /ucrt64/bin from find_program even when | ||
| # passed as HINTS. | ||
| set(_nd_protoc "$ENV{MINGW_PREFIX}/bin/protoc.exe") |
There was a problem hiding this comment.
P1: Direct env path here can stay POSIX-shaped (/ucrt64/...) and break native cmake/ninja tool execution. Resolve protoc with find_program(... NO_CMAKE_FIND_ROOT_PATH) so the executable path is Windows-canonical.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packaging/cmake/Modules/NetdataProtobuf.cmake, line 102:
<comment>Direct env path here can stay POSIX-shaped (`/ucrt64/...`) and break native cmake/ninja tool execution. Resolve protoc with `find_program(... NO_CMAKE_FIND_ROOT_PATH)` so the executable path is Windows-canonical.</comment>
<file context>
@@ -93,21 +93,23 @@ macro(netdata_detect_protobuf)
+ # ucrt64 cmake toolchain configures CMAKE_FIND_ROOT_PATH_*
+ # in ways that mask /ucrt64/bin from find_program even when
+ # passed as HINTS.
+ set(_nd_protoc "$ENV{MINGW_PREFIX}/bin/protoc.exe")
+ if(EXISTS "${_nd_protoc}")
+ set(PROTOBUF_PROTOC_EXECUTABLE "${_nd_protoc}")
</file context>
The netdata log subsystem has multiple output channels (file, syslog, systemd-journal, Windows Event Log + ETW). On Windows, the Event Log channel (nd_log-to-windows-events.c) is the native logging path and already provides full functionality, but the syslog channel still tried to compile in: - src/libnetdata/log/nd_log-common.h included <syslog.h> unconditionally just to pick up the LOG_EMERG..LOG_DEBUG numeric constants that the ND_LOG_FIELD_PRIORITY enum aliases. <syslog.h> does not exist under MSYS2 UCRT64 (Windows has no syslog daemon and no syslog C API). - src/libnetdata/log/nd_log-to-syslog.c calls openlog/syslog/closelog; those symbols do not exist on Windows. - src/libnetdata/log/nd_log-init.c calls closelog() directly in the post-fork handler. Make the implementation Windows-correct, and reject 'syslog' as an output method on Windows at config-parse time with a clear warning plus a graceful fall-back to a native Windows channel: - nd_log-config.c: when 'output = syslog' is requested on Windows, log a NDLP_WARNING explaining the channel is not supported, then fall back to 'wel' (preferred) or 'etw' or 'stderr'. The agent stays up; the user's other log channels keep working; the misconfiguration is named so a Linux netdata.conf carried across is visibly degraded rather than silently honoured. Killing the agent here would be the wrong UX because stderr is detached when netdata.exe runs as a Windows service (the MSI deployment shape), so a fatal-at-parse error would manifest as a silent service start failure with no log output anywhere. - nd_log-common.h: prefer <syslog.h> when available (detected via __has_include, with autoconf HAVE_SYSLOG_H as a secondary signal), fall back to POSIX-standard numeric LOG_* defines otherwise. Keeps this header self-contained for the wevt_netdata_mc_generate.c code generator, which compiles without netdata's autoconf chain. - nd_log-to-syslog.c: wrap the syslog implementation in #if !defined(OS_WINDOWS). Provide internal_fatal() stubs for nd_log_init_syslog and nd_logger_syslog on Windows so the NDLM_SYSLOG case arms in nd_log-init.c still link. With the config-parse re-route above these stubs are unreachable; the internal_fatal() guards catch any code path that bypasses the config gate (dev / NETDATA_INTERNAL_CHECKS builds abort loudly, production builds fall through safely). - nd_log-init.c: wrap the post-fork closelog() / re-init block with #if !defined(OS_WINDOWS). nd_log.syslog.initialized is always false on Windows, so this block was already dead at runtime there; the #if prevents the closelog() symbol from being referenced at link time. Windows users continue to get full logging via Event Log + ETW (see nd_log-to-windows-events.c). No functional change on Linux/macOS/BSD. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
1 issue found across 4 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/libnetdata/log/nd_log-config.c">
<violation number="1" location="src/libnetdata/log/nd_log-config.c:119">
P2: Fallback order reversed on Windows. Prefer ETW before WEL to match Netdata’s documented/default Windows logging behavior. Keep same priority in this error path.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
| # if defined(HAVE_WEL) | ||
| ls->method = NDLM_WEL; | ||
| fallback_name = WEL_NAME; | ||
| # elif defined(HAVE_ETW) | ||
| ls->method = NDLM_ETW; | ||
| fallback_name = ETW_NAME; |
There was a problem hiding this comment.
P2: Fallback order reversed on Windows. Prefer ETW before WEL to match Netdata’s documented/default Windows logging behavior. Keep same priority in this error path.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/libnetdata/log/nd_log-config.c, line 119:
<comment>Fallback order reversed on Windows. Prefer ETW before WEL to match Netdata’s documented/default Windows logging behavior. Keep same priority in this error path.</comment>
<file context>
@@ -107,8 +107,36 @@ void nd_log_set_user_settings(ND_LOG_SOURCES source, const char *setting) {
+ // wrong call when running as a Windows service because stderr is
+ // detached and the user would see a silent service-start failure.
+ const char *fallback_name;
+# if defined(HAVE_WEL)
+ ls->method = NDLM_WEL;
+ fallback_name = WEL_NAME;
</file context>
| # if defined(HAVE_WEL) | |
| ls->method = NDLM_WEL; | |
| fallback_name = WEL_NAME; | |
| # elif defined(HAVE_ETW) | |
| ls->method = NDLM_ETW; | |
| fallback_name = ETW_NAME; | |
| # if defined(HAVE_ETW) | |
| ls->method = NDLM_ETW; | |
| fallback_name = ETW_NAME; | |
| # elif defined(HAVE_WEL) | |
| ls->method = NDLM_WEL; | |
| fallback_name = WEL_NAME; |
…indows ExternalProject_Add()'s CONFIGURE_COMMAND for libbacktrace pointed directly at the autotools-generated configure script. On Linux and macOS the kernel honours the script's #!/bin/sh shebang and the command runs. On Windows under MSYSTEM=UCRT64, cmake and ninja are both native Windows binaries that dispatch commands via cmd.exe, which has no concept of shebangs and refuses to execute the file: 'D:\...\libbacktrace-src\configure' is not recognized as an internal or external command, operable program or batch file. Prefix the configure invocation with `bash` on Windows. bash.exe ships with MSYS2 at /usr/bin/bash.exe and is on PATH under MSYSTEM=UCRT64, so cmd.exe can dispatch to it and bash can in turn execute the configure script as a POSIX shell program. Non-Windows platforms keep the previous direct invocation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ash on Windows" This reverts commit 300ee73.
signal-code.c is pure diagnostics: it converts POSIX signal numbers
and per-signal si_code values into readable strings like
"SIGSEGV/SEGV_MAPERR" for log output. Its ENUM_STR_MAP tables name
50+ POSIX/Linux constants -- SIGUSR1, SIGCHLD, SIGCONT, SIGSTOP,
SIGRTMIN, SI_USER, SI_TIMER, SI_DETHREAD, ILL_ILLOPC, FPE_INTDIV,
SEGV_MAPERR, BUS_MCEERR, TRAP_BRKPT, etc. -- none of which UCRT64
defines and none of which fire on a native Windows process anyway.
The signal model on Windows is entirely different (SEH for memory
faults, SetConsoleCtrlHandler for Ctrl+C).
Rather than mirror 50+ #defines whose only purpose is to give a
pretty name to signals that never occur, gate the entire
table-driven body on !OS_WINDOWS and provide three stub public
functions on Windows:
* signal_code() -- still combines signo + si_code into the 64-bit
SIGNAL_CODE the rest of the codebase expects.
* SIGNAL_CODE_2str_h() -- emits the hex fallback ("0x%llx") that
the full implementation uses for unknown values anyway.
* SIGNAL_CODE_2id_h() -- parses hex via strtoull.
Effect: Windows logs that ever surface a signal code show
"0xNNNN..." instead of "SIGSEGV/SEGV_MAPERR". Acceptable because the
underlying signals never actually fire on Windows; if they ever
appeared, it would be through a different mechanism that doesn't use
these constants.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
pipe2(fds, O_CLOEXEC) is a Linux extension to POSIX. macOS has no pipe2 and the existing code already falls back to plain pipe() there; Windows has neither. Our common.h pipe() macro routes to UCRT's _pipe(fds, 65536, _O_BINARY), so plain pipe() works fine. The O_CLOEXEC bit on Linux is a thread-pipe initialisation convenience -- these notification pipes are used purely for in-process thread signalling, never inherited by spawned children -- so dropping it on Windows is correct. Extend the existing __APPLE__ gate to include OS_WINDOWS. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two standalone executables are POSIX-only:
* nd-run is a privilege-drop helper that uses <grp.h>, getpwnam(),
setresuid(), libcap, etc. -- none of which translate to Windows
(account model is SIDs and ACLs there, and netdata.exe runs as a
Windows service under a configured service account).
* spawn-tester exercises the SPAWN_SERVER_VERSION_NOFORK fork+exec
path via raw fcntl / pipe / socket primitives. Windows uses the
SPAWN_SERVER_VERSION_WINDOWS path (CreateProcess + named pipes),
which is a different implementation and is exercised through
netdata.exe directly.
Wrap both `add_executable` blocks in `if(NOT OS_WINDOWS)`. Linux,
macOS, and FreeBSD builds unchanged.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
O_NOFOLLOW is the POSIX <fcntl.h> open flag that makes open() fail when the trailing path component is a symlink. UCRT64 omits it because POSIX symlinks don't exist on Windows (NTFS reparse points are reached through entirely different APIs, not the open() file model). apps.plugin's apps_plugin.c sets `procfile_open_flags = O_RDONLY | O_NOFOLLOW` as a defence-in-depth measure when running as root. Define O_NOFOLLOW as 0 on Windows so the OR is a no-op -- the open proceeds without symlink protection, matching what we'd do anyway given S_IFLNK is also stubbed (Windows reparse points are not reachable through the POSIX file-mode path). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
apps.plugin (apps_output.c), daemon/pulse (pulse-daemon.c), exporting (send_internal_metrics.c), and unit_test.c call getrusage() with struct rusage to report the agent's own user/system CPU consumption. UCRT64 has neither the function nor the struct. Provide struct rusage with the full POSIX field set (so any caller compiles regardless of which field it reads) and an inline getrusage() backed by GetProcessTimes(). The Win32 call gives us the process's user and kernel FILETIME ticks (100 ns); we split each into seconds + microseconds and write to ru_utime / ru_stime. Other rusage fields (maxrss, page faults, IO blocks, voluntary / involuntary context switches) stay zero -- they have no direct cheap Win32 equivalent, and the self-stats charts that read them just report zero on Windows. RUSAGE_SELF / RUSAGE_THREAD / RUSAGE_CHILDREN constants are also provided. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
is_filename() in apps_pid.c uses statvfs() to confirm that a leading-slash path lives on a real filesystem (`/path`-style POSIX paths). UCRT64 has neither statvfs nor struct statvfs. On Windows the GetFileAttributesW block immediately above already handles native paths (`X:\`, `\\server\share\`, `//server/share/`), so the statvfs path was unreachable in practice on Windows. Wrap the block in `#if !defined(OS_WINDOWS)` so it compiles. Comment makes the gating intent explicit. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
ndsudo is a setuid privilege-drop helper that go.d / charts.d plugins exec to drop to the netdata user before running. It uses POSIX setuid()/setgid()/setegid() -- UCRT64 has none of them, and the concept doesn't translate: netdata.exe runs as a Windows service under a configured service account, not as root that subsequently drops privileges. Add `AND NOT OS_WINDOWS` to the NEED_NDSUDO predicate. Linux/macOS/ FreeBSD with the Go or scripts plugin enabled still build ndsudo. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
POSIX wcscasecmp() is the wide-string counterpart to strcasecmp(). UCRT64 doesn't expose the POSIX name but ships Microsoft's _wcsicmp() with identical signature and semantics (case-insensitive wide-string compare returning <0 / 0 / >0). windows-events.plugin's source-name dedup calls wcscasecmp() on the event-log channel names. Alias it via macro so the call site compiles without per-platform branching. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
claim/main.c is a standalone Windows-only .exe (NetdataClaim) -- the GUI/CLI claim-token launcher. It includes <windows.h> plus a few standard C headers but does not include libnetdata/common.h, so the wcscasecmp alias added there one commit ago doesn't reach this file. Repeat the same alias inline. _wcsicmp is the UCRT equivalent with identical signature and semantics. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The Windows kernel driver target had:
target_include_directories(netdata_driver PRIVATE BEFORE "/mingw64/include/ddk" ...)
That's a subtle bug. The cmake signature is:
target_include_directories(<target> [SYSTEM] [AFTER|BEFORE]
<INTERFACE|PUBLIC|PRIVATE> [items1...])
i.e. AFTER/BEFORE must come BEFORE the scope keyword. With PRIVATE
listed first, cmake treats `BEFORE` as an include-path string, and
since it's a relative path, the result on disk is:
-ID:/a/netdata/netdata/BEFORE (nonsense)
-I/mingw64/include/ddk (correct, but after the nonsense)
ntddk.h was being found via the implicit /ucrt64/include/ddk fallback,
but its `#include <wdm.h>` couldn't resolve because the explicit
/mingw64/include/ddk directive was misordered. Master worked here only
because the same misparse used a path that happened to coincidentally
exist in the MSYS-runtime layout; under UCRT64 it doesn't.
Swap to the correct ordering: BEFORE PRIVATE.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
daemon.c performs POSIX daemonization (fork + setsid + setuid + chown
of run/log directories) and POSIX scheduling priority changes
(sched_setscheduler with SCHED_BATCH/SCHED_IDLE). On Windows the agent
runs as a service hosted by the SCM -- none of these apply. Privileges
are configured via ACLs at install time; scheduling priority is
controlled via SetPriorityClass/SetThreadPriority, not POSIX sched_*.
UCRT64 doesn't declare any of: chown, dirfd, unlinkat, getuid, geteuid,
getgid, getegid, setuid, seteuid, setgid, setegid, setgroups, fork,
setsid, sched_getparam, sched_setscheduler, struct sched_param,
SCHED_OTHER/SCHED_BATCH/SCHED_IDLE.
Stub everything as no-ops in the OS_WINDOWS block. Stubs:
* chown/fchown -> return 0 (already-stubbed fchown was a hint)
* dirfd -> return -1 (callers handle "no dir fd")
* unlinkat -> forwards to unlink() ignoring the dir fd; relative
paths resolve to CWD, which matches what daemon.c expects when
the dir fd was supposed to be a parent it had cd'd to anyway.
* get*id / set*id / setgroups -> succeed silently as the running
process is effectively root in the Windows-service model.
* fork / setsid -> return -1 with ENOSYS. daemon.c calls these
only when -D is set on the command line; that flag is never used
by the Windows service-host wrapper.
* sched_* -> succeed silently with priority 0.
Effect on Windows: daemonization is a series of successful no-ops,
the service host then proceeds with its own startup. Linux/macOS/
FreeBSD code paths are untouched -- the real POSIX functions stay
in scope via the system <unistd.h>.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ram shim
Previous commit re-declared struct sched_param and sched_setscheduler
in the OS_WINDOWS block, conflicting with the definitions that
winpthreads ships in <sched.h> (transitively included via <pthread.h>).
gcc rejected the duplicates with "redefinition of 'struct sched_param'"
and "conflicting types for 'sched_setscheduler'".
mingw-w64's <sched.h> already provides:
* struct sched_param
* SCHED_OTHER / SCHED_FIFO / SCHED_RR
* sched_setscheduler / sched_getscheduler / sched_yield /
sched_get_priority_min / sched_get_priority_max
What it does NOT provide -- and what daemon.c actually needs:
* sched_getparam (read the current priority)
* SCHED_BATCH / SCHED_IDLE (Linux-only policies)
Include <sched.h> explicitly so the winpthreads pieces are in scope,
then add just sched_getparam() as a no-op stub and SCHED_BATCH/
SCHED_IDLE as fallback constants. Pure addition; no conflicting
redefinitions.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… args Two follow-ups exposed by this round: 1. signal-handler.c references SIGUSR2 (and SIGUSR1 under FSANITIZE_ADDRESS) in its signal-action table; signals.c's deadly list also needs SIGUSR2/SIGCHLD/etc. Previous round shimmed only the deadly-signal subset (BUS/SYS/XCPU/XFSZ); add the remainder (HUP/QUIT/USR1/USR2/CHLD). Renumber the existing SIGBUS/SIGSYS shims to glibc values to keep every SIG* macro distinct -- previously SIGBUS=10 collided with the glibc-style SIGUSR1=10. New layout follows glibc/Linux numbering throughout, chosen so each macro stays distinct from each other AND from the C-standard signals UCRT actually raises. 2. netdata_registry_get_dword / netdata_registry_get_dword_from_open_key declared their `out` parameter as `unsigned int *` but win_system-info.c (and any other Windows caller) passes `DWORD *`. Under LLP64 both are 32-bit but `unsigned int` and `unsigned long` are distinct types -- gcc rejects the implicit cast. Change the signatures and the function bodies to use `DWORD *`. RegQueryValueEx already expects LPBYTE there so the cast inside is unchanged. Also fix the length parameter from a hardcoded 260 (which is FILENAME_MAX, not the size of a DWORD) to sizeof(DWORD). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The previous `target_include_directories(... "/mingw64/include/ddk")`
literal worked under the MSYS cmake (a Cygwin binary that POSIX-
translated leading-slash paths transparently). Under the UCRT64
cmake we now use, there is no POSIX translation: `/mingw64/...`
gets interpreted as a Windows root-relative path and resolves to
<build-drive>:\mingw64\..., which never exists.
Outcome: ntddk.h was being found via the implicit /ucrt64/include/ddk
fallback (the UCRT64 toolchain's default system include path), but
its `#include <wdm.h>` could not resolve because the explicit
"/mingw64/include/ddk" -I directive pointed nowhere on disk.
Use $ENV{MINGW_PREFIX} so cmake substitutes the real prefix the
toolchain is using (/ucrt64 under MSYSTEM=UCRT64, /mingw64 under
MSYSTEM=MINGW64). The DDK headers ship in the same upstream
mingw-w64-headers package and live under the same <prefix>/include/ddk
relative path in every environment; only the prefix itself differs.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Three POSIX file-ops UCRT64 doesn't ship:
* fchmod(fd, mode) -- status-file-io.c uses it to set 0664 on the
temp file before rename. Windows permissions are ACL-based, not
POSIX mode bits; stub returns 0 so the call is informational.
* fsync(fd) -- UCRT's _commit(fd) is the documented equivalent,
same signature and same semantic (flush buffered modifications
to disk). Forward via macro.
* utimensat(dirfd, path, times[2], flags) -- POSIX *at-family
timestamp updater with nanosecond precision. UCRT has _utime64
(sec precision, path-based, no dir-fd). machine-guid.c calls
utimensat(AT_FDCWD, path, times, 0); route through _utime64
with sec-precision truncation. The persisted GUID-file mtime is
diagnostic, not load-bearing, so the truncation is acceptable.
AT_FDCWD added as a sentinel value the stub ignores. Linux/macOS/
FreeBSD continue to use the real fchmod/fsync/utimensat from
<unistd.h> / <fcntl.h>.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Winsock declares recv() and send() with `char *` / `const char *` buffer arguments; POSIX uses `void *` / `const void *`. C call sites (libnetdata/socket/nd-sock.h's static inlines) pass `void *` directly and rely on the implicit conversion -- which works in C with a warning but is outright rejected in C++. ml/ad_charts.cc includes nd-sock.h transitively and hit the failure: "invalid conversion from 'void*' to 'char*'" on the recv/send calls inside nd_sock_revc_nowait / nd_sock_peek_nowait / nd_sock_send_nowait. Same fix pattern as get/setsockopt one commit ago: self-referencing macros that cast the buffer arg to char * / const char *. C99 6.10.3 guarantees the inner recv/send resolve to the Winsock functions, not the macros. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
UCRT64 has no POSIX unsetenv(). The documented Microsoft equivalent
is _putenv("NAME=") -- an empty value triggers the delete-the-variable
path. rrdhost-labels.c calls unsetenv() to remove a variable from the
process environment after reading it.
Wrap with the POSIX signature: validate that the name has no '=' (per
POSIX EINVAL), allocate a NUL-terminated "NAME=" string, and call
_putenv. Free the buffer before returning so we don't leak; UCRT's
_putenv copies the value internally and is safe to free after.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
POSIX XSI random()/srandom() are 31-bit linear-congruential RNGs; UCRT64 has only C-standard rand()/srand() (15-bit per call). dbengine-stresstest.c uses random() to pick chart/dim indices during stress runs -- the reduced range from rand (RAND_MAX = 0x7FFF) is acceptable for a stress-test helper, all the values consumed are modulo'd to small bounds anyway. Alias the names via macro. srandom takes the seed as a long; UCRT srand takes unsigned -- cast in the macro. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
-rdynamic asks the linker to export all dynamic symbols so backtrace() and friends can resolve them at runtime. ELF (Linux/FreeBSD) and Mach-O (macOS) linkers support it; the mingw-w64 binutils ld variant that the UCRT64 toolchain uses on Windows does not -- PE/COFF symbol export works through __declspec(dllexport) or a .def file instead. NetdataClaim.exe and windows-events.plugin.exe both failed to link with "cc.exe: error: unrecognized command-line option '-rdynamic'". Guard the add_link_options(-rdynamic) call with NOT OS_WINDOWS. The compile-side frame-pointer / unwind-table flags are unchanged -- those work fine on Windows. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
UCRT64 has no POSIX link() (create hard link). Windows exposes the equivalent through Win32: CreateHardLinkA(new, existing, NULL). NTFS supports hard links natively. The registry rotation in registry_db.c uses link(current, ".old") followed by unlink(current) to do an atomic backup before writing the new database -- if anything goes wrong mid-write, the .old copy still exists. The same pattern works on Windows via the hard-link equivalent. Wrap CreateHardLinkA with the POSIX link() signature: int return, 0 on success, -1 with errno on failure. Map the common Win32 error codes to POSIX errnos so the caller's `errno != ENOENT` test still behaves correctly. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
POSIX shutdown(fd, how) takes SHUT_RD / SHUT_WR / SHUT_RDWR for the direction. Winsock's shutdown() takes SD_RECEIVE / SD_SEND / SD_BOTH -- same numeric values, different names. mingw-w64's <winsock2.h> defines the SD_* names but not the POSIX SHUT_* aliases. stream-receiver.c shutdowns the streaming socket with SHUT_RDWR. Alias the three POSIX names via #define so the call sites compile unchanged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
POSIX 2008 added the st_mtim / st_atim / st_ctim struct timespec fields to struct stat for nanosecond-resolution timestamps. UCRT's struct stat predates this and exposes only the second-resolution st_mtime / st_atime / st_ctime fields. The existing #ifdef __APPLE__ ... #else branch picked st_mtimespec on macOS and st_mtim everywhere else. Add an OS_WINDOWS branch that reads st_mtime directly. Second precision is fine here -- the value feeds an HTTP "Date" header that has only second resolution anyway. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
websocket-handshake.c sets the command-pipe read side to non-blocking via fcntl(F_SETFL, O_NONBLOCK) so the poll-driven thread can drain all signal bytes without a final blocking read. UCRT64 has no fcntl(), and anonymous pipes from _pipe() aren't trivially switchable to non-blocking under Win32 (SetNamedPipeHandleState applies to named pipes; CRT-fd pipes have no documented per-fd toggle). The websocket command pipe carries short, well-bounded signal bytes, not a streaming workload. A blocking short-read of a single signal byte is fine in practice -- the poll/nd_poll layer wakes the thread, the read pulls one byte, the loop continues. Wrap the fcntl() call with `#if !defined(OS_WINDOWS)`. Linux/macOS/ FreeBSD behaviour is unchanged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
netdata.exe failed to link at the very end of the build with hundreds of undefined references to Abseil symbols: absl::lts_20260107::status_internal::StatusRep::Unref() absl::lts_20260107::hash_internal::MixingHashState::kSeed absl::lts_20260107::hash_internal::CombineLargeContiguousImpl... google::protobuf::internal::ThreadSafeArena::thread_cache_ ... Root cause: the NetdataProtobuf.cmake Windows branch hardcoded `set(PROTOBUF_LIBRARIES "-lprotobuf")` and stopped there. Protobuf 22+ links against Abseil; MSYS2's mingw-w64-ucrt-x86_64-protobuf (v33.x) ships protobuf-config.cmake which declares the abseil deps as transitive requirements of protobuf::libprotobuf. The bare `-lprotobuf` linker arg pulled in libprotobuf.a only and dropped abseil on the floor. Switch the Windows branch to use find_package(Protobuf CONFIG REQUIRED) -- same path the Linux branch already uses -- so the abseil deps come along automatically through the protobuf::libprotobuf target. The protoc.exe location detection stays unchanged (still uses MINGW_PREFIX explicitly; find_program-via-package would still fail to locate it under the CMAKE_FIND_ROOT_PATH_* policy on the MSYS2 ucrt64 toolchain). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The Windows install step hard-coded three MSYS-runtime DLLs from /usr/bin: msys-protobuf-32.dll, msys-yaml-0-2.dll, msys-uv-1.dll. Those are the Cygwin-style libraries the MSYS shell build linked against. Under MSYSTEM=UCRT64 we link against native Windows libs from $MINGW_PREFIX/bin with different names -- libprotobuf-33.X.dll, libyaml-0-2.dll, libuv-1.dll, plus libabsl_*.dll (the Abseil dependencies that protobuf 22+ pulls in). The hardcoded path made the install step fail with: file INSTALL cannot find "/usr/bin/msys-protobuf-32.dll" Switch to a globbed list of $MINGW_PREFIX/bin/lib*.dll patterns that covers everything netdata.exe / plugins are likely to load at runtime. Glob rather than hard-list the abseil files: 40+ libabsl_* DLLs exist and the set changes with each upstream release. CONFIGURE_DEPENDS so cmake re-evals if the MSYS2 package set changes. Coverage: protobuf + abseil, yaml, uv, openssl/libcrypto, libcurl and its TLS-stack deps (gnutls, nettle, gmp, hogweed, tasn1, unistring, p11-kit, libssh2, idn2, psl, nghttp*), the gcc/stdc++ runtime and winpthreads, plus the compression libs (zlib, lz4, zstd, brotli) and pcre2. Also relocate the ssl-cert directory copy from /usr/ssl (MSYS location) to $MINGW_PREFIX/etc/ssl (UCRT64 location); curl looks for ca-bundle there. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|




Re-opens #22535 as a same-repo PR so workflow-file edits on this branch take effect for this PR's CI. The previous fork-based PR could not modify its own CI behavior — base-branch workflow files were used. Same commits, same content; only the head repository changed.
Summary
rust-demostaticlib smoke crate (src/crates/rust-demo/) wired into the mainnetdatatarget via a newENABLE_RUST_DEMOoption (defaultOff). The Windows build flips this toOnat the end of the migration to validate Rust-on-Windows end-to-end.What's in the PR
Commits already landed:
8733eadfrust-demosmoke crate (Cargo.toml, src/lib.rs, hand-written rust_demo.h) and wire it intoCMakeLists.txtbehind a newENABLE_RUST_DEMOoption. Adds onenetdata_log_info(\"RUST FFI smoke: …\")call next to the existingNETDATA STARTUPlog line.0b022181compile-on-windows.shpasses-DENABLE_RUST_DEMO=Offduring migration.da82bd03MSYSTEM=UCRT64in every PowerShell entry point; require it inNetdataPlatform.cmakewith aFATAL_ERRORotherwise; drop the explicit-DRust_COMPILER(Corrosion finds rustc/cargo on PATH under UCRT64); replace the MSYS and MINGW64 CLion.batfiles with a single UCRT64 variant.ab6f3e65packaging/windows/LOCAL_DEV_LINUX.md) plusdev-vm.shwrapper.bffb496e/usr/bin/cmake→cmake; installmingw-w64-ucrt-x86_64-{cmake,ninja}). FlipENABLE_RUST_DEMOdefault toOffso source-tarball builds without Rust toolchain don't break.d46fba1dCMAKE_INSTALL_PREFIXcheck to accept both/opt/netdataand the UCRT64-cmake-canonicalisedC:/msys64/opt/netdata.Background
Full investigation, ABI analysis, and migration plan in SOW-0033. SOW-0032 tracks the rust-demo smoke crate as the Rust-on-Windows validator (resumes at Phase 7 of SOW-0033).
Why draft
Test plan
CMAKE_INSTALL_PREFIXcheck (fixed ind46fba1d); next CI signal will be from Phase 3 (cygwin_conv_path removal).cygwin_conv_path()in netdata C source.ntldd netdata.exeagainst the staged installer payload confirms no transitively-required DLL is missed.RUST FFI smoke: rust-demo 0.1.0 reports nd_rust_add(2, 3) = 5.🤖 Generated with Claude Code
Summary by cubic
Migrates the Windows build to MSYS2 UCRT64, drops Cygwin, and adds Windows‑native shims so the agent builds and runs without
msys-2.0.dll. Replaces the Event Log pipeline with a Rustwevt-builderand updates packaging to bundle UCRT64 runtime DLLs.Migration
MSYSTEM=UCRT64; use UCRTcmake/ninja; define_CRT_RAND_S; use systemlibbacktraceviapkg-config; locateprotoc.exeunder$MINGW_PREFIX/bin; on Windows, usefind_package(Protobuf CONFIG)soprotobuf::libprotobufpulls Abseil; accept UCRT‑canonicalCMAKE_INSTALL_PREFIX; replace Event Log scripts with the Rustwevt-builder; skip-rdynamicon Windows; bundle UCRT64 runtime DLLs from$MINGW_PREFIX/bin(protobuf+Abseil, yaml, uv, curl/OpenSSL, runtimes, compression libs) and copy certs from$MINGW_PREFIX/etc/ssl.rwin; gate POSIX‑only targets (nd-run,spawn-tester,ndsudo) to non‑Windows; fixnetdata_driverincludes via$MINGW_PREFIX/include/ddk; add Linux→Windows VM walkthrough +dev-vm.sh; provide a CLionucrt64environment.Portability
sock_setnonblock()/sock_setcloexec(); treatMSG_DONTWAITas no‑op; aliasSHUT_*to WinsockSD_*; castrecv/sendbuffers for Winsock; usepipe()for notification pipes and avoid non‑blockingfcntl()on Windows pipes.mmap/munmap/msyncshim;posix_memalign()via_aligned_malloc/_aligned_free; introducend_mkdir(); addos_dirent_type(); stubreadlink()/lstat(); addfchmod()stub,fsync()via_commit,utimensat()via_utime64, andlink()viaCreateHardLinkA; replace Cygwin path calls with native translators.syslogto Event Log/ETW with a clear warning; short‑circuit journald helpers; addnd_tm_gmtoff()and ansscanf()RFC‑3339 parser; providestrsep()/strcasestr()/wcscasecmp(), endian macros,strerror_r()shim, and minimalsysconf()/getrlimit()/getrusage()shims; aliasrandom()/srandom(); set web “Date” header fromst_mtimeon Windows.close_range(); spawn‑server fixes for native handles and path translation; stub POSIX process/privilege APIs and scheduling (keep asched_getparamshim); provide POSIX signal‑number shims and hex‑fallback diagnostics; align registry helpers to useDWORD*.Written for commit d53ddad. Summary will update on new commits. Review in cubic