cmTargetPropCommandBase.cxx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2013 Stephen Kelly <[email protected]>
  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 "cmTargetPropCommandBase.h"
  11. #include "cmGlobalGenerator.h"
  12. //----------------------------------------------------------------------------
  13. bool cmTargetPropCommandBase
  14. ::HandleArguments(std::vector<std::string> const& args, const char *prop,
  15. ArgumentFlags flags)
  16. {
  17. if(args.size() < 3)
  18. {
  19. this->SetError("called with incorrect number of arguments");
  20. return false;
  21. }
  22. // Lookup the target for which libraries are specified.
  23. this->Target =
  24. this->Makefile->GetCMakeInstance()
  25. ->GetGlobalGenerator()->FindTarget(0, args[0].c_str());
  26. if(!this->Target)
  27. {
  28. this->Target = this->Makefile->FindTargetToUse(args[0].c_str());
  29. }
  30. if(!this->Target)
  31. {
  32. this->HandleMissingTarget(args[0]);
  33. return false;
  34. }
  35. unsigned int argIndex = 1;
  36. bool prepend = false;
  37. if ((flags & PROCESS_BEFORE) && args[argIndex] == "BEFORE")
  38. {
  39. if (args.size() < 4)
  40. {
  41. this->SetError("called with incorrect number of arguments");
  42. return false;
  43. }
  44. prepend = true;
  45. ++argIndex;
  46. }
  47. this->Property = prop;
  48. while (argIndex < args.size())
  49. {
  50. if (!this->ProcessContentArgs(args, argIndex, prepend))
  51. {
  52. return false;
  53. }
  54. }
  55. return true;
  56. }
  57. //----------------------------------------------------------------------------
  58. static bool isGeneratorExpression(const std::string &lib)
  59. {
  60. const std::string::size_type openpos = lib.find("$<");
  61. return (openpos != std::string::npos)
  62. && (lib.find(">", openpos) != std::string::npos);
  63. }
  64. //----------------------------------------------------------------------------
  65. bool cmTargetPropCommandBase
  66. ::ProcessContentArgs(std::vector<std::string> const& args,
  67. unsigned int &argIndex, bool prepend)
  68. {
  69. const std::string scope = args[argIndex];
  70. if(scope != "PUBLIC"
  71. && scope != "PRIVATE"
  72. && scope != "INTERFACE" )
  73. {
  74. this->SetError("called with invalid arguments");
  75. return false;
  76. }
  77. if(this->Target->IsImported())
  78. {
  79. this->HandleImportedTarget(args[0]);
  80. return false;
  81. }
  82. ++argIndex;
  83. std::string content;
  84. std::string sep;
  85. for(unsigned int i=argIndex; i < args.size(); ++i, ++argIndex)
  86. {
  87. if(args[i] == "PUBLIC"
  88. || args[i] == "PRIVATE"
  89. || args[i] == "INTERFACE" )
  90. {
  91. this->PopulateTargetProperies(scope, content, prepend);
  92. return true;
  93. }
  94. if (this->Makefile->FindTargetToUse(args[i].c_str()))
  95. {
  96. content += sep + "$<TARGET_PROPERTY:" + args[i]
  97. + ",INTERFACE_" + this->Property + ">";
  98. }
  99. else if(isGeneratorExpression(args[i]))
  100. {
  101. content += sep + args[i];
  102. }
  103. else if (!this->HandleNonTargetArg(content, sep, args[i], args[0]))
  104. {
  105. return false;
  106. }
  107. sep = ";";
  108. }
  109. this->PopulateTargetProperies(scope, content, prepend);
  110. return true;
  111. }
  112. //----------------------------------------------------------------------------
  113. void cmTargetPropCommandBase
  114. ::PopulateTargetProperies(const std::string &scope,
  115. const std::string &content, bool prepend)
  116. {
  117. if (scope == "PRIVATE" || scope == "PUBLIC")
  118. {
  119. this->HandleDirectContent(this->Target, content, prepend);
  120. }
  121. if (scope == "INTERFACE" || scope == "PUBLIC")
  122. {
  123. if (prepend)
  124. {
  125. const std::string propName = std::string("INTERFACE_") + this->Property;
  126. const char *propValue = this->Target->GetProperty(propName.c_str());
  127. const std::string totalContent = content + (propValue
  128. ? std::string(";") + propValue
  129. : std::string());
  130. this->Target->SetProperty(propName.c_str(), totalContent.c_str());
  131. }
  132. else
  133. {
  134. this->Target->AppendProperty(("INTERFACE_" + this->Property).c_str(),
  135. content.c_str());
  136. }
  137. }
  138. }