Skip to content

[python][win] use .dll for shared lib test, catch error for win32 workaround - #126

Merged
aaronj0 merged 2 commits into
compiler-research:mainfrom
aaronj0:windows-portability
Oct 1, 2026
Merged

aaronj0 merged 2 commits into
compiler-research:mainfrom
aaronj0:windows-portability

Conversation

@aaronj0

@aaronj0 aaronj0 commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

@guitargeek guitargeek left a comment

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.

Since you're already fixing for different shared object extensions, this should be done consistently in the other places that hardcode .so as well.

So I'd suggest complementing the PR with this patch:

diff --git a/test/Makefile b/test/Makefile
index 7f1433e..7c89130 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,6 +1,11 @@
 # the C++ sides of the tests live under cpp/ and build into shared
 # libraries next to their sources (load_reflection_info resolves the
-# header as a sibling of the loaded Dict.so)
+# header as a sibling of the loaded Dict library)
+soext = .so
+ifeq ($(OS),Windows_NT)
+  soext = .dll
+endif
+
 dictnames = advancedcpp \
             advancedcpp2 \
             conversions \
@@ -17,7 +22,7 @@ dictnames = advancedcpp \
             stltypes \
             templates

-dicts = $(addprefix cpp/,$(addsuffix Dict.so,$(dictnames)))
+dicts = $(addprefix cpp/,$(addsuffix Dict$(soext),$(dictnames)))

 all : $(dicts)

@@ -30,11 +35,11 @@ ifeq ($(PLATFORM),Darwin)
 endif

 # a worker can load the library while another rebuilds it, so publish it whole
-cpp/%Dict.so: cpp/%.cxx cpp/%.h
+cpp/%Dict$(soext): cpp/%.cxx cpp/%.h
        $(CXX) $(cppflags) -shared -o $@.$$$$.tmp $< && mv -f $@.$$$$.tmp $@

diff --git a/test/Makefile b/test/Makefile
index 7f1433e..7c89130 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,6 +1,11 @@
 # the C++ sides of the tests live under cpp/ and build into shared
 # libraries next to their sources (load_reflection_info resolves the
-# header as a sibling of the loaded Dict.so)
+# header as a sibling of the loaded Dict library)
+soext = .so
+ifeq ($(OS),Windows_NT)
+  soext = .dll
+endif
+
 dictnames = advancedcpp \
             advancedcpp2 \
             conversions \
@@ -17,7 +22,7 @@ dictnames = advancedcpp \
             stltypes \
             templates

-dicts = $(addprefix cpp/,$(addsuffix Dict.so,$(dictnames)))
+dicts = $(addprefix cpp/,$(addsuffix Dict$(soext),$(dictnames)))

 all : $(dicts)

@@ -30,11 +35,11 @@ ifeq ($(PLATFORM),Darwin)
 endif

 # a worker can load the library while another rebuilds it, so publish it whole
-cpp/%Dict.so: cpp/%.cxx cpp/%.h
+cpp/%Dict$(soext): cpp/%.cxx cpp/%.h
        $(CXX) $(cppflags) -shared -o $@.$$$$.tmp $< && mv -f $@.$$$$.tmp $@

-# convenience: `make datatypesDict.so` builds cpp/datatypesDict.so
-%Dict.so: cpp/%Dict.so ;
+# convenience: `make datatypesDict$(soext)` builds cpp/datatypesDict$(soext)
+%Dict$(soext): cpp/%Dict$(soext) ;

 .PHONY: test clean

diff --git a/test/support.py b/test/support.py
index 91fab8e..94c4738 100644
--- a/test/support.py
+++ b/test/support.py
@@ -45,7 +45,7 @@ def setup_make(targetname, optional=False):
         if fcntl is not None:
             fcntl.flock(lockf, fcntl.LOCK_EX)
         popen = subprocess.Popen(
-            ["make", targetname + "Dict.so"],
+            ["make", targetname + "Dict" + soext],
             cwd=str(currpath),
             stdout=subprocess.PIPE,
             stderr=subprocess.STDOUT,

Comment thread test/support.py
test03_add_library_path hardcodes .so for the library it copies and
loads, so on Windows the load can never succeed (the dictionary is a
.dll there), and the test Makefile and setup_make build and name the
dictionaries as Dict.so as well. Derive the extension from the platform
once, in support.py next to the other platform facts and as soext in
the Makefile, and use it everywhere the dictionaries are built or
loaded. Once the load succeeds, the library is mapped into the process
and Windows refuses to delete it, so the temporary directory is cleaned
up with ignore_cleanup_errors.

Seen on the Windows CI of ROOT's cppjit migration branch, which is
currently the only Windows coverage the test suite gets.
The Windows workaround declares an explicit specialization of
std::endl<char> at import time. When std::endl<char> was already
instantiated in the interpreter, as it is when cppjit is imported into a
process that loaded iostream-using headers before it (ROOT's PyROOT), the
declaration is ill-formed and cppdef raises SyntaxError, which aborts the
import. Ignore that error: the instantiation the workaround wants already
exists.
@aaronj0
aaronj0 force-pushed the windows-portability branch from 4250d87 to 67116c8 Compare October 1, 2026 09:41

@guitargeek guitargeek left a comment

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.

LGTM! Thanks for these Windows fixes

@aaronj0
aaronj0 merged commit 7dc6bf0 into compiler-research:main Oct 1, 2026
25 checks passed
@aaronj0
aaronj0 deleted the windows-portability branch October 1, 2026 12:36
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.

3 participants