/*============================================================================ CMake - Cross Platform Makefile Generator Copyright 2000-2009 Kitware, Inc., Insight Software Consortium Distributed under the OSI-approved BSD License (the "License"); see accompanying file Copyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ #include "cmFindPathCommand.h" #include cmFindPathCommand::cmFindPathCommand() { this->EnvironmentPath = "INCLUDE"; this->IncludeFileInPath = false; } // cmFindPathCommand bool cmFindPathCommand ::InitialPass(std::vector const& argsIn, cmExecutionStatus &) { this->VariableDocumentation = "Path to a file."; this->CMakePathName = "INCLUDE"; if(!this->ParseArguments(argsIn)) { return false; } if(this->AlreadyInCache) { // If the user specifies the entry on the command line without a // type we should add the type and docstring but keep the original // value. if(this->AlreadyInCacheWithoutMetaInfo) { this->Makefile->AddCacheDefinition( this->VariableName, "", this->VariableDocumentation.c_str(), (this->IncludeFileInPath ? cmState::FILEPATH :cmState::PATH) ); } return true; } std::string result = this->FindHeader(); if(!result.empty()) { this->Makefile->AddCacheDefinition (this->VariableName, result.c_str(), this->VariableDocumentation.c_str(), (this->IncludeFileInPath) ? cmState::FILEPATH :cmState::PATH); return true; } this->Makefile->AddCacheDefinition (this->VariableName, (this->VariableName + "-NOTFOUND").c_str(), this->VariableDocumentation.c_str(), (this->IncludeFileInPath) ? cmState::FILEPATH :cmState::PATH); return true; } //---------------------------------------------------------------------------- std::string cmFindPathCommand::FindHeader() { std::string header; if(this->SearchFrameworkFirst || this->SearchFrameworkOnly) { header = this->FindFrameworkHeader(); } if(header.empty() && !this->SearchFrameworkOnly) { header = this->FindNormalHeader(); } if(header.empty() && this->SearchFrameworkLast) { header = this->FindFrameworkHeader(); } return header; } std::string cmFindPathCommand::FindHeaderInFramework(std::string const& file, std::string const& dir) { std::string fileName = file; std::string frameWorkName; std::string::size_type pos = fileName.find("/"); // if there is a / in the name try to find the header as a framework // For example bar/foo.h would look for: // bar.framework/Headers/foo.h if(pos != fileName.npos) { // remove the name from the slash; fileName = fileName.substr(pos+1); frameWorkName = file; frameWorkName = frameWorkName.substr(0, frameWorkName.size()-fileName.size()-1); // if the framework has a path in it then just use the filename if(frameWorkName.find("/") != frameWorkName.npos) { fileName = file; frameWorkName = ""; } if(!frameWorkName.empty()) { std::string fpath = dir; fpath += frameWorkName; fpath += ".framework"; std::string intPath = fpath; intPath += "/Headers/"; intPath += fileName; if(cmSystemTools::FileExists(intPath.c_str())) { if(this->IncludeFileInPath) { return intPath; } return fpath; } } } // if it is not found yet or not a framework header, then do a glob search // for all frameworks in the directory: dir/*.framework/Headers/ std::string glob = dir; glob += "*.framework/Headers/"; glob += file; cmsys::Glob globIt; globIt.FindFiles(glob); std::vector files = globIt.GetFiles(); if(!files.empty()) { std::string fheader = cmSystemTools::CollapseFullPath(files[0]); if(this->IncludeFileInPath) { return fheader; } fheader = cmSystemTools::GetFilenamePath(fheader); return fheader; } return ""; } //---------------------------------------------------------------------------- std::string cmFindPathCommand::FindNormalHeader() { std::string tryPath; for(std::vector::const_iterator ni = this->Names.begin(); ni != this->Names.end() ; ++ni) { for(std::vector::const_iterator p = this->SearchPaths.begin(); p != this->SearchPaths.end(); ++p) { tryPath = *p; tryPath += *ni; if(cmSystemTools::FileExists(tryPath.c_str())) { if(this->IncludeFileInPath) { return tryPath; } else { return *p; } } } } return ""; } //---------------------------------------------------------------------------- std::string cmFindPathCommand::FindFrameworkHeader() { for(std::vector::const_iterator ni = this->Names.begin(); ni != this->Names.end() ; ++ni) { for(std::vector::const_iterator p = this->SearchPaths.begin(); p != this->SearchPaths.end(); ++p) { std::string fwPath = this->FindHeaderInFramework(*ni, *p); if(!fwPath.empty()) { return fwPath; } } } return ""; }