cmGetPropertyCommand.cxx 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmGetPropertyCommand.h"
  11. #include "cmGlobalGenerator.h"
  12. #include "cmPropertyDefinition.h"
  13. #include "cmSourceFile.h"
  14. #include "cmState.h"
  15. #include "cmTest.h"
  16. #include "cmake.h"
  17. cmGetPropertyCommand::cmGetPropertyCommand()
  18. {
  19. this->InfoType = OutValue;
  20. }
  21. bool cmGetPropertyCommand::InitialPass(std::vector<std::string> const& args,
  22. cmExecutionStatus&)
  23. {
  24. if (args.size() < 3) {
  25. this->SetError("called with incorrect number of arguments");
  26. return false;
  27. }
  28. // The cmake variable in which to store the result.
  29. this->Variable = args[0];
  30. // Get the scope from which to get the property.
  31. cmProperty::ScopeType scope;
  32. if (args[1] == "GLOBAL") {
  33. scope = cmProperty::GLOBAL;
  34. } else if (args[1] == "DIRECTORY") {
  35. scope = cmProperty::DIRECTORY;
  36. } else if (args[1] == "TARGET") {
  37. scope = cmProperty::TARGET;
  38. } else if (args[1] == "SOURCE") {
  39. scope = cmProperty::SOURCE_FILE;
  40. } else if (args[1] == "TEST") {
  41. scope = cmProperty::TEST;
  42. } else if (args[1] == "VARIABLE") {
  43. scope = cmProperty::VARIABLE;
  44. } else if (args[1] == "CACHE") {
  45. scope = cmProperty::CACHE;
  46. } else if (args[1] == "INSTALL") {
  47. scope = cmProperty::INSTALL;
  48. } else {
  49. std::ostringstream e;
  50. e << "given invalid scope " << args[1] << ". "
  51. << "Valid scopes are "
  52. << "GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE, CACHE, INSTALL.";
  53. this->SetError(e.str());
  54. return false;
  55. }
  56. // Parse remaining arguments.
  57. enum Doing
  58. {
  59. DoingNone,
  60. DoingName,
  61. DoingProperty,
  62. DoingType
  63. };
  64. Doing doing = DoingName;
  65. for (unsigned int i = 2; i < args.size(); ++i) {
  66. if (args[i] == "PROPERTY") {
  67. doing = DoingProperty;
  68. } else if (args[i] == "BRIEF_DOCS") {
  69. doing = DoingNone;
  70. this->InfoType = OutBriefDoc;
  71. } else if (args[i] == "FULL_DOCS") {
  72. doing = DoingNone;
  73. this->InfoType = OutFullDoc;
  74. } else if (args[i] == "SET") {
  75. doing = DoingNone;
  76. this->InfoType = OutSet;
  77. } else if (args[i] == "DEFINED") {
  78. doing = DoingNone;
  79. this->InfoType = OutDefined;
  80. } else if (doing == DoingName) {
  81. doing = DoingNone;
  82. this->Name = args[i];
  83. } else if (doing == DoingProperty) {
  84. doing = DoingNone;
  85. this->PropertyName = args[i];
  86. } else {
  87. std::ostringstream e;
  88. e << "given invalid argument \"" << args[i] << "\".";
  89. this->SetError(e.str());
  90. return false;
  91. }
  92. }
  93. // Make sure a property name was found.
  94. if (this->PropertyName.empty()) {
  95. this->SetError("not given a PROPERTY <name> argument.");
  96. return false;
  97. }
  98. // Compute requested output.
  99. if (this->InfoType == OutBriefDoc) {
  100. // Lookup brief documentation.
  101. std::string output;
  102. if (cmPropertyDefinition const* def =
  103. this->Makefile->GetState()->GetPropertyDefinition(this->PropertyName,
  104. scope)) {
  105. output = def->GetShortDescription();
  106. } else {
  107. output = "NOTFOUND";
  108. }
  109. this->Makefile->AddDefinition(this->Variable, output.c_str());
  110. } else if (this->InfoType == OutFullDoc) {
  111. // Lookup full documentation.
  112. std::string output;
  113. if (cmPropertyDefinition const* def =
  114. this->Makefile->GetState()->GetPropertyDefinition(this->PropertyName,
  115. scope)) {
  116. output = def->GetFullDescription();
  117. } else {
  118. output = "NOTFOUND";
  119. }
  120. this->Makefile->AddDefinition(this->Variable, output.c_str());
  121. } else if (this->InfoType == OutDefined) {
  122. // Lookup if the property is defined
  123. if (this->Makefile->GetState()->GetPropertyDefinition(this->PropertyName,
  124. scope)) {
  125. this->Makefile->AddDefinition(this->Variable, "1");
  126. } else {
  127. this->Makefile->AddDefinition(this->Variable, "0");
  128. }
  129. } else {
  130. // Dispatch property getting.
  131. switch (scope) {
  132. case cmProperty::GLOBAL:
  133. return this->HandleGlobalMode();
  134. case cmProperty::DIRECTORY:
  135. return this->HandleDirectoryMode();
  136. case cmProperty::TARGET:
  137. return this->HandleTargetMode();
  138. case cmProperty::SOURCE_FILE:
  139. return this->HandleSourceMode();
  140. case cmProperty::TEST:
  141. return this->HandleTestMode();
  142. case cmProperty::VARIABLE:
  143. return this->HandleVariableMode();
  144. case cmProperty::CACHE:
  145. return this->HandleCacheMode();
  146. case cmProperty::INSTALL:
  147. return this->HandleInstallMode();
  148. case cmProperty::CACHED_VARIABLE:
  149. break; // should never happen
  150. }
  151. }
  152. return true;
  153. }
  154. bool cmGetPropertyCommand::StoreResult(const char* value)
  155. {
  156. if (this->InfoType == OutSet) {
  157. this->Makefile->AddDefinition(this->Variable, value ? "1" : "0");
  158. } else // if(this->InfoType == OutValue)
  159. {
  160. if (value) {
  161. this->Makefile->AddDefinition(this->Variable, value);
  162. } else {
  163. this->Makefile->RemoveDefinition(this->Variable);
  164. }
  165. }
  166. return true;
  167. }
  168. bool cmGetPropertyCommand::HandleGlobalMode()
  169. {
  170. if (!this->Name.empty()) {
  171. this->SetError("given name for GLOBAL scope.");
  172. return false;
  173. }
  174. // Get the property.
  175. cmake* cm = this->Makefile->GetCMakeInstance();
  176. return this->StoreResult(
  177. cm->GetState()->GetGlobalProperty(this->PropertyName));
  178. }
  179. bool cmGetPropertyCommand::HandleDirectoryMode()
  180. {
  181. // Default to the current directory.
  182. cmMakefile* mf = this->Makefile;
  183. // Lookup the directory if given.
  184. if (!this->Name.empty()) {
  185. // Construct the directory name. Interpret relative paths with
  186. // respect to the current directory.
  187. std::string dir = this->Name;
  188. if (!cmSystemTools::FileIsFullPath(dir.c_str())) {
  189. dir = this->Makefile->GetCurrentSourceDirectory();
  190. dir += "/";
  191. dir += this->Name;
  192. }
  193. // The local generators are associated with collapsed paths.
  194. dir = cmSystemTools::CollapseFullPath(dir);
  195. // Lookup the generator.
  196. mf = this->Makefile->GetGlobalGenerator()->FindMakefile(dir);
  197. if (!mf) {
  198. // Could not find the directory.
  199. this->SetError(
  200. "DIRECTORY scope provided but requested directory was not found. "
  201. "This could be because the directory argument was invalid or, "
  202. "it is valid but has not been processed yet.");
  203. return false;
  204. }
  205. }
  206. if (this->PropertyName == "DEFINITIONS") {
  207. switch (mf->GetPolicyStatus(cmPolicies::CMP0059)) {
  208. case cmPolicies::WARN:
  209. mf->IssueMessage(cmake::AUTHOR_WARNING,
  210. cmPolicies::GetPolicyWarning(cmPolicies::CMP0059));
  211. case cmPolicies::OLD:
  212. return this->StoreResult(mf->GetDefineFlagsCMP0059());
  213. case cmPolicies::NEW:
  214. case cmPolicies::REQUIRED_ALWAYS:
  215. case cmPolicies::REQUIRED_IF_USED:
  216. break;
  217. }
  218. }
  219. // Get the property.
  220. return this->StoreResult(mf->GetProperty(this->PropertyName));
  221. }
  222. bool cmGetPropertyCommand::HandleTargetMode()
  223. {
  224. if (this->Name.empty()) {
  225. this->SetError("not given name for TARGET scope.");
  226. return false;
  227. }
  228. if (cmTarget* target = this->Makefile->FindTargetToUse(this->Name)) {
  229. if (this->PropertyName == "ALIASED_TARGET") {
  230. if (this->Makefile->IsAlias(this->Name)) {
  231. return this->StoreResult(target->GetName().c_str());
  232. }
  233. return this->StoreResult(CM_NULLPTR);
  234. }
  235. return this->StoreResult(
  236. target->GetProperty(this->PropertyName, this->Makefile));
  237. }
  238. std::ostringstream e;
  239. e << "could not find TARGET " << this->Name
  240. << ". Perhaps it has not yet been created.";
  241. this->SetError(e.str());
  242. return false;
  243. }
  244. bool cmGetPropertyCommand::HandleSourceMode()
  245. {
  246. if (this->Name.empty()) {
  247. this->SetError("not given name for SOURCE scope.");
  248. return false;
  249. }
  250. // Get the source file.
  251. if (cmSourceFile* sf = this->Makefile->GetOrCreateSource(this->Name)) {
  252. return this->StoreResult(sf->GetPropertyForUser(this->PropertyName));
  253. }
  254. std::ostringstream e;
  255. e << "given SOURCE name that could not be found or created: " << this->Name;
  256. this->SetError(e.str());
  257. return false;
  258. }
  259. bool cmGetPropertyCommand::HandleTestMode()
  260. {
  261. if (this->Name.empty()) {
  262. this->SetError("not given name for TEST scope.");
  263. return false;
  264. }
  265. // Loop over all tests looking for matching names.
  266. if (cmTest* test = this->Makefile->GetTest(this->Name)) {
  267. return this->StoreResult(test->GetProperty(this->PropertyName));
  268. }
  269. // If not found it is an error.
  270. std::ostringstream e;
  271. e << "given TEST name that does not exist: " << this->Name;
  272. this->SetError(e.str());
  273. return false;
  274. }
  275. bool cmGetPropertyCommand::HandleVariableMode()
  276. {
  277. if (!this->Name.empty()) {
  278. this->SetError("given name for VARIABLE scope.");
  279. return false;
  280. }
  281. return this->StoreResult(this->Makefile->GetDefinition(this->PropertyName));
  282. }
  283. bool cmGetPropertyCommand::HandleCacheMode()
  284. {
  285. if (this->Name.empty()) {
  286. this->SetError("not given name for CACHE scope.");
  287. return false;
  288. }
  289. const char* value = CM_NULLPTR;
  290. if (this->Makefile->GetState()->GetCacheEntryValue(this->Name)) {
  291. value = this->Makefile->GetState()->GetCacheEntryProperty(
  292. this->Name, this->PropertyName);
  293. }
  294. this->StoreResult(value);
  295. return true;
  296. }
  297. bool cmGetPropertyCommand::HandleInstallMode()
  298. {
  299. if (this->Name.empty()) {
  300. this->SetError("not given name for INSTALL scope.");
  301. return false;
  302. }
  303. // Get the installed file.
  304. cmake* cm = this->Makefile->GetCMakeInstance();
  305. if (cmInstalledFile* file =
  306. cm->GetOrCreateInstalledFile(this->Makefile, this->Name)) {
  307. std::string value;
  308. bool isSet = file->GetProperty(this->PropertyName, value);
  309. return this->StoreResult(isSet ? value.c_str() : CM_NULLPTR);
  310. }
  311. std::ostringstream e;
  312. e << "given INSTALL name that could not be found or created: " << this->Name;
  313. this->SetError(e.str());
  314. return false;
  315. }