77include (HPX_AddCompileFlag)
88include (HPX_Message)
99
10+ if (NOT HPX_WITH_CXX_MODULES)
11+ return ()
12+ endif ()
13+
14+ # Unfortunately, different compilers expect different file extensions for the
15+ # C++ module definition files.
16+ if (MSVC )
17+ set (HPX_MODULE_INTERFACE_EXTENSION ".ixx" )
18+ elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES
19+ "AppleClang"
20+ )
21+ set (HPX_MODULE_INTERFACE_EXTENSION ".cppm" )
22+ elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" )
23+ set (HPX_MODULE_INTERFACE_EXTENSION ".cxx" )
24+ else ()
25+ hpx_error(
26+ "C++ modules are not supported for the used compiler ('${CMAKE_CXX_COMPILER_ID} ')"
27+ )
28+ endif ()
29+
1030# hpx_configure_module_producer(<producer> [MODULE_OUT_DIR <dir>])
1131#
1232# * Ensures a stable module output dir for producer target
1333# * Adds compiler flags to write module cache there (Clang/GCC)
14- # * Creates a target '<producer>_module ' for consumers to link to
34+ # * Creates an interface target '<producer>_if ' for consumers to link to
1535function (hpx_configure_module_producer producer)
1636 if (NOT TARGET ${producer} )
17- hpx_error("configure_module_producer : target '${producer} ' not found" )
37+ hpx_error("hpx_configure_module_producer : target '${producer} ' not found" )
1838 endif ()
1939
2040 # parse optional args
@@ -35,13 +55,16 @@ function(hpx_configure_module_producer producer)
3555 if (NOT TARGET ${_iface} )
3656 add_library (${_iface} INTERFACE )
3757 target_link_libraries (${_iface} INTERFACE ${producer} )
38- # target_include_directories(${_iface} INTERFACE "${_moddir}")
3958 endif ()
4059
4160 # Set a property so consumers can query the BMI directory via
4261 # get_target_property.
43- set_target_properties (${producer} PROPERTIES EXPORT_MODULE_DIR "${_moddir} " )
44- set_target_properties (${producer} PROPERTIES CXX_SCAN_FOR_MODULES On )
62+ set_target_properties (
63+ ${_iface} PROPERTIES INTERFACE_EXPORT_MODULE_DIR "${_moddir} "
64+ )
65+
66+ # Make sure consumers scan for the BMI
67+ set_target_properties (${_iface} PROPERTIES INTERFACE_CXX_SCAN_FOR_MODULES On )
4568
4669 if (MSVC )
4770 # MSVC: CMake/MSVC handle IFCs automatically; create a target for
@@ -55,32 +78,71 @@ function(hpx_configure_module_producer producer)
5578 )
5679 # Clang common flags
5780 target_compile_options (${producer} PRIVATE "-fmodule-output=${_moddir} " )
58- target_compile_options (
59- ${_iface} INTERFACE "-fprebuilt-module-path=${_moddir} "
60- )
6181 elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" )
62- # GCC: try a few likely flags depending on version Prefer flags used in GCC
63- # 11+: -fmodules-ts, -fmodules-cache-path (or -fmodule-cache-path)
82+ # GCC: modern flags
6483 hpx_add_target_compile_option_if_available(
6584 ${producer} PRIVATE "-fmodule-output=${_moddir} " RESULT ok
6685 )
6786 if (NOT ok)
6887 hpx_error(
69- "configure_module_producer: the used version of gcc does not support '-fmodule-output'"
70- )
71- endif ()
72- hpx_add_target_compile_option_if_available(
73- ${_iface} INTERFACE "-fprebuilt-module-path=${_moddir} " RESULT ok
74- )
75- if (NOT ok)
76- hpx_error(
77- "configure_module_producer: the used version of gcc does not support '-fprebuilt-module-path='"
88+ "hpx_configure_module_producer: the used version of gcc does not support '-fmodule-output'"
7889 )
7990 endif ()
8091 else ()
8192 hpx_warn(
82- "configure_module_producer : unknown compiler '${CMAKE_CXX_COMPILER_ID} '; "
83- "exposing CXX_MODULE_OUTPUT_DIRECTORY ='${_moddir} ' for manual handling"
93+ "hpx_configure_module_producer : unknown compiler '${CMAKE_CXX_COMPILER_ID} '; "
94+ "exposing EXPORT_MODULE_DIR ='${_moddir} ' for manual handling"
8495 )
8596 endif ()
8697endfunction ()
98+
99+ # hpx_configure_module_consumer(<consumer> <producer>])
100+ #
101+ # * propagates module-related properties from producer interface target
102+ # * sets necessary consumer compiler flags for clang and gcc
103+ function (hpx_configure_module_consumer consumer producer)
104+ if (NOT TARGET ${consumer} )
105+ hpx_error("hpx_configure_module_consumer: target '${consumer} ' not found" )
106+ endif ()
107+ if (NOT TARGET ${producer} )
108+ hpx_error("hpx_configure_module_consumer: target '${producer} ' not found" )
109+ endif ()
110+
111+ target_link_libraries (${consumer} PUBLIC ${producer} )
112+ get_target_property (_scan ${producer} INTERFACE_CXX_SCAN_FOR_MODULES)
113+ if (_scan)
114+ set_target_properties (${consumer} PROPERTIES CXX_SCAN_FOR_MODULES ${_scan} )
115+ endif ()
116+
117+ get_target_property (_module_dir ${producer} INTERFACE_EXPORT_MODULE_DIR)
118+ if (_module_dir)
119+ if (MSVC )
120+ return ()
121+ elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID
122+ MATCHES "AppleClang"
123+ )
124+ target_compile_options (
125+ ${consumer} PRIVATE "-fprebuilt-module-path=${_module_dir} "
126+ )
127+ get_target_property (_type ${consumer} TYPE )
128+ if ((_type STREQUAL "SHARED_LIBRARY" ) OR (_type STREQUAL "EXECUTABLE" ))
129+ target_link_options (${consumer} PRIVATE "-fuse-ld=lld" )
130+ target_link_options (${consumer} PRIVATE "-Wl,--error-limit=0" )
131+ endif ()
132+ elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" )
133+ hpx_add_target_compile_option_if_available(
134+ ${consumer} PRIVATE "-fprebuilt-module-path=${_module_dir} " RESULT ok
135+ )
136+ if (NOT ok)
137+ hpx_error(
138+ "hpx_configure_module_consumer: the used version of clang does not "
139+ "support '-fprebuilt-module-path='"
140+ )
141+ endif ()
142+ else ()
143+ hpx_warn(
144+ "hpx_configure_module_consumer: unknown compiler '${CMAKE_CXX_COMPILER_ID} '"
145+ )
146+ endif ()
147+ endif ()
148+ endfunction ()
0 commit comments