cmFindPathCommand.cxx 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  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 "cmFindPathCommand.h"
  14. #include "cmCacheManager.h"
  15. #include <cmsys/Glob.hxx>
  16. cmFindPathCommand::cmFindPathCommand()
  17. {
  18. this->IncludeFileInPath = false;
  19. cmSystemTools::ReplaceString(this->GenericDocumentation,
  20. "FIND_XXX", "FIND_PATH");
  21. cmSystemTools::ReplaceString(this->GenericDocumentation,
  22. "CMAKE_XXX_PATH", "CMAKE_INCLUDE_PATH");
  23. cmSystemTools::ReplaceString(this->GenericDocumentation,
  24. "XXX_SYSTEM", "INCLUDE");
  25. cmSystemTools::ReplaceString(this->GenericDocumentation,
  26. "CMAKE_SYSTEM_XXX_PATH",
  27. "CMAKE_SYSTEM_INCLUDE_PATH");
  28. cmSystemTools::ReplaceString(this->GenericDocumentation,
  29. "SEARCH_XXX_DESC",
  30. "directory containing the named file");
  31. cmSystemTools::ReplaceString(this->GenericDocumentation,
  32. "SEARCH_XXX", "file in a directory");
  33. this->ExtraDocAdded = false;
  34. }
  35. const char* cmFindPathCommand::GetFullDocumentation()
  36. {
  37. if(!this->ExtraDocAdded && !this->IncludeFileInPath)
  38. {
  39. this->GenericDocumentation +=
  40. "\n"
  41. "When searching for frameworks, if the file is specified as "
  42. "A/b.h, then the framework search will look for "
  43. "A.framework/Headers/b.h. "
  44. "If that is found the path will be set to the path to the framework. "
  45. "CMake will convert this to the correct -F option to include the "
  46. "file. ";
  47. this->ExtraDocAdded = true;
  48. }
  49. return this->GenericDocumentation.c_str();
  50. }
  51. // cmFindPathCommand
  52. bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn)
  53. {
  54. this->VariableDocumentation = "Path to a file.";
  55. this->CMakePathName = "INCLUDE";
  56. if(!this->ParseArguments(argsIn))
  57. {
  58. return false;
  59. }
  60. if(this->AlreadyInCache)
  61. {
  62. return true;
  63. }
  64. std::string ff = this->Makefile->GetSafeDefinition("CMAKE_FIND_FRAMEWORK");
  65. bool supportFrameworks = true;
  66. if( ff.size() == 0 || ff == "NEVER" )
  67. {
  68. supportFrameworks = false;
  69. }
  70. std::string framework;
  71. // Use the search path to find the file.
  72. unsigned int k;
  73. std::string result;
  74. for(k=0; k < this->SearchPaths.size(); k++)
  75. {
  76. for(unsigned int j =0; j < this->Names.size(); ++j)
  77. {
  78. // if frameworks are supported try to find the header in a framework
  79. std::string tryPath;
  80. if(supportFrameworks)
  81. {
  82. tryPath = this->FindHeaderInFramework(this->Names[j],
  83. this->SearchPaths[k]);
  84. if(tryPath.size())
  85. {
  86. result = tryPath;
  87. }
  88. }
  89. if(result.size() == 0)
  90. {
  91. tryPath = this->SearchPaths[k];
  92. tryPath += "/";
  93. tryPath += this->Names[j];
  94. if(cmSystemTools::FileExists(tryPath.c_str()))
  95. {
  96. if(this->IncludeFileInPath)
  97. {
  98. result = tryPath;
  99. }
  100. else
  101. {
  102. result = this->SearchPaths[k];
  103. }
  104. }
  105. }
  106. if(result.size() != 0)
  107. {
  108. this->Makefile->AddCacheDefinition
  109. (this->VariableName.c_str(), result.c_str(),
  110. this->VariableDocumentation.c_str(),
  111. (this->IncludeFileInPath) ?
  112. cmCacheManager::FILEPATH :cmCacheManager::PATH);
  113. return true;
  114. }
  115. }
  116. }
  117. this->Makefile->AddCacheDefinition
  118. (this->VariableName.c_str(),
  119. (this->VariableName + "-NOTFOUND").c_str(),
  120. this->VariableDocumentation.c_str(),
  121. (this->IncludeFileInPath) ?
  122. cmCacheManager::FILEPATH :cmCacheManager::PATH);
  123. return true;
  124. }
  125. std::string cmFindPathCommand::FindHeaderInFramework(std::string& file,
  126. std::string& dir)
  127. {
  128. cmStdString fileName = file;
  129. cmStdString frameWorkName;
  130. cmStdString::size_type pos = fileName.find("/");
  131. // if there is a / in the name try to find the header as a framework
  132. // For example bar/foo.h would look for:
  133. // bar.framework/Headers/foo.h
  134. if(pos != fileName.npos)
  135. {
  136. // remove the name from the slash;
  137. fileName = fileName.substr(pos+1);
  138. frameWorkName = file;
  139. frameWorkName =
  140. frameWorkName.substr(0, frameWorkName.size()-fileName.size()-1);
  141. // if the framework has a path in it then just use the filename
  142. if(frameWorkName.find("/") != frameWorkName.npos)
  143. {
  144. fileName = file;
  145. frameWorkName = "";
  146. }
  147. if(frameWorkName.size())
  148. {
  149. std::string fpath = dir;
  150. fpath += "/";
  151. fpath += frameWorkName;
  152. fpath += ".framework";
  153. std::string intPath = fpath;
  154. intPath += "/Headers/";
  155. intPath += fileName;
  156. if(cmSystemTools::FileExists(intPath.c_str()))
  157. {
  158. if(this->IncludeFileInPath)
  159. {
  160. return intPath;
  161. }
  162. return fpath;
  163. }
  164. }
  165. }
  166. // if it is not found yet or not a framework header, then do a glob search
  167. // for all files in dir/*/Headers/
  168. cmStdString glob = dir;
  169. glob += "/*/Headers/";
  170. glob += file;
  171. cmsys::Glob globIt;
  172. globIt.FindFiles(glob);
  173. std::vector<std::string> files = globIt.GetFiles();
  174. if(files.size())
  175. {
  176. cmStdString fheader = cmSystemTools::CollapseFullPath(files[0].c_str());
  177. if(this->IncludeFileInPath)
  178. {
  179. return fheader;
  180. }
  181. fheader = cmSystemTools::GetFilenamePath(fheader);
  182. return fheader;
  183. }
  184. return "";
  185. }