1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
3 #include "cmTargetPropCommandBase.h"
5 #include "cmExecutionStatus.h"
6 #include "cmGlobalGenerator.h"
7 #include "cmMakefile.h"
8 #include "cmStateTypes.h"
12 cmTargetPropCommandBase::cmTargetPropCommandBase(cmExecutionStatus
& status
)
13 : Makefile(&status
.GetMakefile())
18 void cmTargetPropCommandBase::SetError(std::string
const& e
)
20 this->Status
.SetError(e
);
23 bool cmTargetPropCommandBase::HandleArguments(
24 std::vector
<std::string
> const& args
, const std::string
& prop
,
27 if (args
.size() < 2) {
28 this->SetError("called with incorrect number of arguments");
32 if (this->Makefile
->IsAlias(args
[0])) {
33 this->SetError("can not be used on an ALIAS target.");
36 // Lookup the target for which property-values are specified.
37 this->Target
= this->Makefile
->GetGlobalGenerator()->FindTarget(args
[0]);
39 this->Target
= this->Makefile
->FindTargetToUse(args
[0]);
42 this->HandleMissingTarget(args
[0]);
45 const bool isRegularTarget
=
46 (this->Target
->GetType() == cmStateEnums::EXECUTABLE
) ||
47 (this->Target
->GetType() == cmStateEnums::STATIC_LIBRARY
) ||
48 (this->Target
->GetType() == cmStateEnums::SHARED_LIBRARY
) ||
49 (this->Target
->GetType() == cmStateEnums::MODULE_LIBRARY
) ||
50 (this->Target
->GetType() == cmStateEnums::OBJECT_LIBRARY
) ||
51 (this->Target
->GetType() == cmStateEnums::INTERFACE_LIBRARY
) ||
52 (this->Target
->GetType() == cmStateEnums::UNKNOWN_LIBRARY
);
53 const bool isCustomTarget
= this->Target
->GetType() == cmStateEnums::UTILITY
;
55 if (prop
== "SOURCES") {
56 if (!isRegularTarget
&& !isCustomTarget
) {
57 this->SetError("called with non-compilable target type");
61 if (!isRegularTarget
) {
62 this->SetError("called with non-compilable target type");
68 unsigned int argIndex
= 1;
70 if ((flags
& PROCESS_SYSTEM
) && args
[argIndex
] == "SYSTEM") {
71 if (args
.size() < 3) {
72 this->SetError("called with incorrect number of arguments");
80 if ((flags
& PROCESS_BEFORE
) && args
[argIndex
] == "BEFORE") {
81 if (args
.size() < 3) {
82 this->SetError("called with incorrect number of arguments");
87 } else if ((flags
& PROCESS_AFTER
) && args
[argIndex
] == "AFTER") {
88 if (args
.size() < 3) {
89 this->SetError("called with incorrect number of arguments");
96 if ((flags
& PROCESS_REUSE_FROM
) && args
[argIndex
] == "REUSE_FROM") {
97 if (args
.size() != 3) {
98 this->SetError("called with incorrect number of arguments");
103 this->Target
->SetProperty("PRECOMPILE_HEADERS_REUSE_FROM", args
[argIndex
]);
107 this->Property
= prop
;
109 while (argIndex
< args
.size()) {
110 if (!this->ProcessContentArgs(args
, argIndex
, prepend
, system
)) {
117 bool cmTargetPropCommandBase::ProcessContentArgs(
118 std::vector
<std::string
> const& args
, unsigned int& argIndex
, bool prepend
,
121 std::string
const& scope
= args
[argIndex
];
123 if (scope
!= "PUBLIC" && scope
!= "PRIVATE" && scope
!= "INTERFACE") {
124 this->SetError("called with invalid arguments");
130 std::vector
<std::string
> content
;
132 for (unsigned int i
= argIndex
; i
< args
.size(); ++i
, ++argIndex
) {
133 if (args
[i
] == "PUBLIC" || args
[i
] == "PRIVATE" ||
134 args
[i
] == "INTERFACE") {
137 content
.push_back(args
[i
]);
139 if (!content
.empty()) {
140 if (this->Target
->GetType() == cmStateEnums::INTERFACE_LIBRARY
&&
141 scope
!= "INTERFACE" && this->Property
!= "SOURCES") {
142 this->SetError("may only set INTERFACE properties on INTERFACE targets");
145 if (this->Target
->IsImported() && scope
!= "INTERFACE") {
146 this->SetError("may only set INTERFACE properties on IMPORTED targets");
149 if (this->Target
->GetType() == cmStateEnums::UTILITY
&&
150 scope
!= "PRIVATE") {
151 this->SetError("may only set PRIVATE properties on custom targets");
155 return this->PopulateTargetProperties(scope
, content
, prepend
, system
);
158 bool cmTargetPropCommandBase::PopulateTargetProperties(
159 const std::string
& scope
, const std::vector
<std::string
>& content
,
160 bool prepend
, bool system
)
162 if (content
.empty()) {
165 if (scope
== "PRIVATE" || scope
== "PUBLIC") {
166 if (!this->HandleDirectContent(this->Target
, content
, prepend
, system
)) {
170 if (scope
== "INTERFACE" || scope
== "PUBLIC") {
171 this->HandleInterfaceContent(this->Target
, content
, prepend
, system
);
176 void cmTargetPropCommandBase::HandleInterfaceContent(
177 cmTarget
* tgt
, const std::vector
<std::string
>& content
, bool prepend
, bool)
180 const std::string propName
= std::string("INTERFACE_") + this->Property
;
181 cmValue propValue
= tgt
->GetProperty(propName
);
182 const std::string totalContent
=
183 this->Join(content
) + (propValue
? (";" + *propValue
) : std::string());
184 tgt
->SetProperty(propName
, totalContent
);
186 tgt
->AppendProperty("INTERFACE_" + this->Property
, this->Join(content
));