mirror of
https://github.com/Kitware/CMake.git
synced 2026-08-04 06:40:24 +00:00
FILE_SET: enhance FRAMEWORK compatibility checks
The SOURCES file set type is compatible with the FRAMEWORK target. Add check at generation time. Fixes: #27705
This commit is contained in:
@@ -109,7 +109,8 @@ files within those directories.
|
|||||||
``INTERFACE`` scope except on ``IMPORTED`` targets.
|
``INTERFACE`` scope except on ``IMPORTED`` targets.
|
||||||
|
|
||||||
The optional default file sets are named after their type. The target may not
|
The optional default file sets are named after their type. The target may not
|
||||||
be a custom target or :prop_tgt:`FRAMEWORK` target.
|
be a custom target or, for ``HEADERS`` and ``CXX_MODULES`` types, a
|
||||||
|
:prop_tgt:`FRAMEWORK` target.
|
||||||
|
|
||||||
Files in a ``PRIVATE`` or ``PUBLIC`` file set are marked as source files for
|
Files in a ``PRIVATE`` or ``PUBLIC`` file set are marked as source files for
|
||||||
the purposes of IDE integration. Additionally, files in ``HEADERS`` file sets
|
the purposes of IDE integration. Additionally, files in ``HEADERS`` file sets
|
||||||
|
|||||||
@@ -85,17 +85,20 @@ std::map<cm::string_view, FileSetDescriptor> const FileSetDescriptors{
|
|||||||
{ cm::FileSetMetadata::HEADERS,
|
{ cm::FileSetMetadata::HEADERS,
|
||||||
cm::FileSetMetadata::FileSetLookup::Target,
|
cm::FileSetMetadata::FileSetLookup::Target,
|
||||||
{ DependencyMode ::Includables },
|
{ DependencyMode ::Includables },
|
||||||
DependencyMode ::Includables } },
|
DependencyMode ::Includables,
|
||||||
|
FrameworkCompatible::No } },
|
||||||
{ cm::FileSetMetadata::SOURCES,
|
{ cm::FileSetMetadata::SOURCES,
|
||||||
{ cm::FileSetMetadata::SOURCES,
|
{ cm::FileSetMetadata::SOURCES,
|
||||||
cm::FileSetMetadata::FileSetLookup::Dependencies,
|
cm::FileSetMetadata::FileSetLookup::Dependencies,
|
||||||
{ DependencyMode ::IndependentFiles, DependencyMode ::Includables },
|
{ DependencyMode ::IndependentFiles, DependencyMode ::Includables },
|
||||||
DependencyMode ::Includables } },
|
DependencyMode ::Includables,
|
||||||
|
FrameworkCompatible::Yes } },
|
||||||
{ cm::FileSetMetadata::CXX_MODULES,
|
{ cm::FileSetMetadata::CXX_MODULES,
|
||||||
{ cm::FileSetMetadata::CXX_MODULES,
|
{ cm::FileSetMetadata::CXX_MODULES,
|
||||||
cm::FileSetMetadata::FileSetLookup::Target,
|
cm::FileSetMetadata::FileSetLookup::Target,
|
||||||
{ DependencyMode ::IndependentFiles },
|
{ DependencyMode ::IndependentFiles },
|
||||||
DependencyMode ::IndependentFiles } },
|
DependencyMode ::IndependentFiles,
|
||||||
|
FrameworkCompatible::No } },
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<cm::string_view> KnownTypes{ HEADERS, SOURCES, CXX_MODULES };
|
std::vector<cm::string_view> KnownTypes{ HEADERS, SOURCES, CXX_MODULES };
|
||||||
@@ -135,6 +138,15 @@ DependencyMode GetDependencyMode(cm::string_view type,
|
|||||||
return DependencyMode::Includables;
|
return DependencyMode::Includables;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsFrameworkSupported(cm::string_view type)
|
||||||
|
{
|
||||||
|
auto descriptor = GetFileSetDescriptor(type);
|
||||||
|
if (descriptor) {
|
||||||
|
return descriptor->FrameworkSupported == FrameworkCompatible::Yes;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<cm::string_view> const& GetKnownTypes()
|
std::vector<cm::string_view> const& GetKnownTypes()
|
||||||
{
|
{
|
||||||
return KnownTypes;
|
return KnownTypes;
|
||||||
|
|||||||
@@ -52,15 +52,23 @@ enum class DependencyMode
|
|||||||
};
|
};
|
||||||
using DependencySet = std::set<DependencyMode>;
|
using DependencySet = std::set<DependencyMode>;
|
||||||
|
|
||||||
|
enum class FrameworkCompatible
|
||||||
|
{
|
||||||
|
No,
|
||||||
|
Yes
|
||||||
|
};
|
||||||
|
|
||||||
struct FileSetDescriptor
|
struct FileSetDescriptor
|
||||||
{
|
{
|
||||||
FileSetDescriptor(cm::string_view type, FileSetLookup lookup,
|
FileSetDescriptor(cm::string_view type, FileSetLookup lookup,
|
||||||
DependencySet dependencies,
|
DependencySet dependencies,
|
||||||
DependencyMode defaultDependency)
|
DependencyMode defaultDependency,
|
||||||
|
FrameworkCompatible frameworkSupported)
|
||||||
: Type(type)
|
: Type(type)
|
||||||
, Lookup(lookup)
|
, Lookup(lookup)
|
||||||
, SupportedDependencies(std::move(dependencies))
|
, SupportedDependencies(std::move(dependencies))
|
||||||
, DefaultDependency(defaultDependency)
|
, DefaultDependency(defaultDependency)
|
||||||
|
, FrameworkSupported(frameworkSupported)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,6 +77,7 @@ struct FileSetDescriptor
|
|||||||
, Lookup(lookup)
|
, Lookup(lookup)
|
||||||
, SupportedDependencies({ DependencyMode::Includables })
|
, SupportedDependencies({ DependencyMode::Includables })
|
||||||
, DefaultDependency(DependencyMode::Includables)
|
, DefaultDependency(DependencyMode::Includables)
|
||||||
|
, FrameworkSupported(FrameworkCompatible::No)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,12 +85,14 @@ struct FileSetDescriptor
|
|||||||
FileSetLookup const Lookup;
|
FileSetLookup const Lookup;
|
||||||
DependencySet const SupportedDependencies;
|
DependencySet const SupportedDependencies;
|
||||||
DependencyMode const DefaultDependency;
|
DependencyMode const DefaultDependency;
|
||||||
|
FrameworkCompatible const FrameworkSupported;
|
||||||
};
|
};
|
||||||
|
|
||||||
cm::optional<FileSetDescriptor> GetFileSetDescriptor(cm::string_view type);
|
cm::optional<FileSetDescriptor> GetFileSetDescriptor(cm::string_view type);
|
||||||
DependencyMode GetDependencyMode(cm::string_view type);
|
DependencyMode GetDependencyMode(cm::string_view type);
|
||||||
DependencyMode GetDependencyMode(cm::string_view type,
|
DependencyMode GetDependencyMode(cm::string_view type,
|
||||||
DependencyMode requestedMode);
|
DependencyMode requestedMode);
|
||||||
|
bool IsFrameworkSupported(cm::string_view type);
|
||||||
|
|
||||||
std::vector<cm::string_view> const& GetKnownTypes();
|
std::vector<cm::string_view> const& GetKnownTypes();
|
||||||
bool IsKnownType(cm::string_view type);
|
bool IsKnownType(cm::string_view type);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <cm/optional>
|
#include <cm/optional>
|
||||||
#include <cmext/algorithm>
|
#include <cmext/algorithm>
|
||||||
|
|
||||||
|
#include "cmFileSet.h"
|
||||||
#include "cmFileSetMetadata.h"
|
#include "cmFileSetMetadata.h"
|
||||||
#include "cmGenExContext.h"
|
#include "cmGenExContext.h"
|
||||||
#include "cmGenExEvaluation.h"
|
#include "cmGenExEvaluation.h"
|
||||||
@@ -24,6 +25,8 @@
|
|||||||
#include "cmLinkItem.h"
|
#include "cmLinkItem.h"
|
||||||
#include "cmList.h"
|
#include "cmList.h"
|
||||||
#include "cmListFileCache.h"
|
#include "cmListFileCache.h"
|
||||||
|
#include "cmMakefile.h"
|
||||||
|
#include "cmMessageType.h"
|
||||||
#include "cmSourceFile.h"
|
#include "cmSourceFile.h"
|
||||||
#include "cmStringAlgorithms.h"
|
#include "cmStringAlgorithms.h"
|
||||||
#include "cmSystemTools.h"
|
#include "cmSystemTools.h"
|
||||||
@@ -35,30 +38,47 @@ cmGeneratorFileSets::cmGeneratorFileSets(cmGeneratorTarget* target,
|
|||||||
: Target(target)
|
: Target(target)
|
||||||
, LocalGenerator(lg)
|
, LocalGenerator(lg)
|
||||||
{
|
{
|
||||||
for (auto const& name : target->Target->GetAllPrivateFileSets()) {
|
bool isFramework = target->IsFrameworkOnApple();
|
||||||
auto entry =
|
auto issueMessage = [&target](cmFileSet const* fileSet) {
|
||||||
this->FileSets.emplace(name,
|
target->Makefile->IssueMessage(
|
||||||
cm::make_unique<cmGeneratorFileSet>(
|
MessageType::FATAL_ERROR,
|
||||||
target, target->Target->GetFileSet(name)));
|
cmStrCat(R"(The file set ")", fileSet->GetName(), R"(", of type ")",
|
||||||
|
fileSet->GetType(),
|
||||||
|
R"(", is incompatible with the "FRAMEWORK" target ")",
|
||||||
|
target->GetName(), R"(".)"));
|
||||||
|
};
|
||||||
|
|
||||||
auto const* fileSet = entry.first->second.get();
|
for (auto const& name : target->Target->GetAllPrivateFileSets()) {
|
||||||
this->AllFileSets.push_back(fileSet);
|
cmFileSet const* fileSet = target->Target->GetFileSet(name);
|
||||||
this->SelfFileSets[fileSet->GetType()].push_back(fileSet);
|
if (isFramework &&
|
||||||
|
!cm::FileSetMetadata::IsFrameworkSupported(fileSet->GetType())) {
|
||||||
|
issueMessage(fileSet);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto entry = this->FileSets.emplace(
|
||||||
|
name, cm::make_unique<cmGeneratorFileSet>(target, fileSet));
|
||||||
|
auto const* genFileSet = entry.first->second.get();
|
||||||
|
this->AllFileSets.push_back(genFileSet);
|
||||||
|
this->SelfFileSets[genFileSet->GetType()].push_back(genFileSet);
|
||||||
}
|
}
|
||||||
for (auto const& name : target->Target->GetAllInterfaceFileSets()) {
|
for (auto const& name : target->Target->GetAllInterfaceFileSets()) {
|
||||||
auto it = this->FileSets.find(name);
|
auto it = this->FileSets.find(name);
|
||||||
cmGeneratorFileSet const* fileSet = nullptr;
|
cmGeneratorFileSet const* genFileSet = nullptr;
|
||||||
if (it == this->FileSets.end()) {
|
if (it == this->FileSets.end()) {
|
||||||
auto entry =
|
cmFileSet const* fileSet = target->Target->GetFileSet(name);
|
||||||
this->FileSets.emplace(name,
|
if (isFramework &&
|
||||||
cm::make_unique<cmGeneratorFileSet>(
|
!cm::FileSetMetadata::IsFrameworkSupported(fileSet->GetType())) {
|
||||||
target, target->Target->GetFileSet(name)));
|
issueMessage(fileSet);
|
||||||
fileSet = entry.first->second.get();
|
continue;
|
||||||
this->AllFileSets.push_back(fileSet);
|
}
|
||||||
|
auto entry = this->FileSets.emplace(
|
||||||
|
name, cm::make_unique<cmGeneratorFileSet>(target, fileSet));
|
||||||
|
genFileSet = entry.first->second.get();
|
||||||
|
this->AllFileSets.push_back(genFileSet);
|
||||||
} else {
|
} else {
|
||||||
fileSet = it->second.get();
|
genFileSet = it->second.get();
|
||||||
}
|
}
|
||||||
this->InterfaceFileSets[fileSet->GetType()].push_back(fileSet);
|
this->InterfaceFileSets[genFileSet->GetType()].push_back(genFileSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmGeneratorFileSets::~cmGeneratorFileSets() = default;
|
cmGeneratorFileSets::~cmGeneratorFileSets() = default;
|
||||||
|
|||||||
@@ -228,10 +228,6 @@ bool TargetSourcesImpl::HandleOneFileSet(
|
|||||||
this->SetError("FILE_SETs may not be added to custom targets");
|
this->SetError("FILE_SETs may not be added to custom targets");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (this->Target->IsFrameworkOnApple()) {
|
|
||||||
this->SetError("FILE_SETs may not be added to FRAMEWORK targets");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!args.Type.empty() && !cm::FileSetMetadata::IsKnownType(args.Type)) {
|
if (!args.Type.empty() && !cm::FileSetMetadata::IsKnownType(args.Type)) {
|
||||||
this->SetError(
|
this->SetError(
|
||||||
@@ -269,6 +265,13 @@ bool TargetSourcesImpl::HandleOneFileSet(
|
|||||||
cm::FileSetMetadata::Visibility visibility =
|
cm::FileSetMetadata::Visibility visibility =
|
||||||
cm::FileSetMetadata::VisibilityFromName(scope, this->Makefile);
|
cm::FileSetMetadata::VisibilityFromName(scope, this->Makefile);
|
||||||
|
|
||||||
|
if (this->Target->IsFrameworkOnApple() &&
|
||||||
|
!cm::FileSetMetadata::IsFrameworkSupported(type)) {
|
||||||
|
this->SetError(cmStrCat(R"(FILE_SETs, of type ")", type,
|
||||||
|
R"(", may not be added to FRAMEWORK targets)"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto fileSet =
|
auto fileSet =
|
||||||
this->Target->GetOrCreateFileSet(args.FileSet, type, visibility);
|
this->Target->GetOrCreateFileSet(args.FileSet, type, visibility);
|
||||||
if (fileSet.second) {
|
if (fileSet.second) {
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
CMake Error in CMakeLists\.txt:
|
||||||
|
The file set "HEADERS", of type "HEADERS", is incompatible with the
|
||||||
|
"FRAMEWORK" target "lib1"\.
|
||||||
8
Tests/RunCMake/FileSet-SOURCES/FileSetFramework1.cmake
Normal file
8
Tests/RunCMake/FileSet-SOURCES/FileSetFramework1.cmake
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
enable_language(C)
|
||||||
|
|
||||||
|
add_library(lib1 SHARED)
|
||||||
|
target_sources(lib1
|
||||||
|
PUBLIC FILE_SET SOURCES FILES lib1.c
|
||||||
|
FILE_SET HEADERS FILES lib1.h
|
||||||
|
)
|
||||||
|
set_property(TARGET lib1 PROPERTY FRAMEWORK ON)
|
||||||
7
Tests/RunCMake/FileSet-SOURCES/FileSetFramework2.cmake
Normal file
7
Tests/RunCMake/FileSet-SOURCES/FileSetFramework2.cmake
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
enable_language(C)
|
||||||
|
|
||||||
|
add_library(lib1 SHARED)
|
||||||
|
target_sources(lib1
|
||||||
|
PUBLIC FILE_SET SOURCES FILES lib1.c
|
||||||
|
)
|
||||||
|
set_property(TARGET lib1 PROPERTY FRAMEWORK ON)
|
||||||
@@ -34,6 +34,10 @@ run_and_build(CustomCommandInput)
|
|||||||
run_and_build(IncludeDirectoriesOrder)
|
run_and_build(IncludeDirectoriesOrder)
|
||||||
run_and_build(FileSetTransitivity)
|
run_and_build(FileSetTransitivity)
|
||||||
run_and_check(CompileOptionsOrder)
|
run_and_check(CompileOptionsOrder)
|
||||||
|
if(APPLE)
|
||||||
|
run_cmake(FileSetFramework1)
|
||||||
|
run_and_build(FileSetFramework2)
|
||||||
|
endif()
|
||||||
if (RunCMake_GENERATOR MATCHES "Ninja")
|
if (RunCMake_GENERATOR MATCHES "Ninja")
|
||||||
run_cmake(IndependentFilesWarning)
|
run_cmake(IndependentFilesWarning)
|
||||||
if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
^CMake Error at FileSetFramework\.cmake:[0-9]+ \(target_sources\):
|
|
||||||
target_sources FILE_SETs may not be added to FRAMEWORK targets
|
|
||||||
Call Stack \(most recent call first\):
|
|
||||||
CMakeLists\.txt:[0-9]+ \(include\)$
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
CMake Error at FileSetFramework1\.cmake:[0-9]+ \(target_sources\):
|
||||||
|
target_sources FILE_SETs, of type "HEADERS", may not be added to FRAMEWORK
|
||||||
|
targets
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists\.txt:[0-9]+ \(include\)$
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
CMake Error in CMakeLists\.txt:
|
||||||
|
The file set "HEADERS", of type "HEADERS", is incompatible with the
|
||||||
|
"FRAMEWORK" target "lib1"\.
|
||||||
7
Tests/RunCMake/target_sources/FileSetFramework2.cmake
Normal file
7
Tests/RunCMake/target_sources/FileSetFramework2.cmake
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
enable_language(C)
|
||||||
|
|
||||||
|
add_library(lib1 SHARED lib1.c)
|
||||||
|
target_sources(lib1
|
||||||
|
PUBLIC FILE_SET HEADERS BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} FILES h1.h
|
||||||
|
)
|
||||||
|
set_property(TARGET lib1 PROPERTY FRAMEWORK ON)
|
||||||
@@ -46,7 +46,8 @@ run_cmake(FileSetWrongSyntax)
|
|||||||
run_cmake(FileSetDirect)
|
run_cmake(FileSetDirect)
|
||||||
run_cmake(FileSetDuplicateSource)
|
run_cmake(FileSetDuplicateSource)
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
run_cmake(FileSetFramework)
|
run_cmake(FileSetFramework1)
|
||||||
|
run_cmake(FileSetFramework2)
|
||||||
endif()
|
endif()
|
||||||
run_cmake(CMP0211-OLD)
|
run_cmake(CMP0211-OLD)
|
||||||
run_cmake(CMP0211-NEW)
|
run_cmake(CMP0211-NEW)
|
||||||
|
|||||||
Reference in New Issue
Block a user