Skip to content

Native build on Windows - #3309

Open
yorickreum wants to merge 2 commits into
NanoComp:masterfrom
yorickreum:windows-native-build
Open

yorickreum wants to merge 2 commits into
NanoComp:masterfrom
yorickreum:windows-native-build

Conversation

@yorickreum

Copy link
Copy Markdown
Contributor

Turns out that not much needs to be adjusted to be able to build and run MEEP natively on Windows (with MYSY2 UCRT64)... All required changes are in the first commit, the second commit adds a Windows CI runner.

Addresses #385

Comment thread python/tests/test_mpb.py
ref_fname = "tutorial-e.k16.b08.z.tm.h5"
ref_path = os.path.join(self.data_dir, ref_fname)
res_path = re.sub("tutorial", ms.filename_prefix, ref_fname)
res_path = ref_fname.replace("tutorial", ms.filename_prefix)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes seem unrelated to this PR. Perhaps they can be part of a separate PR?

@yorickreum yorickreum Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes seem unrelated to this PR. Perhaps they can be part of a separate PR?

They are required to get the test script to run on Windows.

filename_prefix is os.path.join(self.temp_dir, ...), so on Windows it's an absolute path like C:\Users\...\meep-abc\test_foo-0. As the replacement argument to re.sub that's a template. \U raises re.error: bad escape \U.

So all of these tests errored out before even reaching compare_h5_files.

Even when it doesn't raise, a prefix containing \t or \1 would be silently rewritten. str.replace takes the string literally and behaves identically on POSIX (where the replacement never contains a backslash...).

None are reachable on Linux or macOS, so they have gone unnoticed; four are
latent bugs rather than build breakage.

Source:

* output_directory.cpp: Windows mkdir() takes one argument, and its remove()
  fails on directories, so nftw() aborted and delete_directory() removed
  nothing at all.
* meepgeom.cpp: epsilon-input-file is split on strrchr(fname, ':'), so
  "C:\dir\eps.h5" became the filename "C" and the failed H5Fopen aborted.
* mympi.cpp: _GNU_SOURCE came after <cstdlib>, too late to declare
  vasprintf() on mingw-w64.
* tests/h5test.cpp: POSIX sync() does not exist there, breaking the C++ test
  suite's compile.

Build:

* Windows DLLs may not contain undefined symbols; without -no-undefined
  libtool silently emits a static archive.
* PYTHON_LIBS was referenced but never set.  Empty is right on Unix, where
  modules take their symbols from the interpreter; on Windows they must link
  the Python library.  Module suffixes (.so vs .pyd) are chosen per host too.
* _mpb linked only libpympb, relying on transitive resolution Windows does
  not permit.  Both modules use -avoid-version now, as no platform imports a
  versioned extension module.
* sphere-quad.h's rule ignored $(EXEEXT).
* TESTS_ENVIRONMENT built PYTHONPATH from $(abs_top_builddir): an MSYS
  "/c/..." path joined with ":", neither readable by native Python.
* test_mpb.py passed a path as an re.sub() replacement, where backslashes are
  escapes.

A native build also needs lt_cv_deplibs_check_method=pass_all; libctl,
harminv, mpb and libGDSII need their own fixes.
Builds and tests Meep on windows-latest via MSYS2.  No dependency needs
patching: harminv is built static, MPB already carries -no-undefined, and the
one libctl omits is supplied on the make command line.  The reasoning behind
the less obvious choices -- UCRT64 over MINGW64, pass_all, libctl from a
release tarball, and vendoring the runtime DLLs beside _meep.pyd -- is in
comments in the workflow.
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