Escape hell, and how to escape it

I’m trying to make the following code work:

    foreach(module ${CXXMODULES})
        set(MODULE_MAP_FLAGS "")
        string(APPEND MODULE_MAP_FLAGS ";-Xcc;-fmodule-map-file=${MODULE_SOURCE_DIR}/module.modulemap")
      endif()
    endforeach()

    message(STATUS "MODULE_MAP_FLAGS: ${_NAME} ${MODULE_MAP_FLAGS}")
    target_compile_options(${_NAME} PRIVATE
      $<$<COMPILE_LANGUAGE:Swift>:-cxx-interoperability-mode=default>
      $<$<COMPILE_LANGUAGE:Swift>:-Xcc;-std=c++${CXX_STANDARD};${MODULE_MAP_FLAGS}>
      $<$<COMPILE_LANGUAGE:Swift>:-I${INTERFACE_INCLUDE_DIRS}>
    )

However, as presented above, while the output of message looks valid:

-- MODULE_MAP_FLAGS: Session ;-Xcc;-fmodule-map-file=dir1/module.modulemap;-Xcc;-fmodule-map-file=dir2/module.modulemap

The actual command during build looks like

-Xcc -std\=c++20 -fmodule-map-file\=dir1/module.modulemap -fmodule-map-file\=dir2/module.modulemap

In other words, all the repeat occurrences of -Xcc are being eliminated. Most of the alternatives tried result in spaces being escaped with backslash, which is a different problem.

Any advice on how to make this work and keep all of my -Xcc’s intact?

Using

        target_compile_options(${_NAME} PRIVATE
          $<$<COMPILE_LANGUAGE:Swift>:-Xcc;-fmodule-map-file=${MODULE_SOURCE_DIR}/module.modulemap>
        )

multiple times in the loop results in the same behavior (only the first -Xcc makes it through)

Found this in the docs for target_compile_options: https://cmake.org/cmake/help/latest/command/target_compile_options.html#option-de-duplication

Building a list of options with it, like so, works:

      if(EXISTS "${MODULE_SOURCE_DIR}/module.modulemap")
        list(APPEND LOCAL_CXX_FLAGS "SHELL:-Xcc -fmodule-map-file=${MODULE_SOURCE_DIR}/module.modulemap")
      endif()