cmExportCommand.cxx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #include "cmExportCommand.h"
  14. #include "cmGlobalGenerator.h"
  15. #include "cmLocalGenerator.h"
  16. #include "cmGeneratedFileStream.h"
  17. #include "cmake.h"
  18. #include "cmExportBuildFileGenerator.h"
  19. cmExportCommand::cmExportCommand()
  20. :cmCommand()
  21. ,ArgumentGroup()
  22. ,Targets(&Helper, "TARGETS")
  23. ,Namespace(&Helper, "NAMESPACE", &ArgumentGroup)
  24. ,Filename(&Helper, "FILE", &ArgumentGroup)
  25. {
  26. // at first TARGETS
  27. this->Targets.Follows(0);
  28. // and after that the other options in any order
  29. this->ArgumentGroup.Follows(&this->Targets);
  30. }
  31. // cmExportCommand
  32. bool cmExportCommand
  33. ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
  34. {
  35. if(args.size() < 2 )
  36. {
  37. this->SetError("called with too few arguments");
  38. return false;
  39. }
  40. std::vector<std::string> unknownArgs;
  41. this->Helper.Parse(&args, &unknownArgs);
  42. if (!unknownArgs.empty())
  43. {
  44. this->SetError("Unknown arguments.");
  45. return false;
  46. }
  47. if (this->Targets.WasFound() == false)
  48. {
  49. this->SetError("TARGETS option missing.");
  50. return false;
  51. }
  52. if(!this->Filename.WasFound())
  53. {
  54. this->SetError("FILE <filename> option missing.");
  55. return false;
  56. }
  57. // Make sure the file has a .cmake extension.
  58. if(cmSystemTools::GetFilenameLastExtension(this->Filename.GetCString())
  59. != ".cmake")
  60. {
  61. cmOStringStream e;
  62. e << "FILE option given filename \"" << this->Filename.GetString()
  63. << "\" which does not have an extension of \".cmake\".\n";
  64. this->SetError(e.str().c_str());
  65. return false;
  66. }
  67. // Get the file to write.
  68. std::string fname = this->Filename.GetString();
  69. if(cmSystemTools::FileIsFullPath(fname.c_str()))
  70. {
  71. if(!this->Makefile->CanIWriteThisFile(fname.c_str()))
  72. {
  73. cmOStringStream e;
  74. e << "FILE option given filename \"" << fname
  75. << "\" which is in the source tree.\n";
  76. this->SetError(e.str().c_str());
  77. return false;
  78. }
  79. }
  80. else
  81. {
  82. // Interpret relative paths with respect to the current build dir.
  83. fname = this->Makefile->GetCurrentOutputDirectory();
  84. fname += "/";
  85. fname += this->Filename.GetString();
  86. }
  87. // If no targets are to be exported we are done.
  88. if(this->Targets.GetVector().empty())
  89. {
  90. return true;
  91. }
  92. // Collect the targets to be exported.
  93. std::vector<cmTarget*> targets;
  94. for(std::vector<std::string>::const_iterator
  95. currentTarget = this->Targets.GetVector().begin();
  96. currentTarget != this->Targets.GetVector().end();
  97. ++currentTarget)
  98. {
  99. if(cmTarget* target =
  100. this->Makefile->GetLocalGenerator()->
  101. GetGlobalGenerator()->FindTarget(0, currentTarget->c_str()))
  102. {
  103. if((target->GetType() == cmTarget::EXECUTABLE) ||
  104. (target->GetType() == cmTarget::STATIC_LIBRARY) ||
  105. (target->GetType() == cmTarget::SHARED_LIBRARY) ||
  106. (target->GetType() == cmTarget::MODULE_LIBRARY))
  107. {
  108. targets.push_back(target);
  109. }
  110. else
  111. {
  112. cmOStringStream e;
  113. e << "given target \"" << *currentTarget
  114. << "\" which is not an executable or library.";
  115. this->SetError(e.str().c_str());
  116. return false;
  117. }
  118. }
  119. else
  120. {
  121. cmOStringStream e;
  122. e << "given target \"" << *currentTarget
  123. << "\" which is not built by this project.";
  124. this->SetError(e.str().c_str());
  125. return false;
  126. }
  127. }
  128. // Setup export file generation.
  129. cmExportBuildFileGenerator ebfg;
  130. ebfg.SetExportFile(fname.c_str());
  131. ebfg.SetNamespace(this->Namespace.GetCString());
  132. ebfg.SetExports(&targets);
  133. // Compute the set of configurations exported.
  134. if(const char* types =
  135. this->Makefile->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
  136. {
  137. std::vector<std::string> configurationTypes;
  138. cmSystemTools::ExpandListArgument(types, configurationTypes);
  139. for(std::vector<std::string>::const_iterator
  140. ci = configurationTypes.begin();
  141. ci != configurationTypes.end(); ++ci)
  142. {
  143. ebfg.AddConfiguration(ci->c_str());
  144. }
  145. }
  146. else if(const char* config =
  147. this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"))
  148. {
  149. ebfg.AddConfiguration(config);
  150. }
  151. else
  152. {
  153. ebfg.AddConfiguration("");
  154. }
  155. // Generate the import file.
  156. if(!ebfg.GenerateImportFile())
  157. {
  158. this->SetError("could not write export file.");
  159. return false;
  160. }
  161. return true;
  162. }