Skip to content

feat: Add Windows platform support (MSVC and MinGW)#14

Merged
movingpictures83 merged 3 commits into
FIUBioRG:masterfrom
quinnjr:feature/windows-support
May 22, 2026
Merged

feat: Add Windows platform support (MSVC and MinGW)#14
movingpictures83 merged 3 commits into
FIUBioRG:masterfrom
quinnjr:feature/windows-support

Conversation

@quinnjr

@quinnjr quinnjr commented May 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds Windows platform support to PluMA's C++ core (MSVC and MinGW toolchains) and to the SConstruct build configuration. The implementation is non-invasive on Unix: existing Linux / macOS builds compile and link identically, and all current upstream contributions (Rust loader, parallel scheduler, plugin venv, build fixes from PRs #7, #8, #10, #11, #13) are preserved unchanged.

What it adds

C++ core

  • src/platform.h — single header that abstracts the three POSIX primitives PluMA's core relies on but Windows lacks or names differently:
    • dlopen / dlsym / dlclose / dlerrorLoadLibrary / GetProcAddress / FreeLibrary / Windows error formatting on _WIN32
    • glob / glob_t → a Windows shim built on FindFirstFile / FindNextFile
    • POSIX path separators / unistd.h / pthread includes → conditional wrappers
  • src/main.cxx, src/languages/Compiled.cxx, src/languages/Language.{cxx,h} — use src/platform.h instead of including <dlfcn.h> / <glob.h> / <unistd.h> directly.

Build system

  • build_config.py — adds is_msvc and is_mingw toolchain detection (alongside the is_windows / is_darwin / is_linux / is_alpine flags upstream master already provides) and platform-specific filename conventions (shared_lib_ext, shared_lib_prefix, executable_ext, path_separator). Windows overrides lib_search_path and include_search_path because the /lib + /usr/lib + /usr/local/lib convention doesn't apply.
  • SConstruct:
    • get_platform_config() picks up Windows / MSVC / MinGW branches that set PLUMA_PLATFORM_WINDOWS, WIN32_LEAN_AND_MEAN, and NOMINMAX defines (so src/platform.h selects the LoadLibrary / GetProcAddress code path). MinGW additionally gets -Wl,--export-all-symbols and psapi linkage.
    • create_base_environment() splits CCFLAGS / CXXFLAGS into an MSVC branch (/EHsc /utf-8 /O2) and a gcc-style branch (-fpermissive -fPIC -O2).
  • .github/workflows/windows-build.yml — Windows CI smoke test using windows-latest runners with both Visual Studio and MinGW.

What it does not do (deferred)

  • Rust plugin loading on Windows. src/languages/Rust.cxx (added by PR Add Rust language support for PluMA plugins #8) still uses POSIX dlopen / dlsym directly rather than the src/platform.h abstraction. Threading the abstraction through the Rust loader is a small but separable follow-up; the main pluma binary still builds on Windows without it, and Rust plugin support remains Unix-only for now.
  • Python / Perl / R embedded interpreters on Windows. Each of those embeds an upstream interpreter that has its own Windows story (Python is fine; Perl on Windows needs a strawberry-perl-style build; R on Windows requires Rtools alignment). Out of scope for this PR.
  • Java plugin loading on Windows. JNI itself is portable; the plugin-discovery glob path needs the same src/platform.h treatment as the Rust loader before Windows-side Java plugins can be loaded.

Compatibility

  • Linux / macOS: unchanged. Verified on Arch Linux (clang 21 / R 4.6 / perl 5.42 / Python 3.14 / OpenJDK 17) that scons --with-rust still produces a working pluma binary with dlsym imported (i.e. HAVE_RUST wiring from PR build(scons): fix master build and wire --with-rust through to HAVE_RUST #13 intact).
  • Windows: build target is the C++ core. The accompanying CI workflow exercises the SConstruct branches on windows-latest with both MSVC and MinGW.

Notes on the merge

The branch was originally cut from 819d31a (pre-PR-#7), before the SConstruct refactor and the subsequent Rust / parallel / venv / build-fix series merged. To bring the branch onto current master without rewriting upstream history, I merged upstream/master in and resolved by taking master's refactored versions of SConstruct / build_config.py / build_support.py and re-applying the Windows-specific additions on top. The single merge commit (9563464) captures that resolution; the two original Windows commits (5f1d6e8 for the platform layer, b50ddad for CI) are unchanged.

Test plan

  • scons --with-rust on Linux produces a pluma binary with dlsym imported (HAVE_RUST wired)
  • nm pluma | grep -c dlsym returns ≥ 1
  • Existing Catch2 tests on master continue to build via the CMake test harness
  • Windows CI smoke test passes on the PR's GitHub Actions run
  • MSVC and MinGW builds both produce a pluma.exe

🤖 Generated with Claude Code

quinnjr and others added 3 commits May 14, 2026 12:01
Implements cross-platform support for building PluMA on Windows with both
MSVC and MinGW compilers, while maintaining full compatibility with Linux
and macOS builds.

- Platform detection macros (PLUMA_PLATFORM_WINDOWS, PLUMA_PLATFORM_UNIX, etc.)
- Cross-platform dynamic library loading (dlopen/LoadLibrary abstraction)
- Windows glob emulation for directory pattern matching
- File system utilities (fileExists, removeFile, getCurrentDirectory, etc.)
- Platform-specific path separators and shared library extensions
- DLL export/import macros for Windows

- src/main.cxx: Use platform abstraction for paths, env vars, file operations
- src/languages/Language.cxx: Use platform-agnostic library loading
- src/languages/Language.h: Include platform.h, conditionally use glob
- src/languages/Compiled.cxx: Use platform abstraction for dynamic loading

- SConstruct: Full Windows/MSVC/MinGW support with proper compiler flags
- build_config.py: Platform detection, Windows paths, MSVC/MinGW detection
- build_support.py: Windows Python config, MSVC/MinGW flags, cross-platform R detection

- Supports MSVC (Visual Studio) compiler on Windows
- Supports MinGW (GCC) compiler on Windows
- Automatic compiler detection and flag configuration
- Cross-platform shared library extension handling (.dll/.so/.dylib)
- Windows-compatible path handling (backslash separators, semicolon path lists)
- Maintains backward compatibility with Linux and macOS builds

With MSVC (Visual Studio Developer Command Prompt):
  scons

With MinGW:
  scons

- Perl and R support on Windows requires appropriate installations
- CUDA support on Windows uses NVIDIA's standard Windows paths

Co-authored-by: Claude <noreply@anthropic.com>
Adds a comprehensive Windows build workflow that:
- Tests both MSVC and MinGW compilers
- Tests Python 3.11 and 3.12
- Installs all required dependencies (SWIG, Perl, R, Rcpp, RInside)
- Builds PluMA with various language configurations
- Uploads build artifacts on success

The workflow runs on:
- Push to master, develop, and feature/windows-support branches
- Pull requests to master and develop

Co-authored-by: Claude <noreply@anthropic.com>
Brings the windows-support work onto current master (post PRs FIUBioRG#7, FIUBioRG#8,
FIUBioRG#10, FIUBioRG#11, FIUBioRG#13) and reconciles the build configuration. The branch was
originally cut from 819d31a, before the SConstruct refactor and the
Rust / parallel / venv / build-fix series merged; a direct rebase
would have rewritten history beyond recognition, so we instead merge
master in and re-apply the windows-specific additions on top of the
refactored build files.

Resolution strategy:
- SConstruct, build_config.py, build_support.py: take master's
  post-refactor versions wholesale, then layer the windows-only
  additions on top.
- All other files (the Rust loader, the parallel scheduler, the
  Catch2 tests, the fuzz harness) merge cleanly from master with no
  intervention.

Windows-specific additions preserved:
- build_config.py gains is_msvc / is_mingw toolchain detection
  (alongside the is_windows / is_darwin / is_linux / is_alpine flags
  master already defines), an is_unix convenience flag, and
  platform-specific shared_lib_ext / shared_lib_prefix /
  executable_ext / path_separator constants. Windows overrides
  lib_search_path and include_search_path because the /lib +
  /usr/lib + /usr/local/lib convention doesn't apply.
- SConstruct's get_platform_config() picks up Windows /
  MSVC / MinGW branches that set PLUMA_PLATFORM_WINDOWS,
  WIN32_LEAN_AND_MEAN, and NOMINMAX defines (so src/platform.h
  selects the LoadLibrary / GetProcAddress code path) and, for
  MinGW, --export-all-symbols + psapi.
- create_base_environment() splits CCFLAGS / CXXFLAGS into MSVC
  (/EHsc /utf-8 /O2) and gcc-style branches.
- src/platform.h is preserved from the original branch and used by
  src/main.cxx and the language loaders to abstract dlopen / glob /
  pthread away from POSIX-specific includes.

Verified on Linux: clean scons build with --with-rust still produces
a pluma binary that imports dlsym (HAVE_RUST wiring intact); the
binary has all the upstream PRs' contributions present.
@movingpictures83 movingpictures83 merged commit 81c4be3 into FIUBioRG:master May 22, 2026
3 of 5 checks passed
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.

2 participants