mirror of
https://github.com/Kitware/CMake.git
synced 2026-08-03 22:30:29 +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.
|
||||
|
||||
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
|
||||
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::FileSetLookup::Target,
|
||||
{ DependencyMode ::Includables },
|
||||
DependencyMode ::Includables } },
|
||||
DependencyMode ::Includables,
|
||||
FrameworkCompatible::No } },
|
||||
{ cm::FileSetMetadata::SOURCES,
|
||||
{ cm::FileSetMetadata::SOURCES,
|
||||
cm::FileSetMetadata::FileSetLookup::Dependencies,
|
||||
{ DependencyMode ::IndependentFiles, DependencyMode ::Includables },
|
||||
DependencyMode ::Includables } },
|
||||
DependencyMode ::Includables,
|
||||
FrameworkCompatible::Yes } },
|
||||
{ cm::FileSetMetadata::CXX_MODULES,
|
||||
{ cm::FileSetMetadata::CXX_MODULES,
|
||||
cm::FileSetMetadata::FileSetLookup::Target,
|
||||
{ DependencyMode ::IndependentFiles },
|
||||
DependencyMode ::IndependentFiles } },
|
||||
DependencyMode ::IndependentFiles,
|
||||
FrameworkCompatible::No } },
|
||||
};
|
||||
|
||||
std::vector<cm::string_view> KnownTypes{ HEADERS, SOURCES, CXX_MODULES };
|
||||
@@ -135,6 +138,15 @@ DependencyMode GetDependencyMode(cm::string_view type,
|
||||
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()
|
||||
{
|
||||
return KnownTypes;
|
||||
|
||||
@@ -52,15 +52,23 @@ enum class DependencyMode
|
||||
};
|
||||
using DependencySet = std::set<DependencyMode>;
|
||||
|
||||
enum class FrameworkCompatible
|
||||
{
|
||||
No,
|
||||
Yes
|
||||
};
|
||||
|
||||
struct FileSetDescriptor
|
||||
{
|
||||
FileSetDescriptor(cm::string_view type, FileSetLookup lookup,
|
||||
DependencySet dependencies,
|
||||
DependencyMode defaultDependency)
|
||||
DependencyMode defaultDependency,
|
||||
FrameworkCompatible frameworkSupported)
|
||||
: Type(type)
|
||||
, Lookup(lookup)
|
||||
, SupportedDependencies(std::move(dependencies))
|
||||
, DefaultDependency(defaultDependency)
|
||||
, FrameworkSupported(frameworkSupported)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -69,6 +77,7 @@ struct FileSetDescriptor
|
||||
, Lookup(lookup)
|
||||
, SupportedDependencies({ DependencyMode::Includables })
|
||||
, DefaultDependency(DependencyMode::Includables)
|
||||
, FrameworkSupported(FrameworkCompatible::No)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -76,12 +85,14 @@ struct FileSetDescriptor
|
||||
FileSetLookup const Lookup;
|
||||
DependencySet const SupportedDependencies;
|
||||
DependencyMode const DefaultDependency;
|
||||
FrameworkCompatible const FrameworkSupported;
|
||||
};
|
||||
|
||||
cm::optional<FileSetDescriptor> GetFileSetDescriptor(cm::string_view type);
|
||||
DependencyMode GetDependencyMode(cm::string_view type);
|
||||
DependencyMode GetDependencyMode(cm::string_view type,
|
||||
DependencyMode requestedMode);
|
||||
bool IsFrameworkSupported(cm::string_view type);
|
||||
|
||||
std::vector<cm::string_view> const& GetKnownTypes();
|
||||
bool IsKnownType(cm::string_view type);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <cm/optional>
|
||||
#include <cmext/algorithm>
|
||||
|
||||
#include "cmFileSet.h"
|
||||
#include "cmFileSetMetadata.h"
|
||||
#include "cmGenExContext.h"
|
||||
#include "cmGenExEvaluation.h"
|
||||
@@ -24,6 +25,8 @@
|
||||
#include "cmLinkItem.h"
|
||||
#include "cmList.h"
|
||||
#include "cmListFileCache.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmMessageType.h"
|
||||
#include "cmSourceFile.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmSystemTools.h"
|
||||
@@ -35,30 +38,47 @@ cmGeneratorFileSets::cmGeneratorFileSets(cmGeneratorTarget* target,
|
||||
: Target(target)
|
||||
, LocalGenerator(lg)
|
||||
{
|
||||
for (auto const& name : target->Target->GetAllPrivateFileSets()) {
|
||||
auto entry =
|
||||
this->FileSets.emplace(name,
|
||||
cm::make_unique<cmGeneratorFileSet>(
|
||||
target, target->Target->GetFileSet(name)));
|
||||
bool isFramework = target->IsFrameworkOnApple();
|
||||
auto issueMessage = [&target](cmFileSet const* fileSet) {
|
||||
target->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
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();
|
||||
this->AllFileSets.push_back(fileSet);
|
||||
this->SelfFileSets[fileSet->GetType()].push_back(fileSet);
|
||||
for (auto const& name : target->Target->GetAllPrivateFileSets()) {
|
||||
cmFileSet const* fileSet = target->Target->GetFileSet(name);
|
||||
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()) {
|
||||
auto it = this->FileSets.find(name);
|
||||
cmGeneratorFileSet const* fileSet = nullptr;
|
||||
cmGeneratorFileSet const* genFileSet = nullptr;
|
||||
if (it == this->FileSets.end()) {
|
||||
auto entry =
|
||||
this->FileSets.emplace(name,
|
||||
cm::make_unique<cmGeneratorFileSet>(
|
||||
target, target->Target->GetFileSet(name)));
|
||||
fileSet = entry.first->second.get();
|
||||
this->AllFileSets.push_back(fileSet);
|
||||
cmFileSet const* fileSet = target->Target->GetFileSet(name);
|
||||
if (isFramework &&
|
||||
!cm::FileSetMetadata::IsFrameworkSupported(fileSet->GetType())) {
|
||||
issueMessage(fileSet);
|
||||
continue;
|
||||
}
|
||||
auto entry = this->FileSets.emplace(
|
||||
name, cm::make_unique<cmGeneratorFileSet>(target, fileSet));
|
||||
genFileSet = entry.first->second.get();
|
||||
this->AllFileSets.push_back(genFileSet);
|
||||
} 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;
|
||||
|
||||
@@ -228,10 +228,6 @@ bool TargetSourcesImpl::HandleOneFileSet(
|
||||
this->SetError("FILE_SETs may not be added to custom targets");
|
||||
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)) {
|
||||
this->SetError(
|
||||
@@ -269,6 +265,13 @@ bool TargetSourcesImpl::HandleOneFileSet(
|
||||
cm::FileSetMetadata::Visibility visibility =
|
||||
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 =
|
||||
this->Target->GetOrCreateFileSet(args.FileSet, type, visibility);
|
||||
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(FileSetTransitivity)
|
||||
run_and_check(CompileOptionsOrder)
|
||||
if(APPLE)
|
||||
run_cmake(FileSetFramework1)
|
||||
run_and_build(FileSetFramework2)
|
||||
endif()
|
||||
if (RunCMake_GENERATOR MATCHES "Ninja")
|
||||
run_cmake(IndependentFilesWarning)
|
||||
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(FileSetDuplicateSource)
|
||||
if(APPLE)
|
||||
run_cmake(FileSetFramework)
|
||||
run_cmake(FileSetFramework1)
|
||||
run_cmake(FileSetFramework2)
|
||||
endif()
|
||||
run_cmake(CMP0211-OLD)
|
||||
run_cmake(CMP0211-NEW)
|
||||
|
||||
Reference in New Issue
Block a user