File set "xyz" is listed in interface file sets of W but has not been exported

I am getting the error in the title in the following script, but I could not resolve it any way I tried.

set(LIB_NAME Useful)

if(USEFUL_BUILD_SHARED_LIBS)
	add_library(${LIB_NAME} SHARED)
else()
	add_library(${LIB_NAME} STATIC)
endif()

string(TOUPPER ${LIB_NAME} UPPER_LIB_NAME)
generate_export_header(${LIB_NAME}
	EXPORT_MACRO_NAME ${UPPER_LIB_NAME}_EXPORT
	EXPORT_FILE_NAME ${LIB_NAME}_Export.hpp
)
target_sources(${LIB_NAME}
	PRIVATE Useful.cpp
)
target_sources(${LIB_NAME}
	PUBLIC
		FILE_SET public_header_files
			TYPE HEADERS
			BASE_DIRS
				"${PROJECT_SOURCE_DIR}/include"
				"${CMAKE_CURRENT_BINARY_DIR}"
			FILES
				"${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME}_Export.hpp"
				"${PROJECT_SOURCE_DIR}/include/Useful.hpp"
	PRIVATE
		FILE_SET private_header_files
			TYPE HEADERS
			BASE_DIRS "${PROJECT_SOURCE_DIR}/src"
			FILES DefaultLocale.hpp
)
target_include_directories(${LIB_NAME}
	PUBLIC
		$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
		$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
		$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
)
install(
	TARGETS ${LIB_NAME}
	RUNTIME
		DESTINATION ${CMAKE_INSTALL_BINDIR}
		COMPONENT Runtime
	LIBRARY
		DESTINATION ${CMAKE_INSTALL_LIBDIR}
		NAMELINK_SKIP
		COMPONENT Runtime
	ARCHIVE
		DESTINATION ${CMAKE_INSTALL_LIBDIR}
		COMPONENT Runtime
)
install(
	TARGETS ${LIB_NAME}
	EXPORT ${LIB_NAME}Exports
	LIBRARY
		DESTINATION ${CMAKE_INSTALL_LIBDIR}
		NAMELINK_ONLY
		COMPONENT Development
	ARCHIVE
		DESTINATION ${CMAKE_INSTALL_LIBDIR}
		COMPONENT Development
	PUBLIC_HEADER
		DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
		COMPONENT Development
	FILE_SET public_header_files
		DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
		COMPONENT Development
)
install(
# FILES $<TARGET_PDB_FILE:${LIB_NAME}> is cleanest, but is MSVC link.exe specific. LLVM's lld.exe and lld-link.exe don't support it (configure-time error)
# FILES $<TARGET_PROPERTY:${LIB_NAME},COMPILE_PDB_OUTPUT_DIRECTORY>/${LIB_NAME}.pdb looks OK, but even though there's a PDB, this prop is empty on non-MSVC toolchains
  FILES $<TARGET_FILE_DIR:${LIB_NAME}>/${LIB_NAME}.pdb # is the most implicit (expect PDB be next to the library), yet the only one that universally works
  DESTINATION ${CMAKE_INSTALL_BINDIR}
  OPTIONAL
)
set(config_package_location ${CMAKE_INSTALL_DATADIR}/cmake/${LIB_NAME})
export(
	TARGETS ${LIB_NAME}
	NAMESPACE Proj::
	FILE ${LIB_NAME}Config.cmake
)
install(
	EXPORT ${LIB_NAME}Exports
	FILE ${LIB_NAME}Config.cmake
	NAMESPACE Proj::
	DESTINATION ${config_package_location}
	COMPONENT Development
)
write_basic_package_version_file(
  "${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME}ConfigVersion.cmake"
  VERSION ${PROJECT_VERSION}
  COMPATIBILITY AnyNewerVersion
)
install(
  FILES "${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME}ConfigVersion.cmake"
  DESTINATION ${config_package_location}
  COMPONENT Development
)

The project configures, builds, installs, packages fine when the libUseful is a STATIC library (in this case the Runtime DEB package is empty), but it fails to even configure when it’s a SHARED library. I want the public headers to be installed only in the Development package and the Runtime package to have only the .so file (without the namelink, which is in the Development package)

How can I resolve the error? What am I missing?

Which cmake version are you using ?

I get this error with cmake v3.27.6:

bash-5.2$ cmake -B build -S . -G Ninja
-- Configuring done (0.1s)
CMake Error at Usefull.cmake:30 (target_sources):
  File:

    /Users/clausklein/Workspace/cmake/example/DefaultLocale.hpp

  must be in one of the file set's base directories:

    /Users/clausklein/Workspace/cmake/example/source

include(GNUInstallDirs)
include(GenerateExportHeader)
include(CMakePackageConfigHelpers)

OK, as simple as possible, that works:

cmake_minimum_required(VERSION 3.21...3.27)

# Note: update this to your new project's name and version
project(
  Useful
  VERSION 1.0
  LANGUAGES CXX
)

set(LIB_NAME Useful)
set(USEFUL_BUILD_SHARED_LIBS YES)

if(USEFUL_BUILD_SHARED_LIBS)
  add_library(${LIB_NAME} SHARED)
else()
  add_library(${LIB_NAME} STATIC)
endif()

include(GNUInstallDirs)
include(GenerateExportHeader)
include(CMakePackageConfigHelpers)

string(TOUPPER ${LIB_NAME} UPPER_LIB_NAME)
generate_export_header(${LIB_NAME}
  EXPORT_MACRO_NAME ${UPPER_LIB_NAME}_EXPORT
  EXPORT_FILE_NAME ${LIB_NAME}_Export.hpp
)
target_sources(${LIB_NAME}
  PRIVATE Useful.cpp
)
target_sources(${LIB_NAME}
  PUBLIC
    FILE_SET public_header_files
      TYPE HEADERS
      BASE_DIRS
        "${PROJECT_SOURCE_DIR}/include"
        "${CMAKE_CURRENT_BINARY_DIR}"
      FILES
        "${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME}_Export.hpp"
        "${PROJECT_SOURCE_DIR}/include/Useful.hpp"
  PRIVATE
    FILE_SET private_header_files
      TYPE HEADERS
      BASE_DIRS "${PROJECT_SOURCE_DIR}/source"
      FILES source/DefaultLocale.hpp
)
target_include_directories(${LIB_NAME}
 PUBLIC
   $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
   $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
   $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

install(
  TARGETS ${LIB_NAME}
  EXPORT ${LIB_NAME}Exports
  FILE_SET public_header_files
  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
  COMPONENT Development
)

# install(
#   FILES $<TARGET_FILE_DIR:${LIB_NAME}>/${LIB_NAME}.pdb
#   # is the most implicit (expect PDB be next to the library), yet the only one that universally works
#   DESTINATION ${CMAKE_INSTALL_BINDIR}
#   OPTIONAL
# )

set(config_package_location ${CMAKE_INSTALL_DATADIR}/cmake/${LIB_NAME})
install(
  EXPORT ${LIB_NAME}Exports
  FILE ${LIB_NAME}Config.cmake
  NAMESPACE Proj::
  DESTINATION ${config_package_location}
  COMPONENT Development
)

write_basic_package_version_file(
  "${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME}ConfigVersion.cmake"
  VERSION ${PROJECT_VERSION}
  COMPATIBILITY AnyNewerVersion
)
install(
  FILES "${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME}ConfigVersion.cmake"
  DESTINATION ${config_package_location}
  COMPONENT Development
)

include(cpack)

But still, your exported config set seems wrong to me:

Useful-1.0-Darwin/share/cmake/Useful/UsefulConfig-noconfig.cmake
Useful-1.0-Darwin/share/cmake/Useful/UsefulConfig.cmake
Useful-1.0-Darwin/share/cmake/Useful/UsefulConfigVersion.cmake

example with targets*.cmake:

Greeter-1.0-Darwin/lib/cmake/fmt/fmt-config.cmake
Greeter-1.0-Darwin/lib/cmake/fmt/fmt-config-version.cmake
Greeter-1.0-Darwin/lib/cmake/fmt/fmt-targets-noconfig.cmake
Greeter-1.0-Darwin/lib/cmake/fmt/fmt-targets.cmake

If you mean the -noconfig bit, then this is likely because no configuration (Debug or Release) was specified. So for instance with Ninja you’d need to provide -DCMAKE_BUILD_TYPE=Release on configuration and with VS/Xcode you’d need to provide --config Release on build.

NO, I am woundering about missing targets variants.

Ah, for that the installation statements should look like this.