cmFindPathCommand.cxx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  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 "cmFindPathCommand.h"
  11. #include "cmCacheManager.h"
  12. #include <cmsys/Glob.hxx>
  13. cmFindPathCommand::cmFindPathCommand()
  14. {
  15. this->EnvironmentPath = "INCLUDE";
  16. this->IncludeFileInPath = false;
  17. }
  18. // cmFindPathCommand
  19. bool cmFindPathCommand
  20. ::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &)
  21. {
  22. this->VariableDocumentation = "Path to a file.";
  23. this->CMakePathName = "INCLUDE";
  24. if(!this->ParseArguments(argsIn))
  25. {
  26. return false;
  27. }
  28. if(this->AlreadyInCache)
  29. {
  30. // If the user specifies the entry on the command line without a
  31. // type we should add the type and docstring but keep the original
  32. // value.
  33. if(this->AlreadyInCacheWithoutMetaInfo)
  34. {
  35. this->Makefile->AddCacheDefinition(
  36. this->VariableName, "",
  37. this->VariableDocumentation.c_str(),
  38. (this->IncludeFileInPath ?
  39. cmCacheManager::FILEPATH :cmCacheManager::PATH)
  40. );
  41. }
  42. return true;
  43. }
  44. std::string result = this->FindHeader();
  45. if(!result.empty())
  46. {
  47. this->Makefile->AddCacheDefinition
  48. (this->VariableName, result.c_str(),
  49. this->VariableDocumentation.c_str(),
  50. (this->IncludeFileInPath) ?
  51. cmCacheManager::FILEPATH :cmCacheManager::PATH);
  52. return true;
  53. }
  54. this->Makefile->AddCacheDefinition
  55. (this->VariableName,
  56. (this->VariableName + "-NOTFOUND").c_str(),
  57. this->VariableDocumentation.c_str(),
  58. (this->IncludeFileInPath) ?
  59. cmCacheManager::FILEPATH :cmCacheManager::PATH);
  60. return true;
  61. }
  62. //----------------------------------------------------------------------------
  63. std::string cmFindPathCommand::FindHeader()
  64. {
  65. std::string header;
  66. if(this->SearchFrameworkFirst || this->SearchFrameworkOnly)
  67. {
  68. header = this->FindFrameworkHeader();
  69. }
  70. if(header.empty() && !this->SearchFrameworkOnly)
  71. {
  72. header = this->FindNormalHeader();
  73. }
  74. if(header.empty() && this->SearchFrameworkLast)
  75. {
  76. header = this->FindFrameworkHeader();
  77. }
  78. return header;
  79. }
  80. std::string
  81. cmFindPathCommand::FindHeaderInFramework(std::string const& file,
  82. std::string const& dir)
  83. {
  84. std::string fileName = file;
  85. std::string frameWorkName;
  86. std::string::size_type pos = fileName.find("/");
  87. // if there is a / in the name try to find the header as a framework
  88. // For example bar/foo.h would look for:
  89. // bar.framework/Headers/foo.h
  90. if(pos != fileName.npos)
  91. {
  92. // remove the name from the slash;
  93. fileName = fileName.substr(pos+1);
  94. frameWorkName = file;
  95. frameWorkName =
  96. frameWorkName.substr(0, frameWorkName.size()-fileName.size()-1);
  97. // if the framework has a path in it then just use the filename
  98. if(frameWorkName.find("/") != frameWorkName.npos)
  99. {
  100. fileName = file;
  101. frameWorkName = "";
  102. }
  103. if(!frameWorkName.empty())
  104. {
  105. std::string fpath = dir;
  106. fpath += frameWorkName;
  107. fpath += ".framework";
  108. std::string intPath = fpath;
  109. intPath += "/Headers/";
  110. intPath += fileName;
  111. if(cmSystemTools::FileExists(intPath.c_str()))
  112. {
  113. if(this->IncludeFileInPath)
  114. {
  115. return intPath;
  116. }
  117. return fpath;
  118. }
  119. }
  120. }
  121. // if it is not found yet or not a framework header, then do a glob search
  122. // for all frameworks in the directory: dir/*.framework/Headers/<file>
  123. std::string glob = dir;
  124. glob += "*.framework/Headers/";
  125. glob += file;
  126. cmsys::Glob globIt;
  127. globIt.FindFiles(glob);
  128. std::vector<std::string> files = globIt.GetFiles();
  129. if(!files.empty())
  130. {
  131. std::string fheader = cmSystemTools::CollapseFullPath(files[0]);
  132. if(this->IncludeFileInPath)
  133. {
  134. return fheader;
  135. }
  136. fheader = cmSystemTools::GetFilenamePath(fheader);
  137. return fheader;
  138. }
  139. return "";
  140. }
  141. //----------------------------------------------------------------------------
  142. std::string cmFindPathCommand::FindNormalHeader()
  143. {
  144. std::string tryPath;
  145. for(std::vector<std::string>::const_iterator ni = this->Names.begin();
  146. ni != this->Names.end() ; ++ni)
  147. {
  148. for(std::vector<std::string>::const_iterator
  149. p = this->SearchPaths.begin();
  150. p != this->SearchPaths.end(); ++p)
  151. {
  152. tryPath = *p;
  153. tryPath += *ni;
  154. if(cmSystemTools::FileExists(tryPath.c_str()))
  155. {
  156. if(this->IncludeFileInPath)
  157. {
  158. return tryPath;
  159. }
  160. else
  161. {
  162. return *p;
  163. }
  164. }
  165. }
  166. }
  167. return "";
  168. }
  169. //----------------------------------------------------------------------------
  170. std::string cmFindPathCommand::FindFrameworkHeader()
  171. {
  172. for(std::vector<std::string>::const_iterator ni = this->Names.begin();
  173. ni != this->Names.end() ; ++ni)
  174. {
  175. for(std::vector<std::string>::const_iterator
  176. p = this->SearchPaths.begin();
  177. p != this->SearchPaths.end(); ++p)
  178. {
  179. std::string fwPath = this->FindHeaderInFramework(*ni, *p);
  180. if(!fwPath.empty())
  181. {
  182. return fwPath;
  183. }
  184. }
  185. }
  186. return "";
  187. }