You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
5.5 KiB
198 lines
5.5 KiB
/*============================================================================
|
|
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 "cmCacheManager.h"
|
|
|
|
#include <cmsys/Glob.hxx>
|
|
|
|
cmFindPathCommand::cmFindPathCommand()
|
|
{
|
|
this->EnvironmentPath = "INCLUDE";
|
|
this->IncludeFileInPath = false;
|
|
}
|
|
|
|
// cmFindPathCommand
|
|
bool cmFindPathCommand
|
|
::InitialPass(std::vector<std::string> 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 ?
|
|
cmCacheManager::FILEPATH :cmCacheManager::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) ?
|
|
cmCacheManager::FILEPATH :cmCacheManager::PATH);
|
|
return true;
|
|
}
|
|
this->Makefile->AddCacheDefinition
|
|
(this->VariableName,
|
|
(this->VariableName + "-NOTFOUND").c_str(),
|
|
this->VariableDocumentation.c_str(),
|
|
(this->IncludeFileInPath) ?
|
|
cmCacheManager::FILEPATH :cmCacheManager::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/<file>
|
|
std::string glob = dir;
|
|
glob += "*.framework/Headers/";
|
|
glob += file;
|
|
cmsys::Glob globIt;
|
|
globIt.FindFiles(glob);
|
|
std::vector<std::string> 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<std::string>::const_iterator ni = this->Names.begin();
|
|
ni != this->Names.end() ; ++ni)
|
|
{
|
|
for(std::vector<std::string>::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<std::string>::const_iterator ni = this->Names.begin();
|
|
ni != this->Names.end() ; ++ni)
|
|
{
|
|
for(std::vector<std::string>::const_iterator
|
|
p = this->SearchPaths.begin();
|
|
p != this->SearchPaths.end(); ++p)
|
|
{
|
|
std::string fwPath = this->FindHeaderInFramework(*ni, *p);
|
|
if(!fwPath.empty())
|
|
{
|
|
return fwPath;
|
|
}
|
|
}
|
|
}
|
|
return "";
|
|
}
|