mirror of
https://github.com/Kitware/CMake.git
synced 2026-06-30 19:57:41 +00:00
FILE_SET: install and export SOURCES file set type
This commit is contained in:
@@ -245,7 +245,10 @@ Signatures
|
||||
|
||||
File sets are defined by the :command:`target_sources(FILE_SET)` command.
|
||||
If the file set ``<set-name>`` exists and is ``PUBLIC`` or ``INTERFACE``,
|
||||
any files in the set are installed under the destination (see below).
|
||||
any files in the set of type ``HEADERS`` are installed under
|
||||
the destination (see below). Other types do not have any default
|
||||
destination, so ``DESTINATION`` option must be specified for each
|
||||
``FILE_SET``.
|
||||
The directory structure relative to the file set's base directories is
|
||||
preserved. For example, a file added to the file set as
|
||||
``/blah/include/myproj/here.h`` with a base directory ``/blah/include``
|
||||
@@ -265,12 +268,13 @@ Signatures
|
||||
``DESTINATION`` is omitted, a default destination will be taken from the
|
||||
appropriate variable from :module:`GNUInstallDirs`, or set to a built-in
|
||||
default value if that variable is not defined. The same is true for file
|
||||
sets, and the public and private headers associated with the installed
|
||||
targets through the :prop_tgt:`PUBLIC_HEADER` and :prop_tgt:`PRIVATE_HEADER`
|
||||
target properties. A destination must always be provided for module libraries,
|
||||
Apple bundles and frameworks. A destination can be omitted for interface and
|
||||
object libraries, but they are handled differently (see the discussion of this
|
||||
topic toward the end of this section).
|
||||
sets of type ``HEADERS``, and the public and private headers associated with
|
||||
the installed targets through the :prop_tgt:`PUBLIC_HEADER` and
|
||||
:prop_tgt:`PRIVATE_HEADER` target properties. A destination must always be
|
||||
provided for module libraries, Apple bundles and frameworks. A destination
|
||||
can be omitted for interface and object libraries, but they are handled
|
||||
differently (see the discussion of this topic toward the end of this
|
||||
section).
|
||||
|
||||
For shared libraries on DLL platforms, if neither ``RUNTIME`` nor ``ARCHIVE``
|
||||
destinations are specified, both the ``RUNTIME`` and ``ARCHIVE`` components are
|
||||
|
||||
@@ -71,12 +71,17 @@ bool cmExportBuildCMakeConfigGenerator::GenerateMainFile(std::ostream& os)
|
||||
return false;
|
||||
}
|
||||
|
||||
ImportFileSetPropertyMap fsProperties;
|
||||
if (!this->PopulateFileSetInterfaceProperties(gte, fsProperties)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->PopulateInterfaceLinkLibrariesProperty(
|
||||
gte, cmGeneratorExpression::BuildInterface, properties);
|
||||
|
||||
this->GenerateInterfaceProperties(gte, os, properties);
|
||||
|
||||
this->GenerateTargetFileSets(gte, os);
|
||||
this->GenerateTargetFileSets(gte, os, fsProperties);
|
||||
}
|
||||
|
||||
std::string cxx_modules_name;
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
#include "cmExportSet.h"
|
||||
#include "cmGeneratorExpression.h"
|
||||
#include "cmGeneratorFileSet.h"
|
||||
#include "cmGeneratorFileSets.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include "cmList.h"
|
||||
@@ -284,3 +286,24 @@ bool cmExportBuildFileGenerator::PopulateInterfaceProperties(
|
||||
return this->PopulateInterfaceProperties(
|
||||
target, {}, cmGeneratorExpression::BuildInterface, properties);
|
||||
}
|
||||
|
||||
bool cmExportBuildFileGenerator::PopulateFileSetInterfaceProperties(
|
||||
cmGeneratorTarget const* target, ImportFileSetPropertyMap& properties)
|
||||
{
|
||||
cmGeneratorFileSets const* const gfs = target->GetGeneratorFileSets();
|
||||
bool result = true;
|
||||
|
||||
for (auto const& type : gfs->GetInterfaceFileSetTypes()) {
|
||||
for (auto const* fileSet : gfs->GetInterfaceFileSets(type)) {
|
||||
ImportPropertyMap& fsProperties = properties[fileSet->GetName()];
|
||||
this->PopulateFileSetInterfaceProperty(
|
||||
"INTERFACE_INCLUDE_DIRECTORIES", target, fileSet,
|
||||
cmGeneratorExpression::BuildInterface, fsProperties);
|
||||
result = result &&
|
||||
this->PopulateFileSetInterfaceProperties(
|
||||
target, fileSet, cmGeneratorExpression::InstallInterface,
|
||||
fsProperties);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -114,6 +114,10 @@ protected:
|
||||
bool PopulateInterfaceProperties(cmGeneratorTarget const* target,
|
||||
ImportPropertyMap& properties);
|
||||
|
||||
using cmExportFileGenerator::PopulateFileSetInterfaceProperties;
|
||||
bool PopulateFileSetInterfaceProperties(
|
||||
cmGeneratorTarget const* target, ImportFileSetPropertyMap& properties);
|
||||
|
||||
struct TargetExportPrivate
|
||||
{
|
||||
TargetExportPrivate(cmGeneratorTarget* target,
|
||||
|
||||
@@ -612,6 +612,8 @@ cm::optional<FileSetInformation> GetFileSetInformation(cm::string_view type)
|
||||
fileSetsInformation{
|
||||
{ cm::FileSetMetadata::HEADERS,
|
||||
{ cm::FileSetMetadata::HEADERS, "3.23.0"_s } },
|
||||
{ cm::FileSetMetadata::SOURCES,
|
||||
{ cm::FileSetMetadata::SOURCES, "4.4.0"_s } },
|
||||
{ cm::FileSetMetadata::CXX_MODULES,
|
||||
{ cm::FileSetMetadata::CXX_MODULES, "3.28.0"_s } },
|
||||
};
|
||||
@@ -625,7 +627,8 @@ cm::optional<FileSetInformation> GetFileSetInformation(cm::string_view type)
|
||||
}
|
||||
|
||||
void cmExportCMakeConfigGenerator::GenerateTargetFileSets(
|
||||
cmGeneratorTarget* gte, std::ostream& os, cmTargetExport const* te)
|
||||
cmGeneratorTarget* gte, std::ostream& os,
|
||||
ImportFileSetPropertyMap const& properties, cmTargetExport const* te)
|
||||
{
|
||||
cmGeneratorFileSets const* gfs = gte->GetGeneratorFileSets();
|
||||
auto const& types = gfs->GetInterfaceFileSetTypes();
|
||||
@@ -648,9 +651,20 @@ void cmExportCMakeConfigGenerator::GenerateTargetFileSets(
|
||||
<< this->GetFileSetDirectories(gte, fileSet, te) << "\n FILES "
|
||||
<< this->GetFileSetFiles(gte, fileSet, te) << '\n';
|
||||
}
|
||||
os << " )\n";
|
||||
for (auto const* fileSet : gfs->GetInterfaceFileSets(type)) {
|
||||
auto fsProperties = properties.find(fileSet->GetName());
|
||||
if (fsProperties != properties.end()) {
|
||||
for (auto const& property : fsProperties->second) {
|
||||
os << "\n set_property(FILE_SET "
|
||||
<< cmScriptGenerator::Quote(fileSet->GetName()) << " TARGET "
|
||||
<< targetName << "\n PROPERTY " << property.first << ' '
|
||||
<< cmExportFileGeneratorEscape(property.second) << "\n )";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fsInfo) {
|
||||
os << " )";
|
||||
if (type == cm::FileSetMetadata::HEADERS) {
|
||||
os << "\nelse()\n set_property(TARGET " << targetName
|
||||
<< "\n APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES";
|
||||
@@ -658,6 +672,10 @@ void cmExportCMakeConfigGenerator::GenerateTargetFileSets(
|
||||
os << "\n " << this->GetFileSetDirectories(gte, fileSet, te);
|
||||
}
|
||||
os << "\n )";
|
||||
} else if (type == cm::FileSetMetadata::SOURCES) {
|
||||
os << "\nelse()\n message(FATAL_ERROR \"The target '" << targetName
|
||||
<< "' cannot be imported because it relies on 'FILE_SET' of type "
|
||||
"'SOURCES' which is not supported by this CMake version.\")";
|
||||
} else if (type == cm::FileSetMetadata::CXX_MODULES) {
|
||||
os << "\nelse()\n message(AUTHOR_WARNING \"The target '"
|
||||
<< targetName
|
||||
|
||||
@@ -44,6 +44,7 @@ public:
|
||||
|
||||
protected:
|
||||
using ImportPropertyMap = std::map<std::string, std::string>;
|
||||
using ImportFileSetPropertyMap = std::map<std::string, ImportPropertyMap>;
|
||||
|
||||
// Methods to implement export file code generation.
|
||||
bool GenerateImportFile(std::ostream& os) override;
|
||||
@@ -84,6 +85,7 @@ protected:
|
||||
cmGeneratorTarget const* target, ImportPropertyMap& properties);
|
||||
|
||||
void GenerateTargetFileSets(cmGeneratorTarget* gte, std::ostream& os,
|
||||
ImportFileSetPropertyMap const& properties,
|
||||
cmTargetExport const* te = nullptr);
|
||||
|
||||
std::string GetCxxModuleFile(std::string const& name) const override;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "cmComputeLinkInformation.h"
|
||||
#include "cmFindPackageStack.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmGeneratorFileSet.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmLinkItem.h"
|
||||
#include "cmList.h"
|
||||
@@ -139,6 +140,20 @@ bool cmExportFileGenerator::PopulateInterfaceProperties(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmExportFileGenerator::PopulateFileSetInterfaceProperties(
|
||||
cmGeneratorTarget const* target, cmGeneratorFileSet const* fileSet,
|
||||
cmGeneratorExpression::PreprocessContext preprocessRule,
|
||||
ImportPropertyMap& properties)
|
||||
{
|
||||
this->PopulateFileSetInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS",
|
||||
target, fileSet, preprocessRule,
|
||||
properties);
|
||||
this->PopulateFileSetInterfaceProperty("INTERFACE_COMPILE_OPTIONS", target,
|
||||
fileSet, preprocessRule, properties);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void cmExportFileGenerator::PopulateInterfaceProperty(
|
||||
std::string const& propName, cmGeneratorTarget const* target,
|
||||
ImportPropertyMap& properties) const
|
||||
@@ -181,6 +196,29 @@ void cmExportFileGenerator::PopulateInterfaceProperty(
|
||||
properties);
|
||||
}
|
||||
|
||||
void cmExportFileGenerator::PopulateFileSetInterfaceProperty(
|
||||
std::string const& propName, cmGeneratorTarget const* target,
|
||||
cmGeneratorFileSet const* fileSet,
|
||||
cmGeneratorExpression::PreprocessContext preprocessRule,
|
||||
ImportPropertyMap& properties)
|
||||
{
|
||||
cmValue input = fileSet->GetProperty(propName);
|
||||
if (input) {
|
||||
if (input->empty()) {
|
||||
// Set to empty
|
||||
properties[propName].clear();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string prepro =
|
||||
cmGeneratorExpression::Preprocess(*input, preprocessRule);
|
||||
if (!prepro.empty()) {
|
||||
this->ResolveTargetsInGeneratorExpressions(prepro, target);
|
||||
properties[propName] = prepro;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool cmExportFileGenerator::PopulateInterfaceLinkLibrariesProperty(
|
||||
cmGeneratorTarget const* target,
|
||||
cmGeneratorExpression::PreprocessContext preprocessRule,
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
class cmExportSet;
|
||||
class cmGeneratorTarget;
|
||||
class cmGeneratorFileSet;
|
||||
class cmLocalGenerator;
|
||||
|
||||
/** \class cmExportFileGenerator
|
||||
@@ -48,6 +49,7 @@ public:
|
||||
|
||||
protected:
|
||||
using ImportPropertyMap = std::map<std::string, std::string>;
|
||||
using ImportFileSetPropertyMap = std::map<std::string, ImportPropertyMap>;
|
||||
|
||||
// Collect properties with detailed information about targets beyond
|
||||
// their location on disk.
|
||||
@@ -112,6 +114,10 @@ protected:
|
||||
cmGeneratorTarget const* target,
|
||||
cmGeneratorExpression::PreprocessContext,
|
||||
ImportPropertyMap& properties);
|
||||
void PopulateFileSetInterfaceProperty(
|
||||
std::string const& propName, cmGeneratorTarget const* target,
|
||||
cmGeneratorFileSet const* fileSet,
|
||||
cmGeneratorExpression::PreprocessContext, ImportPropertyMap& properties);
|
||||
bool PopulateInterfaceLinkLibrariesProperty(
|
||||
cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext,
|
||||
ImportPropertyMap& properties);
|
||||
@@ -122,6 +128,11 @@ protected:
|
||||
cmGeneratorExpression::PreprocessContext preprocessRule,
|
||||
ImportPropertyMap& properties);
|
||||
|
||||
bool PopulateFileSetInterfaceProperties(
|
||||
cmGeneratorTarget const* target, cmGeneratorFileSet const* fileSet,
|
||||
cmGeneratorExpression::PreprocessContext preprocessRule,
|
||||
ImportPropertyMap& properties);
|
||||
|
||||
virtual void IssueMessage(MessageType type,
|
||||
std::string const& message) const = 0;
|
||||
virtual void IssueDiagnostic(cmDiagnosticCategory category,
|
||||
|
||||
@@ -83,6 +83,11 @@ bool cmExportInstallCMakeConfigGenerator::GenerateMainFile(std::ostream& os)
|
||||
return false;
|
||||
}
|
||||
|
||||
ImportFileSetPropertyMap fsProperties;
|
||||
if (!this->PopulateFileSetInterfaceProperties(te, fsProperties)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this->PopulateInterfaceLinkLibrariesProperty(
|
||||
gt, cmGeneratorExpression::InstallInterface, properties) &&
|
||||
!this->ExportOld) {
|
||||
@@ -99,7 +104,7 @@ bool cmExportInstallCMakeConfigGenerator::GenerateMainFile(std::ostream& os)
|
||||
|
||||
this->GenerateInterfaceProperties(gt, os, properties);
|
||||
|
||||
this->GenerateTargetFileSets(gt, os, te);
|
||||
this->GenerateTargetFileSets(gt, os, fsProperties, te);
|
||||
}
|
||||
|
||||
this->LoadConfigFiles(os);
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
|
||||
#include "cmExportSet.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmGeneratorFileSet.h"
|
||||
#include "cmGeneratorFileSets.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include "cmInstallTargetGenerator.h"
|
||||
@@ -410,6 +412,27 @@ bool cmExportInstallFileGenerator::PopulateInterfaceProperties(
|
||||
properties);
|
||||
}
|
||||
|
||||
bool cmExportInstallFileGenerator::PopulateFileSetInterfaceProperties(
|
||||
cmTargetExport const* targetExport, ImportFileSetPropertyMap& properties)
|
||||
{
|
||||
cmGeneratorTarget const* const gt = targetExport->Target;
|
||||
cmGeneratorFileSets const* const gfs = gt->GetGeneratorFileSets();
|
||||
|
||||
bool result = true;
|
||||
|
||||
for (auto const& type : gfs->GetInterfaceFileSetTypes()) {
|
||||
for (auto const* fileSet : gfs->GetInterfaceFileSets(type)) {
|
||||
ImportPropertyMap& fsProperties = properties[fileSet->GetName()];
|
||||
this->PopulateFileSetIncludeDirectoriesInterface(
|
||||
gt, fileSet, cmGeneratorExpression::InstallInterface, fsProperties);
|
||||
result = result &&
|
||||
this->PopulateFileSetInterfaceProperties(
|
||||
gt, fileSet, cmGeneratorExpression::InstallInterface, fsProperties);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool isSubDirectory(std::string const& a, std::string const& b)
|
||||
{
|
||||
@@ -620,6 +643,37 @@ void cmExportInstallFileGenerator::PopulateIncludeDirectoriesInterface(
|
||||
}
|
||||
}
|
||||
|
||||
void cmExportInstallFileGenerator::PopulateFileSetIncludeDirectoriesInterface(
|
||||
cmGeneratorTarget const* target, cmGeneratorFileSet const* fileSet,
|
||||
cmGeneratorExpression::PreprocessContext preprocessRule,
|
||||
ImportPropertyMap& properties)
|
||||
{
|
||||
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
|
||||
|
||||
char const* const propName = "INTERFACE_INCLUDE_DIRECTORIES";
|
||||
cmValue includes = fileSet->GetProperty(propName);
|
||||
|
||||
if (!includes) {
|
||||
return;
|
||||
}
|
||||
if (includes && includes->empty()) {
|
||||
// Set to empty
|
||||
properties[propName].clear();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string prepro = cmGeneratorExpression::Preprocess(
|
||||
*includes, preprocessRule, this->GetImportPrefixWithSlash());
|
||||
if (!prepro.empty()) {
|
||||
this->ResolveTargetsInGeneratorExpressions(prepro, target);
|
||||
|
||||
if (!this->CheckInterfaceDirs(prepro, target, propName)) {
|
||||
return;
|
||||
}
|
||||
properties[propName] = prepro;
|
||||
}
|
||||
}
|
||||
|
||||
void cmExportInstallFileGenerator::PopulateLinkDependsInterface(
|
||||
cmGeneratorTarget const* gt,
|
||||
cmGeneratorExpression::PreprocessContext preprocessRule,
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "cmStateTypes.h"
|
||||
|
||||
class cmGeneratorTarget;
|
||||
class cmGeneratorFileSet;
|
||||
class cmInstallTargetGenerator;
|
||||
class cmTargetExport;
|
||||
|
||||
@@ -138,6 +139,10 @@ protected:
|
||||
ImportPropertyMap& properties,
|
||||
std::set<std::string>& importedLocations);
|
||||
|
||||
using cmExportFileGenerator::PopulateFileSetInterfaceProperties;
|
||||
bool PopulateFileSetInterfaceProperties(
|
||||
cmTargetExport const* targetExport, ImportFileSetPropertyMap& properties);
|
||||
|
||||
virtual bool CheckInterfaceDirs(std::string const& prepro,
|
||||
cmGeneratorTarget const* target,
|
||||
std::string const& prop) const;
|
||||
@@ -179,4 +184,9 @@ private:
|
||||
cmGeneratorTarget const* target,
|
||||
cmGeneratorExpression::PreprocessContext preprocessRule,
|
||||
ImportPropertyMap& properties);
|
||||
|
||||
void PopulateFileSetIncludeDirectoriesInterface(
|
||||
cmGeneratorTarget const* target, cmGeneratorFileSet const* fileSet,
|
||||
cmGeneratorExpression::PreprocessContext preprocessRule,
|
||||
ImportPropertyMap& properties);
|
||||
};
|
||||
|
||||
40
Tests/RunCMake/FileSet-SOURCES/FileSetExport.cmake
Normal file
40
Tests/RunCMake/FileSet-SOURCES/FileSetExport.cmake
Normal file
@@ -0,0 +1,40 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(lib1 STATIC)
|
||||
target_sources(lib1 PRIVATE lib1.c)
|
||||
target_sources(lib1 PUBLIC FILE_SET a TYPE SOURCES FILES lib2.c)
|
||||
|
||||
set_property(FILE_SET a TARGET lib1 PROPERTY COMPILE_DEFINITIONS LIB1_A)
|
||||
set_property(FILE_SET a TARGET lib1 PROPERTY COMPILE_OPTIONS -DOPT_LIB1_A)
|
||||
set_property(FILE_SET a TARGET lib1 PROPERTY INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/subdir1>"
|
||||
"$<INSTALL_INTERFACE:include/subdir1>")
|
||||
|
||||
set_property(FILE_SET a TARGET lib1 PROPERTY INTERFACE_COMPILE_DEFINITIONS INTERFACE_LIB1_A)
|
||||
set_property(FILE_SET a TARGET lib1 PROPERTY INTERFACE_COMPILE_OPTIONS -DOPT_INTERFACE_LIB1_A)
|
||||
set_property(FILE_SET a TARGET lib1 PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/subdir2>"
|
||||
"$<INSTALL_INTERFACE:include/subdir2>")
|
||||
|
||||
target_sources(lib1 PUBLIC FILE_SET SOURCES FILES lib5.c)
|
||||
|
||||
set_property(FILE_SET SOURCES TARGET lib1 PROPERTY INTERFACE_COMPILE_DEFINITIONS INTERFACE_LIB1_SRCS)
|
||||
set_property(FILE_SET SOURCES TARGET lib1 PROPERTY INTERFACE_COMPILE_OPTIONS -DOPT_INTERFACE_LIB1_SRCS)
|
||||
set_property(FILE_SET SOURCES TARGET lib1 PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/srcs>"
|
||||
"$<INSTALL_INTERFACE:include/srcs>")
|
||||
|
||||
|
||||
add_executable(main main.c)
|
||||
target_link_libraries(main PRIVATE lib1)
|
||||
target_compile_definitions(main PRIVATE CONSUMER)
|
||||
|
||||
if(CMAKE_GENERATOR MATCHES "Xcode")
|
||||
install(TARGETS lib1 EXPORT export FILE_SET a DESTINATION sources
|
||||
FILE_SET SOURCES DESTINATION sources/srcs)
|
||||
else()
|
||||
install(TARGETS lib1 EXPORT export FILE_SET a DESTINATION sources
|
||||
FILE_SET SOURCES DESTINATION sources/$<IF:$<CONFIG:Debug>,debug,release>)
|
||||
endif()
|
||||
install(FILES subdir1/h1.h subdir1/h3.h DESTINATION include/subdir1)
|
||||
install(FILES subdir2/h2.h subdir2/h3.h DESTINATION include/subdir2)
|
||||
|
||||
install(EXPORT export FILE export.cmake NAMESPACE install:: DESTINATION lib/cmake)
|
||||
export(EXPORT export FILE export.cmake NAMESPACE export::)
|
||||
85
Tests/RunCMake/FileSet-SOURCES/FileSetImport.cmake
Normal file
85
Tests/RunCMake/FileSet-SOURCES/FileSetImport.cmake
Normal file
@@ -0,0 +1,85 @@
|
||||
enable_language(C)
|
||||
|
||||
get_property(multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
|
||||
function(assert_target_prop_eq tgt prop value)
|
||||
unset(actual_value)
|
||||
get_property(actual_value TARGET ${tgt} PROPERTY ${prop})
|
||||
if(NOT actual_value STREQUAL value)
|
||||
message(SEND_ERROR "Expected value of target ${prop}:\n ${value}\nActual value:\n ${actual_value}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(assert_fileset_prop_eq tgt fs prop value)
|
||||
unset(actual_value)
|
||||
get_property(actual_value FILE_SET ${fs} TARGET ${tgt} PROPERTY ${prop})
|
||||
if(NOT actual_value STREQUAL value)
|
||||
message(SEND_ERROR "Expected value of file set ${prop}:\n ${value}\nActual value:\n ${actual_value}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
cmake_path(GET CMAKE_BINARY_DIR PARENT_PATH export_build_dir)
|
||||
cmake_path(APPEND export_build_dir "FileSetExport-build")
|
||||
|
||||
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_EQUAL 4.3
|
||||
AND NOT CMAKE_PATCH_VERSION VERSION_LESS 20000000)
|
||||
# development version for future 4.4: Force version 4.4
|
||||
set(CMAKE_VERSION_BACKUP "${CMAKE_VERSION}")
|
||||
set(CMAKE_VERSION 4.4)
|
||||
endif()
|
||||
include("${export_build_dir}/export.cmake")
|
||||
include("${export_build_dir}/install/lib/cmake/export.cmake")
|
||||
if(CMAKE_VERSION VERSION_GREATER 4.3 AND CMAKE_VERSION VERSION_LESS 4.4
|
||||
AND NOT CMake_VERSION_PATCH VERSION_LESS 20000000)
|
||||
# development version for future 4.4: Force version 4.4
|
||||
set(CMAKE_VERSION "${CMAKE_VERSION_BACKUP}")
|
||||
endif()
|
||||
|
||||
|
||||
assert_target_prop_eq(export::lib1 SOURCE_SETS "")
|
||||
assert_target_prop_eq(export::lib1 INTERFACE_SOURCE_SETS "a;SOURCES")
|
||||
assert_target_prop_eq(export::lib1 SOURCE_SET_a "${CMAKE_CURRENT_SOURCE_DIR}/lib2.c")
|
||||
assert_target_prop_eq(export::lib1 SOURCE_SET "${CMAKE_CURRENT_SOURCE_DIR}/lib5.c")
|
||||
assert_target_prop_eq(export::lib1 SOURCE_SET_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/lib5.c")
|
||||
|
||||
assert_fileset_prop_eq(export::lib1 a INTERFACE_COMPILE_DEFINITIONS "INTERFACE_LIB1_A")
|
||||
assert_fileset_prop_eq(export::lib1 a INTERFACE_COMPILE_OPTIONS "-DOPT_INTERFACE_LIB1_A")
|
||||
assert_fileset_prop_eq(export::lib1 a INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/subdir2")
|
||||
|
||||
assert_fileset_prop_eq(export::lib1 SOURCES INTERFACE_COMPILE_DEFINITIONS "INTERFACE_LIB1_SRCS")
|
||||
assert_fileset_prop_eq(export::lib1 SOURCES INTERFACE_COMPILE_OPTIONS "-DOPT_INTERFACE_LIB1_SRCS")
|
||||
assert_fileset_prop_eq(export::lib1 SOURCES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/srcs")
|
||||
|
||||
|
||||
assert_target_prop_eq(install::lib1 SOURCE_SETS "")
|
||||
assert_target_prop_eq(install::lib1 INTERFACE_SOURCE_SETS "a;SOURCES")
|
||||
assert_target_prop_eq(install::lib1 SOURCE_SET_a "${export_build_dir}/install/sources/lib2.c")
|
||||
if(multi_config)
|
||||
if(CMAKE_GENERATOR MATCHES "Xcode")
|
||||
assert_target_prop_eq(install::lib1 SOURCE_SET "${export_build_dir}/install/sources/srcs/lib5.c")
|
||||
assert_target_prop_eq(install::lib1 SOURCE_SET_SOURCES "${export_build_dir}/install/sources/srcs/lib5.c")
|
||||
else()
|
||||
assert_target_prop_eq(install::lib1 SOURCE_SET "$<$<CONFIG:Debug>:${export_build_dir}/install/sources/debug/lib5.c>;$<$<CONFIG:Release>:${export_build_dir}/install/sources/release/lib5.c>")
|
||||
assert_target_prop_eq(install::lib1 SOURCE_SET_SOURCES "$<$<CONFIG:Debug>:${export_build_dir}/install/sources/debug/lib5.c>;$<$<CONFIG:Release>:${export_build_dir}/install/sources/release/lib5.c>")
|
||||
endif()
|
||||
else()
|
||||
assert_target_prop_eq(install::lib1 SOURCE_SET "${export_build_dir}/install/sources/debug/lib5.c")
|
||||
assert_target_prop_eq(install::lib1 SOURCE_SET_SOURCES "${export_build_dir}/install/sources/debug/lib5.c")
|
||||
endif()
|
||||
|
||||
assert_fileset_prop_eq(install::lib1 a INTERFACE_COMPILE_DEFINITIONS "INTERFACE_LIB1_A")
|
||||
assert_fileset_prop_eq(install::lib1 a INTERFACE_COMPILE_OPTIONS "-DOPT_INTERFACE_LIB1_A")
|
||||
assert_fileset_prop_eq(install::lib1 a INTERFACE_INCLUDE_DIRECTORIES "${export_build_dir}/install/include/subdir2")
|
||||
|
||||
assert_fileset_prop_eq(install::lib1 SOURCES INTERFACE_COMPILE_DEFINITIONS "INTERFACE_LIB1_SRCS")
|
||||
assert_fileset_prop_eq(install::lib1 SOURCES INTERFACE_COMPILE_OPTIONS "-DOPT_INTERFACE_LIB1_SRCS")
|
||||
assert_fileset_prop_eq(install::lib1 SOURCES INTERFACE_INCLUDE_DIRECTORIES "${export_build_dir}/install/include/srcs")
|
||||
|
||||
|
||||
add_executable(main_export main.c)
|
||||
target_link_libraries(main_export PRIVATE export::lib1)
|
||||
target_compile_definitions(main_export PRIVATE CONSUMER)
|
||||
|
||||
add_executable(main_install main.c)
|
||||
target_link_libraries(main_install PRIVATE install::lib1)
|
||||
target_compile_definitions(main_install PRIVATE CONSUMER)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,5 @@
|
||||
CMake Error at InstallMissingSetsInterface\.cmake:[0-9]+ \(install\):
|
||||
install TARGETS target lib1 is exported but not all of its interface file
|
||||
sets are installed
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
@@ -0,0 +1,5 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(lib1 STATIC)
|
||||
target_sources(lib1 INTERFACE FILE_SET a TYPE SOURCES BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} FILES lib1.c)
|
||||
install(TARGETS lib1 EXPORT a)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,6 @@
|
||||
CMake Error in CMakeLists\.txt:
|
||||
File set "a" is listed in interface file sets of lib1 but has not been
|
||||
exported
|
||||
|
||||
|
||||
CMake Generate step failed\. Build files cannot be regenerated correctly\.
|
||||
@@ -0,0 +1,6 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(lib1 STATIC)
|
||||
install(TARGETS lib1 EXPORT a)
|
||||
target_sources(lib1 INTERFACE FILE_SET a TYPE SOURCES BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} FILES lib1.c)
|
||||
install(EXPORT a DESTINATION lib/cmake/test)
|
||||
@@ -41,3 +41,53 @@ if ((RunCMake_GENERATOR MATCHES "Makefiles|Ninja|Xcode"
|
||||
AND NOT CMAKE_C_COMPILER_ID STREQUAL "Intel")
|
||||
run_and_check(FileSetProperties2 lib1 main)
|
||||
endif()
|
||||
|
||||
function(run_export_import name)
|
||||
if(ARGV1)
|
||||
set(importname ${ARGV1})
|
||||
else()
|
||||
set(importname ${name})
|
||||
endif()
|
||||
|
||||
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
set(_config_options "-DCMAKE_CONFIGURATION_TYPES=Debug\\\\;Release")
|
||||
else()
|
||||
set(_config_options -DCMAKE_BUILD_TYPE=Debug)
|
||||
endif()
|
||||
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${name}Export-build")
|
||||
set(RunCMake_TEST_OPTIONS "--install-prefix=${RunCMake_TEST_BINARY_DIR}/install" ${_config_options})
|
||||
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
|
||||
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
|
||||
run_cmake(${name}Export)
|
||||
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
run_cmake_command(${name}Export-build-Debug ${CMAKE_COMMAND} --build . --config Debug)
|
||||
run_cmake_command(${name}Export-install-Debug ${CMAKE_COMMAND} --install . --config Debug)
|
||||
run_cmake_command(${name}Export-build-Release ${CMAKE_COMMAND} --build . --config Release)
|
||||
run_cmake_command(${name}Export-install-Release ${CMAKE_COMMAND} --install . --config Release)
|
||||
else()
|
||||
run_cmake_command(${name}Export-build ${CMAKE_COMMAND} --build . --config Debug)
|
||||
run_cmake_command(${name}Export-install ${CMAKE_COMMAND} --install . --config Debug)
|
||||
endif()
|
||||
unset(RunCMake_TEST_OPTIONS)
|
||||
|
||||
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${importname}Import-build")
|
||||
unset(RunCMake_TEST_OPTIONS)
|
||||
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
|
||||
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
|
||||
run_cmake(${importname}Import)
|
||||
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
run_cmake_command(${importname}Import-build-Debug ${CMAKE_COMMAND} --build . --config Debug)
|
||||
run_cmake_command(${importname}Import-build-Release ${CMAKE_COMMAND} --build . --config Release)
|
||||
else()
|
||||
run_cmake_command(${importname}Import-build ${CMAKE_COMMAND} --build . --config Debug)
|
||||
endif()
|
||||
|
||||
unset(RunCMake_TEST_BINARY_DIR)
|
||||
unset(RunCMake_TEST_NO_CLEAN)
|
||||
endfunction()
|
||||
|
||||
run_cmake(InstallMissingSetsInterface)
|
||||
run_cmake(InstallMissingSetsInterfacePostInstall)
|
||||
run_export_import(FileSet)
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
void f5(void)
|
||||
{
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user