FILE_SET: properties management

Fixes: #27307
This commit is contained in:
Marc Chevrier
2026-01-27 18:15:26 +01:00
parent d2345b5e67
commit 4113364c49
39 changed files with 518 additions and 77 deletions
+18 -7
View File
@@ -6,16 +6,17 @@ Get a property.
.. code-block:: cmake
get_property(<variable>
<GLOBAL |
DIRECTORY [<dir>] |
TARGET <target> |
<GLOBAL |
DIRECTORY [<dir>] |
TARGET <target> |
FILE_SET <file_set> TARGET <target> |
SOURCE <source>
[DIRECTORY <dir> | TARGET_DIRECTORY <target>] |
INSTALL <file> |
INSTALL <file> |
TEST <test>
[DIRECTORY <dir>] |
CACHE <entry> |
VARIABLE >
[DIRECTORY <dir>] |
CACHE <entry> |
VARIABLE>
PROPERTY <name>
[SET | DEFINED | BRIEF_DOCS | FULL_DOCS])
@@ -42,6 +43,16 @@ It must be one of the following:
Scope must name one existing target.
See also the :command:`get_target_property` command.
``FILE_SET``
.. versionadded:: 4.3
Scope must name one existing file set.
The following option is required:
``TARGET <target>``
The target to which the file set is attached.
``SOURCE``
Scope must name one source file. By default, the source file's property
will be read from the current source directory's scope.
+17 -6
View File
@@ -5,16 +5,17 @@ Set a named property in a given scope.
.. code-block:: cmake
set_property(<GLOBAL |
DIRECTORY [<dir>] |
TARGET [<target1> ...] |
set_property(<GLOBAL |
DIRECTORY [<dir>] |
TARGET [<target1> ...] |
FILE_SET [<file_set> ...] TARGET <target> |
SOURCE [<src1> ...]
[DIRECTORY <dirs> ...]
[TARGET_DIRECTORY <targets> ...] |
INSTALL [<file1> ...] |
INSTALL [<file1> ...] |
TEST [<test1> ...]
[DIRECTORY <dir>] |
CACHE [<entry1> ...] >
[DIRECTORY <dir>] |
CACHE [<entry1> ...]>
[APPEND] [APPEND_STRING]
PROPERTY <name> [<value1> ...])
@@ -41,6 +42,16 @@ It must be one of the following:
:ref:`Alias Targets` do not support setting target properties.
``FILE_SET``
.. versionadded:: 4.3
Scope may name zero or more existing file sets.
The following option is required:
``TARGET <target>``
The target to which the file set is attached.
``SOURCE``
Scope may name zero or more source files. By default, source file properties
are only visible to targets added in the same directory (``CMakeLists.txt``).
+4
View File
@@ -0,0 +1,4 @@
FILE_SET-properties
-------------------
* The ``FILE_SET`` type gained the support of properties.
+94 -4
View File
@@ -88,9 +88,9 @@ bool cmFileSetTypeCanBeIncluded(std::string const& type)
return type == "HEADERS"_s;
}
cmFileSet::cmFileSet(cmake& cmakeInstance, std::string name, std::string type,
cmFileSet::cmFileSet(cmMakefile* makefile, std::string name, std::string type,
cmFileSetVisibility visibility)
: CMakeInstance(cmakeInstance)
: Makefile(makefile)
, Name(std::move(name))
, Type(std::move(type))
, Visibility(visibility)
@@ -130,7 +130,8 @@ cmFileSet::CompileFileEntries() const
for (auto const& entry : this->FileEntries) {
for (auto const& ex : cmList{ entry.Value }) {
cmGeneratorExpression ge(this->CMakeInstance, entry.Backtrace);
cmGeneratorExpression ge(*this->GetMakefile()->GetCMakeInstance(),
entry.Backtrace);
auto cge = ge.Parse(ex);
result.push_back(std::move(cge));
}
@@ -146,7 +147,8 @@ cmFileSet::CompileDirectoryEntries() const
for (auto const& entry : this->DirectoryEntries) {
for (auto const& ex : cmList{ entry.Value }) {
cmGeneratorExpression ge(this->CMakeInstance, entry.Backtrace);
cmGeneratorExpression ge(*this->GetMakefile()->GetCMakeInstance(),
entry.Backtrace);
auto cge = ge.Parse(ex);
result.push_back(std::move(cge));
}
@@ -261,3 +263,91 @@ bool cmFileSet::IsValidName(std::string const& name)
cmsys::RegularExpressionMatch match;
return regex.find(name.c_str(), match);
}
std::string const cmFileSet::propCOMPILE_DEFINITIONS = "COMPILE_DEFINITIONS";
std::string const cmFileSet::propCOMPILE_OPTIONS = "COMPILE_OPTIONS";
std::string const cmFileSet::propINCLUDE_DIRECTORIES = "INCLUDE_DIRECTORIES";
void cmFileSet::SetProperty(std::string const& prop, cmValue value)
{
if (prop == propINCLUDE_DIRECTORIES) {
this->IncludeDirectories.clear();
if (value) {
cmListFileBacktrace lfbt = this->GetMakefile()->GetBacktrace();
this->IncludeDirectories.emplace_back(value, lfbt);
}
} else if (prop == propCOMPILE_OPTIONS) {
this->CompileOptions.clear();
if (value) {
cmListFileBacktrace lfbt = this->GetMakefile()->GetBacktrace();
this->CompileOptions.emplace_back(value, lfbt);
}
} else if (prop == propCOMPILE_DEFINITIONS) {
this->CompileDefinitions.clear();
if (value) {
cmListFileBacktrace lfbt = this->GetMakefile()->GetBacktrace();
this->CompileDefinitions.emplace_back(value, lfbt);
}
} else {
this->Properties.SetProperty(prop, value);
}
}
void cmFileSet::AppendProperty(std::string const& prop,
std::string const& value, bool asString)
{
if (prop == propINCLUDE_DIRECTORIES) {
if (!value.empty()) {
cmListFileBacktrace lfbt = this->GetMakefile()->GetBacktrace();
this->IncludeDirectories.emplace_back(value, lfbt);
}
} else if (prop == propCOMPILE_OPTIONS) {
if (!value.empty()) {
cmListFileBacktrace lfbt = this->GetMakefile()->GetBacktrace();
this->CompileOptions.emplace_back(value, lfbt);
}
} else if (prop == propCOMPILE_DEFINITIONS) {
if (!value.empty()) {
cmListFileBacktrace lfbt = this->GetMakefile()->GetBacktrace();
this->CompileDefinitions.emplace_back(value, lfbt);
}
} else {
this->Properties.AppendProperty(prop, value, asString);
}
}
cmValue cmFileSet::GetProperty(std::string const& prop) const
{
// Check for the properties with backtraces.
if (prop == propINCLUDE_DIRECTORIES) {
if (this->IncludeDirectories.empty()) {
return nullptr;
}
static std::string output;
output = cmList::to_string(this->IncludeDirectories);
return cmValue(output);
}
if (prop == propCOMPILE_OPTIONS) {
if (this->CompileOptions.empty()) {
return nullptr;
}
static std::string output;
output = cmList::to_string(this->CompileOptions);
return cmValue(output);
}
if (prop == propCOMPILE_DEFINITIONS) {
if (this->CompileDefinitions.empty()) {
return nullptr;
}
static std::string output;
output = cmList::to_string(this->CompileDefinitions);
return cmValue(output);
}
return this->Properties.GetPropertyValue(prop);
}
+33 -3
View File
@@ -2,6 +2,7 @@
file LICENSE.rst or https://cmake.org/licensing for details. */
#pragma once
#include <cstddef>
#include <map>
#include <memory>
#include <string>
@@ -11,6 +12,8 @@
#include <cmext/string_view>
#include "cmListFileCache.h"
#include "cmPropertyMap.h"
#include "cmValue.h"
namespace cm {
namespace GenEx {
@@ -22,7 +25,6 @@ class cmCompiledGeneratorExpression;
struct cmGeneratorExpressionDAGChecker;
class cmGeneratorTarget;
class cmMakefile;
class cmake;
enum class cmFileSetVisibility
{
@@ -41,13 +43,15 @@ bool cmFileSetTypeCanBeIncluded(std::string const& type);
class cmFileSet
{
public:
cmFileSet(cmake& cmakeInstance, std::string name, std::string type,
cmFileSet(cmMakefile* makefile, std::string name, std::string type,
cmFileSetVisibility visibility);
std::string const& GetName() const { return this->Name; }
std::string const& GetType() const { return this->Type; }
cmFileSetVisibility GetVisibility() const { return this->Visibility; }
cmMakefile* GetMakefile() const { return this->Makefile; }
void CopyEntries(cmFileSet const* fs);
void ClearDirectoryEntries();
@@ -84,11 +88,37 @@ public:
static bool IsValidName(std::string const& name);
//! Set/Get a property of this file set
void SetProperty(std::string const& prop, cmValue value);
void SetProperty(std::string const& prop, std::nullptr_t)
{
this->SetProperty(prop, cmValue{ nullptr });
}
void RemoveProperty(std::string const& prop)
{
this->SetProperty(prop, cmValue{ nullptr });
}
void SetProperty(std::string const& prop, std::string const& value)
{
this->SetProperty(prop, cmValue{ value });
}
void AppendProperty(std::string const& prop, std::string const& value,
bool asString = false);
cmValue GetProperty(std::string const& prop) const;
private:
cmake& CMakeInstance;
cmMakefile* Makefile;
std::string Name;
std::string Type;
cmFileSetVisibility Visibility;
std::vector<BT<std::string>> DirectoryEntries;
std::vector<BT<std::string>> FileEntries;
cmPropertyMap Properties;
std::vector<BT<std::string>> CompileOptions;
std::vector<BT<std::string>> CompileDefinitions;
std::vector<BT<std::string>> IncludeDirectories;
static std::string const propCOMPILE_DEFINITIONS;
static std::string const propCOMPILE_OPTIONS;
static std::string const propINCLUDE_DIRECTORIES;
};
+73 -27
View File
@@ -9,6 +9,7 @@
#include <cmext/string_view>
#include "cmExecutionStatus.h"
#include "cmFileSet.h"
#include "cmGlobalGenerator.h"
#include "cmInstalledFile.h"
#include "cmMakefile.h"
@@ -45,6 +46,9 @@ bool HandleDirectoryMode(cmExecutionStatus& status, std::string const& name,
bool HandleTargetMode(cmExecutionStatus& status, std::string const& name,
OutType infoType, std::string const& variable,
std::string const& propertyName);
bool HandleFileSetMode(cmExecutionStatus& status, std::string const& name,
OutType infoType, std::string const& variable,
std::string const& propertyName, cmTarget* target);
bool HandleSourceMode(cmExecutionStatus& status, std::string const& name,
OutType infoType, std::string const& variable,
std::string const& propertyName,
@@ -80,6 +84,9 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
std::string name;
std::string propertyName;
std::string file_set_target_name;
bool file_set_target_option_enabled = false;
std::vector<std::string> source_file_directories;
std::vector<std::string> source_file_target_directories;
bool source_file_directory_option_enabled = false;
@@ -96,6 +103,8 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
scope = cmProperty::DIRECTORY;
} else if (args[1] == "TARGET") {
scope = cmProperty::TARGET;
} else if (args[1] == "FILE_SET") {
scope = cmProperty::FILE_SET;
} else if (args[1] == "SOURCE") {
scope = cmProperty::SOURCE_FILE;
} else if (args[1] == "TEST") {
@@ -107,11 +116,11 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
} else if (args[1] == "INSTALL") {
scope = cmProperty::INSTALL;
} else {
status.SetError(cmStrCat(
"given invalid scope ", args[1],
". "
"Valid scopes are "
"GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE, CACHE, INSTALL."));
status.SetError(cmStrCat("given invalid scope ", args[1],
". "
"Valid scopes are "
"GLOBAL, DIRECTORY, TARGET, FILE_SET, SOURCE, "
"TEST, VARIABLE, CACHE, INSTALL."));
return false;
}
@@ -122,6 +131,7 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
DoingName,
DoingProperty,
DoingType,
DoingFileSetTarget,
DoingSourceDirectory,
DoingSourceTargetDirectory,
DoingTestDirectory,
@@ -145,6 +155,10 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
} else if (doing == DoingName) {
doing = DoingNone;
name = args[i];
} else if (doing == DoingNone && scope == cmProperty::FILE_SET &&
args[i] == "TARGET") {
doing = DoingFileSetTarget;
file_set_target_option_enabled = true;
} else if (doing == DoingNone && scope == cmProperty::SOURCE_FILE &&
args[i] == "DIRECTORY") {
doing = DoingSourceDirectory;
@@ -157,6 +171,9 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
args[i] == "DIRECTORY") {
doing = DoingTestDirectory;
test_directory_option_enabled = true;
} else if (doing == DoingFileSetTarget) {
file_set_target_name = args[i];
doing = DoingNone;
} else if (doing == DoingSourceDirectory) {
source_file_directories.push_back(args[i]);
doing = DoingNone;
@@ -181,21 +198,6 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
return false;
}
std::vector<cmMakefile*> source_file_directory_makefiles;
bool source_file_scopes_handled =
SetPropertyCommand::HandleAndValidateSourceFileDirectoryScopes(
status, source_file_directory_option_enabled,
source_file_target_option_enabled, source_file_directories,
source_file_target_directories, source_file_directory_makefiles);
cmMakefile* test_directory_makefile;
bool test_scopes_handled =
SetPropertyCommand::HandleAndValidateTestDirectoryScopes(
status, test_directory_option_enabled, test_directory,
test_directory_makefile);
if (!(source_file_scopes_handled && test_scopes_handled)) {
return false;
}
// Compute requested output.
if (infoType == OutBriefDoc) {
// Lookup brief documentation.
@@ -231,11 +233,6 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
}
} else {
// Dispatch property getting.
cmMakefile& directory_scope_mf = *(source_file_directory_makefiles[0]);
bool source_file_paths_should_be_absolute =
source_file_directory_option_enabled ||
source_file_target_option_enabled;
switch (scope) {
case cmProperty::GLOBAL:
return HandleGlobalMode(status, name, infoType, variable,
@@ -246,13 +243,43 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
case cmProperty::TARGET:
return HandleTargetMode(status, name, infoType, variable,
propertyName);
case cmProperty::SOURCE_FILE:
case cmProperty::FILE_SET: {
cmTarget* file_set_target;
if (!SetPropertyCommand::HandleAndValidateFileSetTargetScopes(
status, file_set_target_option_enabled, file_set_target_name,
file_set_target)) {
return false;
}
return HandleFileSetMode(status, name, infoType, variable,
propertyName, file_set_target);
}
case cmProperty::SOURCE_FILE: {
std::vector<cmMakefile*> source_file_directory_makefiles;
if (!SetPropertyCommand::HandleAndValidateSourceFileDirectoryScopes(
status, source_file_directory_option_enabled,
source_file_target_option_enabled, source_file_directories,
source_file_target_directories,
source_file_directory_makefiles)) {
return false;
}
bool source_file_paths_should_be_absolute =
source_file_directory_option_enabled ||
source_file_target_option_enabled;
cmMakefile& directory_scope_mf = *(source_file_directory_makefiles[0]);
return HandleSourceMode(status, name, infoType, variable, propertyName,
directory_scope_mf,
source_file_paths_should_be_absolute);
case cmProperty::TEST:
}
case cmProperty::TEST: {
cmMakefile* test_directory_makefile;
if (!SetPropertyCommand::HandleAndValidateTestDirectoryScopes(
status, test_directory_option_enabled, test_directory,
test_directory_makefile)) {
return false;
}
return HandleTestMode(status, name, infoType, variable, propertyName,
*test_directory_makefile);
}
case cmProperty::VARIABLE:
return HandleVariableMode(status, name, infoType, variable,
propertyName);
@@ -413,6 +440,25 @@ bool HandleTargetMode(cmExecutionStatus& status, std::string const& name,
return false;
}
bool HandleFileSetMode(cmExecutionStatus& status, std::string const& name,
OutType infoType, std::string const& variable,
std::string const& propertyName, cmTarget* target)
{
if (name.empty()) {
status.SetError("not given name for FILE_SET scope.");
return false;
}
if (cmFileSet* fileSet = target->GetFileSet(name)) {
cmValue prop = fileSet->GetProperty(propertyName);
return StoreResult(infoType, status.GetMakefile(), variable, prop);
}
status.SetError(cmStrCat("could not find FILE_SET ", name, " for TARGET ",
target->GetName(),
". Perhaps it has not yet been created."));
return false;
}
bool HandleSourceMode(cmExecutionStatus& status, std::string const& name,
OutType infoType, std::string const& variable,
std::string const& propertyName,
+2 -1
View File
@@ -17,6 +17,7 @@ public:
TEST,
VARIABLE,
CACHED_VARIABLE,
INSTALL
INSTALL,
FILE_SET
};
};
+144 -22
View File
@@ -10,6 +10,7 @@
#include <cm/string_view>
#include "cmExecutionStatus.h"
#include "cmFileSet.h"
#include "cmGlobalGenerator.h"
#include "cmInstalledFile.h"
#include "cmListFileCache.h"
@@ -48,6 +49,14 @@ bool HandleTarget(cmTarget* target, cmMakefile& makefile,
std::string const& propertyName,
std::string const& propertyValue, bool appendAsString,
bool appendMode, bool remove);
bool HandleFileSetMode(cmExecutionStatus& status,
std::set<std::string> const& names,
std::string const& propertyName,
std::string const& propertyValue, bool appendAsString,
bool appendMode, bool remove, cmTarget* target);
bool HandleFileSet(cmFileSet* fileSet, std::string const& propertyName,
std::string const& propertyValue, bool appendAsString,
bool appendMode, bool remove);
bool HandleSourceMode(cmExecutionStatus& status,
std::set<std::string> const& names,
std::string const& propertyName,
@@ -87,6 +96,54 @@ bool HandleInstall(cmInstalledFile* file, cmMakefile& makefile,
}
namespace SetPropertyCommand {
bool HandleFileSetTargetScopes(cmExecutionStatus& status,
std::string& file_set_target_name,
cmTarget*& file_set_target)
{
file_set_target = status.GetMakefile().FindTargetToUse(file_set_target_name);
if (!file_set_target) {
status.SetError(
cmStrCat("given non-existent TARGET ", file_set_target_name));
return false;
}
return true;
}
bool HandleFileSetTargetScopeValidation(cmExecutionStatus& status,
bool file_set_target_option_enabled,
std::string& file_set_target_name)
{
if (!file_set_target_option_enabled) {
status.SetError("required TARGET option is missing");
return false;
}
// Validate file set target scopes.
if (file_set_target_name.empty()) {
status.SetError("called with incorrect number of arguments "
"no value provided to the TARGET option");
return false;
}
return true;
}
bool HandleAndValidateFileSetTargetScopes(cmExecutionStatus& status,
bool file_set_target_option_enabled,
std::string& file_set_target_name,
cmTarget*& file_set_target)
{
bool scope_options_valid =
SetPropertyCommand::HandleFileSetTargetScopeValidation(
status, file_set_target_option_enabled, file_set_target_name);
if (!scope_options_valid) {
return false;
}
scope_options_valid = SetPropertyCommand::HandleFileSetTargetScopes(
status, file_set_target_name, file_set_target);
return scope_options_valid;
}
bool HandleSourceFileDirectoryScopes(
cmExecutionStatus& status, std::vector<std::string>& source_file_directories,
std::vector<std::string>& source_file_target_directories,
@@ -402,6 +459,8 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
scope = cmProperty::DIRECTORY;
} else if (scopeName == "TARGET") {
scope = cmProperty::TARGET;
} else if (scopeName == "FILE_SET") {
scope = cmProperty::FILE_SET;
} else if (scopeName == "SOURCE") {
scope = cmProperty::SOURCE_FILE;
} else if (scopeName == "TEST") {
@@ -412,9 +471,8 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
scope = cmProperty::INSTALL;
} else {
status.SetError(cmStrCat("given invalid scope ", scopeName,
". "
"Valid scopes are GLOBAL, DIRECTORY, "
"TARGET, SOURCE, TEST, CACHE, INSTALL."));
". Valid scopes are GLOBAL, DIRECTORY, TARGET, "
"FILE_SET, SOURCE, TEST, CACHE, INSTALL."));
return false;
}
@@ -425,6 +483,9 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
std::string propertyName;
std::string propertyValue;
std::string file_set_target_name;
bool file_set_target_option_enabled = false;
std::vector<std::string> source_file_directories;
std::vector<std::string> source_file_target_directories;
bool source_file_directory_option_enabled = false;
@@ -440,6 +501,7 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
DoingNames,
DoingProperty,
DoingValues,
DoingFileSetTarget,
DoingSourceDirectory,
DoingSourceTargetDirectory,
DoingTestDirectory,
@@ -459,6 +521,10 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
appendMode = true;
remove = false;
appendAsString = true;
} else if (doing != DoingProperty && doing != DoingValues &&
scope == cmProperty::FILE_SET && arg == "TARGET") {
doing = DoingFileSetTarget;
file_set_target_option_enabled = true;
} else if (doing != DoingProperty && doing != DoingValues &&
scope == cmProperty::SOURCE_FILE && arg == "DIRECTORY") {
doing = DoingSourceDirectory;
@@ -473,6 +539,10 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
test_directory_option_enabled = true;
} else if (doing == DoingNames) {
names.insert(arg);
} else if (doing == DoingFileSetTarget) {
file_set_target_name = arg;
file_set_target_option_enabled = true;
doing = DoingNone;
} else if (doing == DoingSourceDirectory) {
source_file_directories.push_back(arg);
} else if (doing == DoingSourceTargetDirectory) {
@@ -500,23 +570,6 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
return false;
}
std::vector<cmMakefile*> source_file_directory_makefiles;
bool source_file_scopes_handled =
SetPropertyCommand::HandleAndValidateSourceFileDirectoryScopes(
status, source_file_directory_option_enabled,
source_file_target_option_enabled, source_file_directories,
source_file_target_directories, source_file_directory_makefiles);
cmMakefile* test_directory_makefile;
bool test_scopes_handled =
SetPropertyCommand::HandleAndValidateTestDirectoryScopes(
status, test_directory_option_enabled, test_directory,
test_directory_makefile);
if (!(source_file_scopes_handled && test_scopes_handled)) {
return false;
}
bool source_file_paths_should_be_absolute =
source_file_directory_option_enabled || source_file_target_option_enabled;
// Dispatch property setting.
switch (scope) {
case cmProperty::GLOBAL:
@@ -528,15 +581,44 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
case cmProperty::TARGET:
return HandleTargetMode(status, names, propertyName, propertyValue,
appendAsString, appendMode, remove);
case cmProperty::SOURCE_FILE:
case cmProperty::FILE_SET: {
cmTarget* file_set_target;
if (!SetPropertyCommand::HandleAndValidateFileSetTargetScopes(
status, file_set_target_option_enabled, file_set_target_name,
file_set_target)) {
return false;
}
return HandleFileSetMode(status, names, propertyName, propertyValue,
appendAsString, appendMode, remove,
file_set_target);
}
case cmProperty::SOURCE_FILE: {
std::vector<cmMakefile*> source_file_directory_makefiles;
if (!SetPropertyCommand::HandleAndValidateSourceFileDirectoryScopes(
status, source_file_directory_option_enabled,
source_file_target_option_enabled, source_file_directories,
source_file_target_directories, source_file_directory_makefiles)) {
return false;
}
bool source_file_paths_should_be_absolute =
source_file_directory_option_enabled ||
source_file_target_option_enabled;
return HandleSourceMode(status, names, propertyName, propertyValue,
appendAsString, appendMode, remove,
source_file_directory_makefiles,
source_file_paths_should_be_absolute);
case cmProperty::TEST:
}
case cmProperty::TEST: {
cmMakefile* test_directory_makefile;
if (!SetPropertyCommand::HandleAndValidateTestDirectoryScopes(
status, test_directory_option_enabled, test_directory,
test_directory_makefile)) {
return false;
}
return HandleTestMode(status, names, propertyName, propertyValue,
appendAsString, appendMode, remove,
test_directory_makefile);
}
case cmProperty::CACHE:
return HandleCacheMode(status, names, propertyName, propertyValue,
appendAsString, appendMode, remove);
@@ -679,6 +761,46 @@ bool HandleTarget(cmTarget* target, cmMakefile& makefile,
return true;
}
bool HandleFileSetMode(cmExecutionStatus& status,
std::set<std::string> const& names,
std::string const& propertyName,
std::string const& propertyValue, bool appendAsString,
bool appendMode, bool remove, cmTarget* target)
{
for (std::string const& name : names) {
if (cmFileSet* fileSet = target->GetFileSet(name)) {
// Handle the current file set.
if (!HandleFileSet(fileSet, propertyName, propertyValue, appendAsString,
appendMode, remove)) {
return false;
}
} else {
status.SetError(cmStrCat("could not find FILE_SET ", name,
" for TARGET ", target->GetName(),
". Perhaps it has not yet been created."));
return false;
}
}
return true;
}
bool HandleFileSet(cmFileSet* fileSet, std::string const& propertyName,
std::string const& propertyValue, bool appendAsString,
bool appendMode, bool remove)
{
// Set or append the property.
if (appendMode) {
fileSet->AppendProperty(propertyName, propertyValue, appendAsString);
} else {
if (remove) {
fileSet->SetProperty(propertyName, nullptr);
} else {
fileSet->SetProperty(propertyName, propertyValue);
}
}
return true;
}
bool HandleSourceMode(cmExecutionStatus& status,
std::set<std::string> const& names,
std::string const& propertyName,
+14
View File
@@ -10,11 +10,25 @@
class cmMakefile;
class cmExecutionStatus;
class cmSourceFile;
class cmTarget;
bool cmSetPropertyCommand(std::vector<std::string> const& args,
cmExecutionStatus& status);
namespace SetPropertyCommand {
bool HandleFileSetTargetScopes(cmExecutionStatus& status,
std::string& file_set_target_name,
cmTarget*& file_set_target);
bool HandleFileSetTargetScopeValidation(cmExecutionStatus& status,
bool file_set_target_option_enabled,
std::string& file_set_target_name);
bool HandleAndValidateFileSetTargetScopes(cmExecutionStatus& status,
bool file_set_target_option_enabled,
std::string& file_set_target_name,
cmTarget*& file_set_target);
bool HandleSourceFileDirectoryScopes(
cmExecutionStatus& status, std::vector<std::string>& source_file_directories,
std::vector<std::string>& source_file_target_directories,
+1 -2
View File
@@ -3138,8 +3138,7 @@ std::pair<cmFileSet*, bool> cmTarget::GetOrCreateFileSet(
std::string const& name, std::string const& type, cmFileSetVisibility vis)
{
auto result = this->impl->FileSets.emplace(
name,
cmFileSet(*this->GetMakefile()->GetCMakeInstance(), name, type, vis));
name, cmFileSet(this->GetMakefile(), name, type, vis));
if (result.second) {
auto bt = this->impl->Makefile->GetBacktrace();
if (type == this->impl->HeadersFileSets.TypeName) {
@@ -499,9 +499,10 @@ static bool testCreateFromFileSet()
{
auto variablesManager =
std::make_shared<cmDebugger::cmDebuggerVariablesManager>();
auto dummies = CreateDummies("Foo");
cmake cm(cmState::Role::Internal);
cmFileSet fileSet(cm, "Foo", "HEADERS", cmFileSetVisibility::Public);
cmFileSet fileSet(dummies.Makefile.get(), "Foo", "HEADERS",
cmFileSetVisibility::Public);
BT<std::string> directory;
directory.Value = "c:/";
fileSet.AddDirectoryEntry(directory);
@@ -543,9 +544,10 @@ static bool testCreateFromFileSets()
{
auto variablesManager =
std::make_shared<cmDebugger::cmDebuggerVariablesManager>();
auto dummies = CreateDummies("Foo");
cmake cm(cmState::Role::Internal);
cmFileSet fileSet(cm, "Foo", "HEADERS", cmFileSetVisibility::Public);
cmFileSet fileSet(dummies.Makefile.get(), "Foo", "HEADERS",
cmFileSetVisibility::Public);
BT<std::string> directory;
directory.Value = "c:/";
fileSet.AddDirectoryEntry(directory);
@@ -0,0 +1 @@
1
@@ -0,0 +1,5 @@
CMake Error at BadFileSet\.cmake:[0-9]+ \(get_property\):
get_property could not find FILE_SET FOO for TARGET FOO\. Perhaps it has
not yet been created.
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)
@@ -0,0 +1,3 @@
add_library(FOO INTERFACE)
get_property(FOO FILE_SET FOO TARGET FOO PROPERTY FOO)
@@ -0,0 +1 @@
1
@@ -0,0 +1,4 @@
CMake Error at BadFileSetTarget\.cmake:[0-9]+ \(get_property\):
get_property given non-existent TARGET FOO
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)
@@ -0,0 +1 @@
get_property(FOO FILE_SET FOO TARGET FOO PROPERTY FOO)
@@ -1,5 +1,5 @@
^CMake Error at BadScope\.cmake:1 \(get_property\):
get_property given invalid scope FOO\. Valid scopes are GLOBAL, DIRECTORY,
TARGET, SOURCE, TEST, VARIABLE, CACHE, INSTALL\.
TARGET, FILE_SET, SOURCE, TEST, VARIABLE, CACHE, INSTALL\.
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)$
@@ -26,6 +26,8 @@ run_cmake(NoTarget)
run_cmake(NoSource)
run_cmake(NoProperty)
run_cmake(NoCache)
run_cmake(BadFileSet)
run_cmake(BadFileSetTarget)
# Since we are testing the GENERATOR_IS_MULTI_CONFIG property itself,
# don't rely on RunCMake_GENERATOR_IS_MULTI_CONFIG being set correctly
@@ -1,2 +1,3 @@
-- Target COMPILE_DEFINITIONS is 'a;b;c;d;;e'
-- Directory COMPILE_DEFINITIONS is 'a;b;c;d;;e'
-- FileSet COMPILE_DEFINITIONS is 'a;b;c;d;;e'
@@ -1,3 +1,4 @@
include(Common.cmake)
test_target_property(COMPILE_DEFINITIONS)
test_directory_property(COMPILE_DEFINITIONS)
test_file_set_property(COMPILE_DEFINITIONS)
@@ -1,2 +1,3 @@
-- Target COMPILE_OPTIONS is 'a;b;c;d;;e'
-- Directory COMPILE_OPTIONS is 'a;b;c;d;;e'
-- FileSet COMPILE_OPTIONS is 'a;b;c;d;;e'
@@ -1,3 +1,4 @@
include(Common.cmake)
test_target_property(COMPILE_OPTIONS)
test_directory_property(COMPILE_OPTIONS)
test_file_set_property(COMPILE_OPTIONS)
+16
View File
@@ -26,3 +26,19 @@ macro(test_directory_property PROP)
message(STATUS "Directory ${PROP} is '${val}'")
set_property(DIRECTORY PROPERTY ${PROP})
endmacro()
macro(test_file_set_property PROP)
add_library(foo INTERFACE)
target_sources(foo INTERFACE FILE_SET foo TYPE HEADERS)
set_property(FILE_SET foo TARGET foo PROPERTY ${PROP} x)
set_property(FILE_SET foo TARGET foo PROPERTY ${PROP})
set_property(FILE_SET foo TARGET foo APPEND PROPERTY ${PROP})
set_property(FILE_SET foo TARGET foo PROPERTY ${PROP} a)
set_property(FILE_SET foo TARGET foo APPEND PROPERTY ${PROP} "")
set_property(FILE_SET foo TARGET foo APPEND PROPERTY ${PROP} b c)
set_property(FILE_SET foo TARGET foo APPEND PROPERTY ${PROP})
set_property(FILE_SET foo TARGET foo APPEND PROPERTY ${PROP} "d;;e")
get_property(val FILE_SET foo TARGET foo PROPERTY ${PROP})
message(STATUS "FileSet ${PROP} is '${val}'")
set_property(FILE_SET foo TARGET foo PROPERTY ${PROP})
endmacro()
@@ -0,0 +1 @@
1
@@ -0,0 +1,10 @@
CMake Error at FILE_SET-PROPERTY-missing\.cmake:5 \(set_property\):
set_property not given a PROPERTY <name> argument\.
Call Stack \(most recent call first\):
CMakeLists\.txt:3 \(include\)
CMake Error at FILE_SET-PROPERTY-missing\.cmake:7 \(set_property\):
set_property not given a PROPERTY <name> argument\.
Call Stack \(most recent call first\):
CMakeLists\.txt:3 \(include\)
@@ -0,0 +1,7 @@
add_library(foo INTERFACE)
target_sources(foo INTERFACE FILE_SET foo TYPE HEADERS)
set_property(FILE_SET foo TARGET foo)
set_property(FILE_SET foo TARGET foo PROPERTY)
@@ -0,0 +1 @@
1
@@ -0,0 +1,4 @@
CMake Error at FILE_SET-TARGET-invalid\.cmake:[0-9]+ \(set_property\):
set_property given non-existent TARGET foo
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)
@@ -0,0 +1,2 @@
set_property(FILE_SET foo TARGET foo PROPERTY PROP VALUE)
@@ -0,0 +1 @@
1
@@ -0,0 +1,5 @@
CMake Error at FILE_SET-invalid\.cmake:[0-9]+ \(set_property\):
set_property could not find FILE_SET foo for TARGET foo\. Perhaps it has
not yet been created.
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)
@@ -0,0 +1,4 @@
add_library(foo SHARED)
set_property(FILE_SET foo TARGET foo PROPERTY PROP VALUE)
@@ -0,0 +1,30 @@
add_library(foo INTERFACE)
target_sources(foo INTERFACE FILE_SET foo1 TYPE HEADERS)
target_sources(foo INTERFACE FILE_SET foo2 TYPE HEADERS)
# check various supported syntax
set_property(FILE_SET TARGET foo PROPERTY FOO)
set_property(FILE_SET TARGET foo PROPERTY FOO BAR)
set_property(FILE_SET TARGET foo PROPERTY FOO BAR BAR2)
set_property(FILE_SET foo1 TARGET foo PROPERTY FOO)
set_property(FILE_SET foo1 TARGET foo PROPERTY FOO BAR)
set_property(FILE_SET foo1 TARGET foo PROPERTY FOO BAR BAR2)
get_property(value FILE_SET foo1 TARGET foo PROPERTY FOO)
if(NOT value STREQUAL "BAR;BAR2")
message(SEND_ERROR "FILE_SET foo1 TARGET foo: \"${value}\", expected \"BAR;BAR2\"")
endif()
set_property(FILE_SET foo1 foo2 TARGET foo PROPERTY FOO)
set_property(FILE_SET foo1 foo2 TARGET foo PROPERTY FOO BAR)
set_property(FILE_SET foo1 foo2 TARGET foo PROPERTY FOO BAR BAR2)
get_property(value FILE_SET foo1 TARGET foo PROPERTY FOO)
if(NOT value STREQUAL "BAR;BAR2")
message(SEND_ERROR "FILE_SET foo1 TARGET foo: \"${value}\", expected \"BAR;BAR2\"")
endif()
get_property(value FILE_SET foo2 TARGET foo PROPERTY FOO)
if(NOT value STREQUAL "BAR;BAR2")
message(SEND_ERROR "FILE_SET foo2 TARGET foo: \"${value}\", expected \"BAR;BAR2\"")
endif()
@@ -1,2 +1,3 @@
-- Target INCLUDE_DIRECTORIES is 'a;b;c;d;;e'
-- Directory INCLUDE_DIRECTORIES is 'a;b;c;d;;e'
-- FileSet INCLUDE_DIRECTORIES is 'a;b;c;d;;e'
@@ -1,3 +1,4 @@
include(Common.cmake)
test_target_property(INCLUDE_DIRECTORIES)
test_directory_property(INCLUDE_DIRECTORIES)
test_file_set_property(INCLUDE_DIRECTORIES)
@@ -19,3 +19,8 @@ set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/TEST-build")
run_cmake(TEST)
set(RunCMake_TEST_NO_CLEAN 1)
run_cmake_command(TEST-test ${CMAKE_CTEST_COMMAND} -C Debug)
run_cmake(FILE_SET-invalid)
run_cmake(FILE_SET-TARGET-invalid)
run_cmake(FILE_SET-PROPERTY-missing)
run_cmake(FILE_SET)
@@ -1,2 +1,3 @@
-- Target USER_PROP is 'a;b;c;d;;e'
-- Directory USER_PROP is 'a;b;c;d;;e'
-- FileSet USER_PROP is 'a;b;c;d;;e'
@@ -1,3 +1,4 @@
include(Common.cmake)
test_target_property(USER_PROP)
test_directory_property(USER_PROP)
test_file_set_property(USER_PROP)