1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmSetPropertyCommand.cxx,v $
6 <<<<<<< cmSetPropertyCommand.cxx
7 Date: $Date: 2008/02/15 16:22:23 $
8 Version: $Revision: 1.6 $
10 Date: $Date: 2008-04-01 18:22:06 $
11 Version: $Revision: 1.7 $
14 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
15 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
17 This software is distributed WITHOUT ANY WARRANTY; without even
18 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
19 PURPOSE. See the above copyright notices for more information.
21 =========================================================================*/
22 #include "cmSetPropertyCommand.h"
23 #include "cmSetTargetPropertiesCommand.h"
24 #include "cmSetTestsPropertiesCommand.h"
25 #include "cmSetSourceFilesPropertiesCommand.h"
27 //----------------------------------------------------------------------------
28 cmSetPropertyCommand::cmSetPropertyCommand()
30 this->AppendMode
= false;
34 //----------------------------------------------------------------------------
35 bool cmSetPropertyCommand
36 ::InitialPass(std::vector
<std::string
> const& args
, cmExecutionStatus
&)
40 this->SetError("called with incorrect number of arguments");
44 // Get the scope on which to set the property.
45 std::vector
<std::string
>::const_iterator arg
= args
.begin();
46 cmProperty::ScopeType scope
;
49 scope
= cmProperty::GLOBAL
;
51 else if(*arg
== "DIRECTORY")
53 scope
= cmProperty::DIRECTORY
;
55 else if(*arg
== "TARGET")
57 scope
= cmProperty::TARGET
;
59 else if(*arg
== "SOURCE")
61 scope
= cmProperty::SOURCE_FILE
;
63 else if(*arg
== "TEST")
65 scope
= cmProperty::TEST
;
70 e
<< "given invalid scope " << *arg
<< ". "
71 << "Valid scopes are GLOBAL, DIRECTORY, TARGET, SOURCE, TEST.";
72 this->SetError(e
.str().c_str());
76 // Parse the rest of the arguments up to the values.
77 enum Doing
{ DoingNone
, DoingNames
, DoingProperty
, DoingValues
};
78 Doing doing
= DoingNames
;
80 for(++arg
; arg
!= args
.end(); ++arg
)
82 if(*arg
== "PROPERTY")
84 doing
= DoingProperty
;
86 else if(*arg
== "APPEND")
89 this->AppendMode
= true;
91 else if(doing
== DoingNames
)
93 this->Names
.insert(*arg
);
95 else if(doing
== DoingProperty
)
97 this->PropertyName
= *arg
;
100 else if(doing
== DoingValues
)
102 this->PropertyValue
+= sep
;
104 this->PropertyValue
+= *arg
;
105 this->Remove
= false;
110 e
<< "given invalid argument \"" << *arg
<< "\".";
111 this->SetError(e
.str().c_str());
116 // Make sure a property name was found.
117 if(this->PropertyName
.empty())
119 this->SetError("not given a PROPERTY <name> argument.");
123 // Dispatch property setting.
126 case cmProperty::GLOBAL
: return this->HandleGlobalMode();
127 case cmProperty::DIRECTORY
: return this->HandleDirectoryMode();
128 case cmProperty::TARGET
: return this->HandleTargetMode();
129 case cmProperty::SOURCE_FILE
: return this->HandleSourceMode();
130 case cmProperty::TEST
: return this->HandleTestMode();
132 case cmProperty::VARIABLE
:
133 case cmProperty::CACHED_VARIABLE
:
134 break; // should never happen
139 //----------------------------------------------------------------------------
140 bool cmSetPropertyCommand::HandleGlobalMode()
142 if(!this->Names
.empty())
144 this->SetError("given names for GLOBAL scope.");
148 // Set or append the property.
149 cmake
* cm
= this->Makefile
->GetCMakeInstance();
150 const char* name
= this->PropertyName
.c_str();
151 const char *value
= this->PropertyValue
.c_str();
158 cm
->AppendProperty(name
, value
);
162 cm
->SetProperty(name
, value
);
168 //----------------------------------------------------------------------------
169 bool cmSetPropertyCommand::HandleDirectoryMode()
171 if(this->Names
.size() > 1)
173 this->SetError("allows at most one name for DIRECTORY scope.");
177 // Default to the current directory.
178 cmMakefile
* mf
= this->Makefile
;
180 // Lookup the directory if given.
181 if(!this->Names
.empty())
183 // Construct the directory name. Interpret relative paths with
184 // respect to the current directory.
185 std::string dir
= *this->Names
.begin();
186 if(!cmSystemTools::FileIsFullPath(dir
.c_str()))
188 dir
= this->Makefile
->GetCurrentDirectory();
190 dir
+= *this->Names
.begin();
193 // The local generators are associated with collapsed paths.
194 dir
= cmSystemTools::CollapseFullPath(dir
.c_str());
196 // Lookup the generator.
197 if(cmLocalGenerator
* lg
=
198 (this->Makefile
->GetLocalGenerator()
199 ->GetGlobalGenerator()->FindLocalGenerator(dir
.c_str())))
201 // Use the makefile for the directory found.
202 mf
= lg
->GetMakefile();
206 // Could not find the directory.
208 ("DIRECTORY scope provided but requested directory was not found. "
209 "This could be because the directory argument was invalid or, "
210 "it is valid but has not been processed yet.");
215 // Set or append the property.
216 const char* name
= this->PropertyName
.c_str();
217 const char *value
= this->PropertyValue
.c_str();
224 mf
->AppendProperty(name
, value
);
228 mf
->SetProperty(name
, value
);
234 //----------------------------------------------------------------------------
235 bool cmSetPropertyCommand::HandleTargetMode()
237 for(std::set
<cmStdString
>::const_iterator ni
= this->Names
.begin();
238 ni
!= this->Names
.end(); ++ni
)
240 if(cmTarget
* target
= this->Makefile
->FindTargetToUse(ni
->c_str()))
242 // Handle the current target.
243 if(!this->HandleTarget(target
))
251 e
<< "could not find TARGET " << *ni
252 << ". Perhaps it has not yet been created.";
253 this->SetError(e
.str().c_str());
260 //----------------------------------------------------------------------------
261 bool cmSetPropertyCommand::HandleTarget(cmTarget
* target
)
263 // Set or append the property.
264 const char* name
= this->PropertyName
.c_str();
265 const char *value
= this->PropertyValue
.c_str();
272 target
->AppendProperty(name
, value
);
276 target
->SetProperty(name
, value
);
282 //----------------------------------------------------------------------------
283 bool cmSetPropertyCommand::HandleSourceMode()
285 for(std::set
<cmStdString
>::const_iterator ni
= this->Names
.begin();
286 ni
!= this->Names
.end(); ++ni
)
288 // Get the source file.
289 if(cmSourceFile
* sf
= this->Makefile
->GetOrCreateSource(ni
->c_str()))
291 if(!this->HandleSource(sf
))
299 e
<< "given SOURCE name that could not be found or created: " << *ni
;
300 this->SetError(e
.str().c_str());
307 //----------------------------------------------------------------------------
308 bool cmSetPropertyCommand::HandleSource(cmSourceFile
* sf
)
310 // Set or append the property.
311 const char* name
= this->PropertyName
.c_str();
312 const char *value
= this->PropertyValue
.c_str();
320 sf
->AppendProperty(name
, value
);
324 sf
->SetProperty(name
, value
);
329 //----------------------------------------------------------------------------
330 bool cmSetPropertyCommand::HandleTestMode()
332 // Loop over all tests looking for matching names.
333 std::vector
<cmTest
*> const& tests
= *this->Makefile
->GetTests();
334 for(std::vector
<cmTest
*>::const_iterator ti
= tests
.begin();
335 ti
!= tests
.end(); ++ti
)
338 std::set
<cmStdString
>::iterator ni
=
339 this->Names
.find(test
->GetName());
340 if(ni
!= this->Names
.end())
342 if(this->HandleTest(test
))
344 this->Names
.erase(ni
);
353 // Names that are still left were not found.
354 if(!this->Names
.empty())
357 e
<< "given TEST names that do not exist:\n";
358 for(std::set
<cmStdString
>::const_iterator ni
= this->Names
.begin();
359 ni
!= this->Names
.end(); ++ni
)
361 e
<< " " << *ni
<< "\n";
363 this->SetError(e
.str().c_str());
369 //----------------------------------------------------------------------------
370 bool cmSetPropertyCommand::HandleTest(cmTest
* test
)
372 // Set or append the property.
373 const char* name
= this->PropertyName
.c_str();
374 const char *value
= this->PropertyValue
.c_str();
381 test
->AppendProperty(name
, value
);
385 test
->SetProperty(name
, value
);