Skip to content

Commit b2344c3

Browse files
committed
[runtime-cxxmodules] Generate std_darwin.modulemap from active SDK
Dynamically extract and wrap the system modulemap from the active SDK in a top-level 'std' module Also remove 'std_ctype_h' module to break cyclic dependencies.
1 parent 038ee1f commit b2344c3

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/env python3
2+
import os
3+
import re
4+
import subprocess
5+
import sys
6+
7+
8+
def get_sdk_path():
9+
result = subprocess.run(["xcrun", "--show-sdk-path"], capture_output=True, text=True)
10+
if result.returncode != 0:
11+
raise RuntimeError("Could not resolve SDK path")
12+
return os.path.realpath(result.stdout.strip())
13+
14+
15+
def remove_ctype_module(content):
16+
# Break cyclic module dependencies
17+
# See: https://github.com/root-project/root/commit/8045591a17125b49c1007787c586868dea764479
18+
pattern = re.compile(r"module\s+std_ctype_h\s+\[system\]\s*\{.*?\}", re.DOTALL)
19+
return pattern.sub("", content)
20+
21+
22+
def main():
23+
if len(sys.argv) < 2:
24+
raise ValueError("Usage: std_modulemap_darwin_fix.py <output_path>")
25+
output_path = sys.argv[1]
26+
sdk = get_sdk_path()
27+
cpp_modulemap = os.path.join(sdk, "usr/include/c++/v1/module.modulemap")
28+
29+
if not os.path.exists(cpp_modulemap):
30+
raise FileNotFoundError(f"Cannot find libc++ modulemap at {cpp_modulemap}")
31+
32+
with open(cpp_modulemap, "r") as f:
33+
original_content = f.read()
34+
35+
cleaned_content = remove_ctype_module(original_content)
36+
37+
os.makedirs(os.path.dirname(output_path), exist_ok=True)
38+
with open(output_path, "w") as f:
39+
f.write("// Auto-generated flat modulemap for Cling\n")
40+
f.write("module std [system] {\n")
41+
f.write("export *\n\n")
42+
f.write("// Entire modulemap wrapped\n")
43+
f.write(cleaned_content)
44+
f.write("\n}\n")
45+
46+
47+
if __name__ == "__main__":
48+
main()

core/clingutils/CMakeLists.txt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,18 @@ if (runtime_cxxmodules)
132132
elseif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 17.0.0.17000013)
133133
set(custom_modulemaps ${custom_modulemaps} std_darwin.MacOSX15.2.sdk.modulemap)
134134
else()
135-
set(custom_modulemaps ${custom_modulemaps} std_darwin.modulemap)
135+
set(GENERATED_MODULEMAP ${CMAKE_BINARY_DIR}/std_darwin.modulemap)
136+
137+
add_custom_command(
138+
OUTPUT ${GENERATED_MODULEMAP}
139+
COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/cmake/scripts/std_modulemap_darwin_fix.py ${GENERATED_MODULEMAP}
140+
DEPENDS ${CMAKE_SOURCE_DIR}/cmake/scripts/std_modulemap_darwin_fix.py
141+
COMMENT "Generating wrapped std modulemap for macOS SDK"
142+
)
143+
add_custom_target(generate_std_modulemap DEPENDS ${GENERATED_MODULEMAP})
144+
list(APPEND copy_commands COMMAND ${CMAKE_COMMAND} -E copy ${GENERATED_MODULEMAP} ${CMAKE_BINARY_DIR}/etc/cling/std_darwin.modulemap)
145+
list(APPEND files_to_copy ${GENERATED_MODULEMAP})
146+
install(FILES ${CMAKE_BINARY_DIR}/etc/cling/std_darwin.modulemap DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/cling)
136147
endif()
137148
endif()
138149

@@ -206,6 +217,9 @@ else()
206217
COMMENT "Copying LLVM resource and header files")
207218
endif()
208219
add_custom_target(LLVMRES DEPENDS ${stamp_file} CLING)
220+
if(GENERATED_MODULEMAP)
221+
add_dependencies(LLVMRES generate_std_modulemap)
222+
endif()
209223
# CLING is a shorthand for CLING_LIBRARIES and some other clang-specific
210224
# dependencies which ensure the correct order of building. Then the cling header
211225
# files (such as RuntimeUniverse.h) are moved to a semi-private place in ROOT

0 commit comments

Comments
 (0)