xmake icon indicating copy to clipboard operation
xmake copied to clipboard

cmake_importfiles: Adding module interface files to the target interface sources of the imported targets

Open MeanSquaredError opened this issue 1 month ago • 2 comments

Is your feature request related to a problem? Please describe.

When installing a project locally it is possible to use utils.install.cmake_importfiles in order to create the various CMake import files (version, config and target files). However it is not possible (or at least I don't see a way) to tell Xmake that certain files that are installed locally via add_installfiles() are C++20 module interface files, that should be added to the list of target interface files of the corresponding target.

In contrast in CMake if you have the following code:

...
set (LIB_NAME "mylib")
set (NS_NAME "mylib")
...
# Module interface files
file (GLOB_RECURSE GLOBBED_SOURCES LIST_DIRECTORIES false CONFIGURE_DEPENDS source/*.cppm)
target_sources (
	"${LIB_NAME}"
	PUBLIC
	FILE_SET modules_iface BASE_DIRS source TYPE CXX_MODULES FILES ${GLOBBED_SOURCES}
)

include (GNUInstallDirs)
# Install the static libraries and module interface files and define the config targets
install (
	TARGETS "${LIB_NAME}"
	EXPORT "${LIB_NAME}-targets"
	ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
	FILE_SET modules_iface DESTINATION  "${CMAKE_INSTALL_PREFIX}/modules/${LIB_NAME}"
)
# Install the files with the defined config targets
install (
	EXPORT "${LIB_NAME}-targets"
	DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${LIB_NAME}"
	NAMESPACE "${NS_NAME}::"
...

Then CMake will create a target file mylib-targets.cmake that will have the following content:

...
if(NOT CMAKE_VERSION VERSION_LESS "3.23.0")
  target_sources(mylib::mylib
    INTERFACE
      FILE_SET "modules_iface"
      TYPE "CXX_MODULES"
      BASE_DIRS "/usr/local/modules/mylib"
      FILES "/usr/local/modules/mylib/mylib.cppm"
  )
else()
  set_property(TARGET mylib::mylib
    APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES
  )
endif()
...

That is it adds the installed interface files (*.cppm) as external sources of the imported target mylib::mylib. Then you could just add the imported target mylib::mylib as a dependency of your project via target_link_libraries() and the imported interface files will be added automatically to your project.

Currently Xmake's utils.install.cmake_importfiles and find_package don't allow one to export/import the module interface files as sources of an imported target.

Describe the solution you'd like

I think that such functionality can be easily added to utils.install.cmake_importfiles and find_package if there is a way to tell Xmake that a certain set of files added via add_installfiles are module interface files, e.g. by using a special boolean option:

add_installfiles ("source/(**.cppm)", {prefixdir="modules/mylib", cxx_module_interface=true})

Then utils.install.cmake_importfiles can use that boolean flag and add these interface files to the imported target sources. After that it would be possible to automatically add the imported target sources through a simple call to

add_requires ("cmake::mylib", {system = true, configs = {link_libraries = {"mylib::mylib"}}})

Describe alternatives you've considered

There are no really good alternatives to exporting/importing the interface files to/from the target sources. It is possible to not export the interface files and then add them manually to the source files of the importing project via add_files("/usr/local/modules/mylib/**.cppm"), but that's not a good solution.

Additional context

I think I can add this functionality to add_installfiles() and utils.install.cmake_importfiles if the Xmake developers agree with the proposed solution.

MeanSquaredError avatar Nov 27 '25 11:11 MeanSquaredError

you can try.

waruqi avatar Nov 28 '25 16:11 waruqi

OK, thanks for approving the idea. I will try to implement that functionality in about a week or so.

MeanSquaredError avatar Nov 29 '25 21:11 MeanSquaredError