cmFindPathCommand.cxx 5.5 KB

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