1
0

cmInstallCommand.cxx 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  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 "cmInstallCommand.h"
  14. #include "cmInstallScriptGenerator.h"
  15. #include "cmInstallTargetGenerator.h"
  16. // cmInstallCommand
  17. bool cmInstallCommand::InitialPass(std::vector<std::string> const& args)
  18. {
  19. // Allow calling with no arguments so that arguments may be built up
  20. // using a variable that may be left empty.
  21. if(args.empty())
  22. {
  23. return true;
  24. }
  25. // Switch among the command modes.
  26. if(args[0] == "SCRIPT")
  27. {
  28. return this->HandleScriptMode(args);
  29. }
  30. else if(args[0] == "TARGETS")
  31. {
  32. return this->HandleTargetsMode(args);
  33. }
  34. // Unknown mode.
  35. cmStdString e = "called with unknown mode ";
  36. e += args[0];
  37. this->SetError(e.c_str());
  38. return false;
  39. }
  40. //----------------------------------------------------------------------------
  41. bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args)
  42. {
  43. bool doing_script = false;
  44. for(size_t i=0; i < args.size(); ++i)
  45. {
  46. if(args[i] == "SCRIPT")
  47. {
  48. doing_script = true;
  49. }
  50. else if(doing_script)
  51. {
  52. doing_script = false;
  53. std::string script = args[i];
  54. if(!cmSystemTools::FileIsFullPath(script.c_str()))
  55. {
  56. script = m_Makefile->GetCurrentDirectory();
  57. script += "/";
  58. script += args[i];
  59. }
  60. if(cmSystemTools::FileIsDirectory(script.c_str()))
  61. {
  62. this->SetError("given a directory as value of SCRIPT argument.");
  63. return false;
  64. }
  65. m_Makefile->AddInstallGenerator(
  66. new cmInstallScriptGenerator(script.c_str()));
  67. }
  68. }
  69. if(doing_script)
  70. {
  71. this->SetError("given no value for SCRIPT argument.");
  72. return false;
  73. }
  74. return true;
  75. }
  76. //----------------------------------------------------------------------------
  77. bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
  78. {
  79. // This is the TARGETS mode.
  80. bool doing_targets = true;
  81. bool doing_destination = false;
  82. bool library_settings = true;
  83. bool runtime_settings = true;
  84. std::vector<cmTarget*> targets;
  85. const char* library_destination = 0;
  86. const char* runtime_destination = 0;
  87. for(unsigned int i=1; i < args.size(); ++i)
  88. {
  89. if(args[i] == "DESTINATION")
  90. {
  91. // Switch to setting the destination property.
  92. doing_targets = false;
  93. doing_destination = true;
  94. }
  95. else if(args[i] == "LIBRARY")
  96. {
  97. // Switch to setting only library properties.
  98. doing_targets = false;
  99. doing_destination = false;
  100. library_settings = true;
  101. runtime_settings = false;
  102. }
  103. else if(args[i] == "RUNTIME")
  104. {
  105. // Switch to setting only runtime properties.
  106. doing_targets = false;
  107. doing_destination = false;
  108. library_settings = false;
  109. runtime_settings = true;
  110. }
  111. else if(doing_targets)
  112. {
  113. // Lookup this target in the current directory.
  114. if(cmTarget* target = m_Makefile->FindTarget(args[i].c_str()))
  115. {
  116. // Found the target. Check its type.
  117. if(target->GetType() != cmTarget::EXECUTABLE &&
  118. target->GetType() != cmTarget::STATIC_LIBRARY &&
  119. target->GetType() != cmTarget::SHARED_LIBRARY &&
  120. target->GetType() != cmTarget::MODULE_LIBRARY)
  121. {
  122. cmOStringStream e;
  123. e << "TARGETS given target \"" << args[i]
  124. << "\" which is not an executable, library, or module.";
  125. this->SetError(e.str().c_str());
  126. return false;
  127. }
  128. // Store the target in the list to be installed.
  129. targets.push_back(target);
  130. }
  131. else
  132. {
  133. // Did not find the target.
  134. cmOStringStream e;
  135. e << "TARGETS given target \"" << args[i]
  136. << "\" which does not exist in this directory.";
  137. this->SetError(e.str().c_str());
  138. return false;
  139. }
  140. }
  141. else if(doing_destination)
  142. {
  143. // Set the destination in the active set(s) of properties.
  144. if(library_settings)
  145. {
  146. library_destination = args[i].c_str();
  147. }
  148. if(runtime_settings)
  149. {
  150. runtime_destination = args[i].c_str();
  151. }
  152. doing_destination = false;
  153. }
  154. else
  155. {
  156. // Unknown argument.
  157. cmOStringStream e;
  158. e << "TARGETS given unknown argument \"" << args[i] << "\".";
  159. this->SetError(e.str().c_str());
  160. return false;
  161. }
  162. }
  163. // Check if there is something to do.
  164. if(targets.empty())
  165. {
  166. return true;
  167. }
  168. if(!library_destination && !runtime_destination)
  169. {
  170. this->SetError("TARGETS given no DESTINATION!");
  171. return false;
  172. }
  173. // Compute destination paths.
  174. std::string library_dest;
  175. std::string runtime_dest;
  176. this->ComputeDestination(library_destination, library_dest);
  177. this->ComputeDestination(runtime_destination, runtime_dest);
  178. // Generate install script code to install the given targets.
  179. for(std::vector<cmTarget*>::iterator ti = targets.begin();
  180. ti != targets.end(); ++ti)
  181. {
  182. // Handle each target type.
  183. cmTarget& target = *(*ti);
  184. switch(target.GetType())
  185. {
  186. case cmTarget::SHARED_LIBRARY:
  187. {
  188. // Shared libraries are handled differently on DLL and non-DLL
  189. // platforms. All windows platforms are DLL platforms
  190. // including cygwin. Currently no other platform is a DLL
  191. // platform.
  192. #if defined(_WIN32) || defined(__CYGWIN__)
  193. // This is a DLL platform.
  194. if(library_destination)
  195. {
  196. // The import library uses the LIBRARY properties.
  197. m_Makefile->AddInstallGenerator(
  198. new cmInstallTargetGenerator(target, library_dest.c_str(), true));
  199. }
  200. if(runtime_destination)
  201. {
  202. // The DLL uses the RUNTIME properties.
  203. m_Makefile->AddInstallGenerator(
  204. new cmInstallTargetGenerator(target, runtime_dest.c_str(), false));
  205. }
  206. #else
  207. // This is a non-DLL platform.
  208. if(library_destination)
  209. {
  210. // The shared library uses the LIBRARY properties.
  211. m_Makefile->AddInstallGenerator(
  212. new cmInstallTargetGenerator(target, library_dest.c_str()));
  213. }
  214. #endif
  215. }
  216. break;
  217. case cmTarget::STATIC_LIBRARY:
  218. case cmTarget::MODULE_LIBRARY:
  219. {
  220. // Static libraries and modules use LIBRARY properties.
  221. if(library_destination)
  222. {
  223. m_Makefile->AddInstallGenerator(
  224. new cmInstallTargetGenerator(target, library_dest.c_str()));
  225. }
  226. else
  227. {
  228. cmOStringStream e;
  229. e << "TARGETS given no LIBRARY DESTINATION for ";
  230. if(target.GetType() == cmTarget::STATIC_LIBRARY)
  231. {
  232. e << "static library";
  233. }
  234. else
  235. {
  236. e << "module";
  237. }
  238. e << " target \"" << target.GetName() << "\".";
  239. this->SetError(e.str().c_str());
  240. return false;
  241. }
  242. }
  243. break;
  244. case cmTarget::EXECUTABLE:
  245. {
  246. // Executables use the RUNTIME properties.
  247. if(runtime_destination)
  248. {
  249. m_Makefile->AddInstallGenerator(
  250. new cmInstallTargetGenerator(target, runtime_dest.c_str()));
  251. }
  252. else
  253. {
  254. cmOStringStream e;
  255. e << "TARGETS given no RUNTIME DESTINATION for executable target \""
  256. << target.GetName() << "\".";
  257. this->SetError(e.str().c_str());
  258. return false;
  259. }
  260. }
  261. break;
  262. default:
  263. // This should never happen due to the above type check.
  264. // Ignore the case.
  265. break;
  266. }
  267. }
  268. return true;
  269. }
  270. //----------------------------------------------------------------------------
  271. void cmInstallCommand::ComputeDestination(const char* destination,
  272. std::string& dest)
  273. {
  274. if(destination)
  275. {
  276. if(cmSystemTools::FileIsFullPath(destination))
  277. {
  278. // Full paths are absolute.
  279. dest = destination;
  280. }
  281. else
  282. {
  283. // Relative paths are treated with respect to the installation prefix.
  284. dest = "${CMAKE_INSTALL_PREFIX}/";
  285. dest += destination;
  286. }
  287. // Format the path nicely. Note this also removes trailing
  288. // slashes.
  289. cmSystemTools::ConvertToUnixSlashes(dest);
  290. }
  291. else
  292. {
  293. dest = "";
  294. }
  295. }