44# Distributed under the Boost Software License, Version 1.0. (See accompanying
55# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
66
7+ include (HPX_AddCompileFlag )
78include (HPX_Message )
89
910macro (hpx_check_cxx_modules_support )
@@ -64,39 +65,79 @@ if(NOT HPX_WITH_CXX_MODULES)
6465 return ()
6566endif ()
6667
67- # hpx_configure_module_producer(<producer>)
68+ # hpx_configure_module_producer(<producer> [MODULE_OUT_DIR <dir>] )
6869#
69- # * Creates an interface target '<producer>_if' for consumers to link to.
70- # * Sets INTERFACE_CXX_SCAN_FOR_MODULES ON so that CMake's native module
71- # dependency tracking propagates to all consumers.
72- #
73- # CMake 3.29+ with FILE_SET CXX_MODULES handles BMI generation and
74- # -fmodule-output/-fprebuilt-module-path flags automatically. No manual compiler
75- # flags are needed here.
70+ # * Ensures a stable module output dir for producer target
71+ # * Adds compiler flags to write module cache there (Clang/GCC)
72+ # * Creates an interface target '<producer>_if' for consumers to link to
7673function (hpx_configure_module_producer producer )
7774 if (NOT TARGET ${producer} )
7875 hpx_error ("hpx_configure_module_producer: target '${producer} ' not found" )
7976 endif ()
8077
78+ # parse optional args
79+ set (options)
80+ set (one_value_args MODULE_OUT_DIR)
81+ set (multi_value_args)
82+ cmake_parse_arguments (
83+ _args "${options} " "${one_value_args} " "${multi_value_args} " ${ARGN}
84+ )
85+
86+ if (_args_MODULE_OUT_DIR)
87+ set (_moddir "${_args_MODULE_OUT_DIR} " )
88+ else ()
89+ set (_moddir "$<TARGET_FILE_DIR :${producer} >" )
90+ endif ()
91+
8192 set (_iface "${producer} _if" )
8293 if (NOT TARGET ${_iface} )
8394 add_library (${_iface} INTERFACE )
8495 target_link_libraries (${_iface} INTERFACE ${producer} )
8596 endif ()
8697
87- # Propagate scanning requirement to consumers via the interface target. CMake
88- # uses this to enable its native module dependency scanning for any target
89- # that links to this interface.
90- set_target_properties (${_iface} PROPERTIES INTERFACE_CXX_SCAN_FOR_MODULES ON )
98+ # Set a property so consumers can query the BMI directory via
99+ # get_target_property.
100+ set_target_properties (
101+ ${_iface} PROPERTIES INTERFACE_EXPORT_MODULE_DIR "${_moddir} "
102+ )
103+
104+ # Make sure consumers scan for the BMI
105+ set_target_properties (${_iface} PROPERTIES INTERFACE_CXX_SCAN_FOR_MODULES On )
106+
107+ if (MSVC )
108+ # MSVC: CMake/MSVC handle IFCs automatically; create a target for
109+ # convenience, consumers can link to this to get ordering and include info
110+ return ()
111+ endif ()
112+
113+ # Compiler-specific flags to instruct where to write module cache
114+ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES
115+ "AppleClang"
116+ )
117+ # Clang common flags
118+ target_compile_options (${producer} PRIVATE "-fmodule-output=${_moddir} " )
119+ elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" )
120+ # GCC: modern flags
121+ hpx_add_target_compile_option_if_available (
122+ ${producer} PRIVATE "-fmodule-output=${_moddir} " RESULT ok
123+ )
124+ if (NOT ok)
125+ hpx_error (
126+ "hpx_configure_module_producer: the used version of gcc does not support '-fmodule-output'"
127+ )
128+ endif ()
129+ else ()
130+ hpx_warn (
131+ "hpx_configure_module_producer: unknown compiler '${CMAKE_CXX_COMPILER_ID} '; "
132+ "exposing EXPORT_MODULE_DIR='${_moddir} ' for manual handling"
133+ )
134+ endif ()
91135endfunction ()
92136
93- # hpx_configure_module_consumer(<consumer> <producer>)
94- #
95- # * Links the consumer to the producer interface target.
96- # * Enables CMake's native module scanning on the consumer.
137+ # hpx_configure_module_consumer(<consumer> <producer>])
97138#
98- # CMake 3.29+ automatically resolves the BMI location from the FILE_SET
99- # CXX_MODULES declared on the producer. No -fprebuilt-module-path needed.
139+ # * propagates module-related properties from producer interface target
140+ # * sets necessary consumer compiler flags for clang and gcc
100141function (hpx_configure_module_consumer consumer producer )
101142 if (NOT TARGET ${consumer} )
102143 hpx_error ("hpx_configure_module_consumer: target '${consumer} ' not found" )
@@ -106,20 +147,40 @@ function(hpx_configure_module_consumer consumer producer)
106147 endif ()
107148
108149 target_link_libraries (${consumer} PRIVATE ${producer} )
109-
110150 get_target_property (_scan ${producer} INTERFACE_CXX_SCAN_FOR_MODULES )
111151 if (_scan)
112152 set_target_properties (${consumer} PROPERTIES CXX_SCAN_FOR_MODULES ${_scan} )
113153 endif ()
114154
115- # Clang emits DWARF-5 when compiling with C++20 modules, which requires lld.
116- if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES
117- "AppleClang"
118- )
119- get_target_property (_type ${consumer} TYPE )
120- if ((_type STREQUAL "SHARED_LIBRARY" ) OR (_type STREQUAL "EXECUTABLE" ))
121- target_link_options (${consumer} PRIVATE "-fuse-ld=lld" )
122- target_link_options (${consumer} PRIVATE "-Wl,--error-limit=0" )
155+ get_target_property (_module_dir ${producer} INTERFACE_EXPORT_MODULE_DIR )
156+ if (_module_dir)
157+ if (MSVC )
158+ return ()
159+ elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID
160+ MATCHES "AppleClang"
161+ )
162+ target_compile_options (
163+ ${consumer} PRIVATE "-fprebuilt-module-path=${_module_dir} "
164+ )
165+ get_target_property (_type ${consumer} TYPE )
166+ if ((_type STREQUAL "SHARED_LIBRARY" ) OR (_type STREQUAL "EXECUTABLE" ))
167+ target_link_options (${consumer} PRIVATE "-fuse-ld=lld" )
168+ target_link_options (${consumer} PRIVATE "-Wl,--error-limit=0" )
169+ endif ()
170+ elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" )
171+ hpx_add_target_compile_option_if_available (
172+ ${consumer} PRIVATE "-fprebuilt-module-path=${_module_dir} " RESULT ok
173+ )
174+ if (NOT ok)
175+ hpx_error (
176+ "hpx_configure_module_consumer: the used version of gcc does not "
177+ "support '-fprebuilt-module-path='"
178+ )
179+ endif ()
180+ else ()
181+ hpx_warn (
182+ "hpx_configure_module_consumer: unknown compiler '${CMAKE_CXX_COMPILER_ID} '"
183+ )
123184 endif ()
124185 endif ()
125186endfunction ()
0 commit comments