Skip to content

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

@MeanSquaredError

Description

@MeanSquaredError

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions