From a5825cd11af3a6def49c9528e77f4394babff7de Mon Sep 17 00:00:00 2001 From: Bill Hoffman Date: Thu, 2 Mar 2006 13:30:22 -0500 Subject: [PATCH] ENH: check in new find stuff --- Modules/Platform/CYGWIN.cmake | 1 + Modules/Platform/Darwin.cmake | 3 + Modules/Platform/Linux.cmake | 1 + Modules/Platform/SunOS.cmake | 1 + Modules/Platform/UnixPaths.cmake | 5 + Modules/Platform/Windows-cl.cmake | 1 + Modules/Platform/WindowsPaths.cmake | 3 + Source/cmBootstrapCommands.cxx | 1 + Source/cmFindBase.cxx | 65 ++++++- Source/cmFindBase.h | 5 + Source/cmFindFileCommand.cxx | 86 +-------- Source/cmFindFileCommand.h | 39 +---- Source/cmFindLibraryCommand.cxx | 261 +++++++++++++++++----------- Source/cmFindLibraryCommand.h | 36 +--- Source/cmFindPathCommand.cxx | 213 ++++++++++++----------- Source/cmFindPathCommand.h | 35 +--- Source/cmFindProgramCommand.cxx | 145 ++++------------ Source/cmFindProgramCommand.h | 32 +--- Source/kwsys/Registry.cxx | 1 + Source/kwsys/SystemTools.cxx | 58 +++++-- 20 files changed, 456 insertions(+), 536 deletions(-) create mode 100644 Modules/Platform/UnixPaths.cmake create mode 100644 Modules/Platform/WindowsPaths.cmake diff --git a/Modules/Platform/CYGWIN.cmake b/Modules/Platform/CYGWIN.cmake index 1f0552238..5cd1a55fe 100644 --- a/Modules/Platform/CYGWIN.cmake +++ b/Modules/Platform/CYGWIN.cmake @@ -27,3 +27,4 @@ SET(CMAKE_C_CREATE_SHARED_LIBRARY " -o -Wl,--out-implib, ") SET(CMAKE_CXX_CREATE_SHARED_LIBRARY " -o -Wl,--out-implib, ") +INCLUDE(Platform/UnixPaths) diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake index c8dbd87a6..0d0e56d52 100644 --- a/Modules/Platform/Darwin.cmake +++ b/Modules/Platform/Darwin.cmake @@ -46,3 +46,6 @@ SET(CMAKE_SYSTEM_FRAMEWORK_PATH /Network/Library/Frameworks /System/Library/Frameworks) +INCLUDE(Platform/UnixPaths) +SET(CMAKE_SYSTEM_INCLUDE_PATH ${CMAKE_SYSTEM_INCLUDE_PATH} /sw/include) +SET(CMAKE_SYSTEM_LIBRARY_PATH ${CMAKE_SYSTEM_LIBRARY_PATH} /sw/lib) diff --git a/Modules/Platform/Linux.cmake b/Modules/Platform/Linux.cmake index 5040b5e42..3053f3711 100644 --- a/Modules/Platform/Linux.cmake +++ b/Modules/Platform/Linux.cmake @@ -7,3 +7,4 @@ SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,") SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":") SET(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-soname,") SET(CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG "-Wl,-soname,") +INCLUDE(Platform/UnixPaths) diff --git a/Modules/Platform/SunOS.cmake b/Modules/Platform/SunOS.cmake index 183c8a058..ab9647674 100644 --- a/Modules/Platform/SunOS.cmake +++ b/Modules/Platform/SunOS.cmake @@ -60,3 +60,4 @@ ELSE(CMAKE_COMPILER_IS_GNUCXX) " ") ENDIF(CMAKE_CXX_COMPILER) ENDIF(CMAKE_COMPILER_IS_GNUCXX) +INCLUDE(Platform/UnixPaths) diff --git a/Modules/Platform/UnixPaths.cmake b/Modules/Platform/UnixPaths.cmake new file mode 100644 index 000000000..ecbad17c1 --- /dev/null +++ b/Modules/Platform/UnixPaths.cmake @@ -0,0 +1,5 @@ +SET(CMAKE_SYSTEM_INCLUDE_PATH ${CMAKE_SYSTEM_INCLUDE_PATH} /usr/include + /usr/local/include /usr/local /usr/X11R6/include /usr/include/X11) +SET(CMAKE_SYSTEM_LIBRARY_PATH ${CMAKE_SYSTEM_LIBRARY_PATH} /lib /use/lib /usr/local/lib + /usr/lib/w32api /usr/X11R6/lib /opt/local/lib /opt/csw/lib /opt/lib ) +SET(CMAKE_SYSTEM_PROGRAM_PATH ${CMAKE_SYSTEM_PROGRAM_PATH} /bin /usr/bin /usr/local/bin /sbin) diff --git a/Modules/Platform/Windows-cl.cmake b/Modules/Platform/Windows-cl.cmake index 6bca89258..70ca1317f 100644 --- a/Modules/Platform/Windows-cl.cmake +++ b/Modules/Platform/Windows-cl.cmake @@ -231,3 +231,4 @@ IF(NOT EXISTS "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeCXXPlatform.cmake") ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeCXXPlatform.cmake IMMEDIATE) ENDIF(NOT EXISTS "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeCXXPlatform.cmake") +INCLUDE(Platform/WindowsPaths) diff --git a/Modules/Platform/WindowsPaths.cmake b/Modules/Platform/WindowsPaths.cmake new file mode 100644 index 000000000..dbd195ead --- /dev/null +++ b/Modules/Platform/WindowsPaths.cmake @@ -0,0 +1,3 @@ +SET(CMAKE_SYSTEM_INCLUDE_PATH ${CMAKE_SYSTEM_INCLUDE_PATH} "$ENV{ProgramFiles}") +SET(CMAKE_SYSTEM_LIBRARY_PATH ${CMAKE_SYSTEM_LIBRARY_PATH} "$ENV{ProgramFiles}") +SET(CMAKE_SYSTEM_PROGRAM_PATH ${CMAKE_SYSTEM_PROGRAM_PATH} "$ENV{ProgramFiles}") diff --git a/Source/cmBootstrapCommands.cxx b/Source/cmBootstrapCommands.cxx index e20da55c6..2216515c0 100644 --- a/Source/cmBootstrapCommands.cxx +++ b/Source/cmBootstrapCommands.cxx @@ -37,6 +37,7 @@ #include "cmEndForEachCommand.cxx" #include "cmEndIfCommand.cxx" #include "cmExecProgramCommand.cxx" +#include "cmFindBase.cxx" #include "cmFileCommand.cxx" #include "cmFindFileCommand.cxx" #include "cmFindLibraryCommand.cxx" diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index 952cd8027..a6265ee6d 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -31,8 +31,68 @@ cmFindBase::cmFindBase() #endif this->SearchFrameworkOnly = false; this->SearchFrameworkLast = false; + this->GenericDocumentation = + " FIND_XXX( name1 path1 path2 ...)\n" + "This is the short-hand signature for the command that" + "is sufficient in many cases. It is the same " + "as FIND_XXX( NAMES name1 PATHS path2 path2 ...)\n" + " FIND_XXX(\n" + " \n" + " NAMES name1 [name2 ...]\n" + " PATHS path1 [path2 ...]\n" + " [PATH_SUFFIXES suffix1 [suffix2 ...]]\n" + " [DOC \"cache documentation string\"]\n" + " [NO_CMAKE_ENVIRONMENT_PATH]\n" + " [NO_CMAKE_PATH]\n" + " [NO_SYSTEM_PATH]\n" + " [NO_CMAKE_SYSTEM_PATH]\n" + " )\n" + "" + "This command is used to find a SEARCH_XXX_DESC. " + "A cache entry named by is created to store the result " + "of this command. If nothing is found, the result will be " + "-NOTFOUND. The name of the SEARCH_XXX that " + "is searched for is specified by the names listed " + "after the NAMES argument. Additional search locations " + "can be specified after the PATHS arguement. The arguement " + "after DOC will be used for the documentation string in " + "the cache. PATH_SUFFIXES can be used to give sub directories " + "that will be appeneded to the search paths.\n" + "The search process is as follows:\n" + "1. Search cmake specific environment varibles. This " + "can be skipped if NO_CMAKE_ENVIRONMENT_PATH is passed.\n" + "" + " CMAKE_FRAMEWORK_PATH\n" + " CMAKE_XXX_PATH\n" + "2. Search cmake variables with the same names as " + "the cmake specific environment variables. These " + "are intended to be used on the command line with a " + "-DVAR=value. This can be skipped if NO_CMAKE_PATH " + "is passed.\n" + "" + " CMAKE_FRAMEWORK_PATH\n" + " CMAKE_XXX_PATH\n" + "3. Search the standard system environment variables. " + "This can be skipped if NO_SYSTEM_PATH is an argument.\n" + " PATH\n" + " XXX_SYSTEM\n" // replace with "", LIB, or INCLUDE + "4. Search cmake variables defined in the Platform files " + "for the current system. This can be skipped if NO_CMAKE_SYSTEM_PATH " + "is passed.\n" + " CMAKE_SYSTEM_FRAMEWORK_PATH\n" + " CMAKE_SYSTEM_XXX_PATH\n" + "5. Search the paths specified after PATHS or in the short-hand version " + "of the command.\n" + "On Darwin or systems supporting OSX Frameworks, the cmake variable" + " CMAKE_FIND_FRAMEWORK can be set to empty or one of the following:\n" + " \"FIRST\" - Try to find frameworks before standard\n" + " libraries or headers. This is the default on Darwin.\n" + " \"LAST\" - Try to find frameworks after standard\n" + " librareis or headers.\n" + " \"ONLY\" - Only try to find frameworks.\n" + " \"NEVER\". - Never try to find frameworks.\n"; } - + bool cmFindBase::ParseArguments(std::vector const& argsIn) { if(argsIn.size() < 2 ) @@ -162,7 +222,6 @@ bool cmFindBase::ParseArguments(std::vector const& argsIn) // FIND_*(VAR name path1 path2 ...) if(!newStyle) { - std::cerr << "oldstyle\n"; this->Names.push_back(args[1]); for(unsigned int j = 2; j < args.size(); ++j) { @@ -355,7 +414,6 @@ void cmFindBase::PrintFindStuff() bool cmFindBase::CheckForVariableInCache() { - std::cerr << "CheckForVariableInCache " << this->VariableName << "\n"; const char* cacheValue = m_Makefile->GetDefinition(this->VariableName.c_str()); if(cacheValue && !cmSystemTools::IsNOTFOUND(cacheValue)) @@ -364,7 +422,6 @@ bool cmFindBase::CheckForVariableInCache() } if(cacheValue) { - std::cerr << "Cachevalue " << cacheValue << "\n"; cmCacheManager::CacheIterator it = m_Makefile->GetCacheManager()->GetCacheIterator(this->VariableName.c_str()); if(!it.IsAtEnd()) diff --git a/Source/cmFindBase.h b/Source/cmFindBase.h index b055b4ff3..31742dd0f 100644 --- a/Source/cmFindBase.h +++ b/Source/cmFindBase.h @@ -35,6 +35,10 @@ public: */ virtual bool ParseArguments(std::vector const& args); cmTypeMacro(cmFindBase, cmCommand); + + virtual const char* GetFullDocumentation() + {return this->GenericDocumentation.c_str();} + protected: void PrintFindStuff(); void ExpandPaths(std::vector userPaths); @@ -48,6 +52,7 @@ protected: // if it has documentation in the cache bool CheckForVariableInCache(); + cmStdString GenericDocumentation; // use by command during find cmStdString VariableDocumentation; cmStdString VariableName; diff --git a/Source/cmFindFileCommand.cxx b/Source/cmFindFileCommand.cxx index daf02dd2f..b2682979c 100644 --- a/Source/cmFindFileCommand.cxx +++ b/Source/cmFindFileCommand.cxx @@ -15,83 +15,15 @@ =========================================================================*/ #include "cmFindFileCommand.h" -#include "cmCacheManager.h" -#include "cmGlob.h" -#include - +#include "cmSystemTools.h" -// cmFindFileCommand -bool cmFindFileCommand::InitialPass(std::vector const& argsIn) +cmFindFileCommand::cmFindFileCommand() { - if(argsIn.size() < 2) - { - this->SetError("called with incorrect number of arguments"); - return false; - } - std::string helpString = "Where can the "; - helpString += argsIn[1] + " file be found"; - size_t size = argsIn.size(); - std::vector args; - for(unsigned int j = 0; j < size; ++j) - { - if(argsIn[j] != "DOC") - { - args.push_back(argsIn[j]); - } - else - { - if(j+1 < size) - { - helpString = argsIn[j+1]; - } - break; - } - } - - std::vector::const_iterator i = args.begin(); - // Use the first argument as the name of something to be defined - const char* define = (*i).c_str(); - i++; // move iterator to next arg - // Now check and see if the value has been stored in the cache - // already, if so use that value and don't look for the program - const char* cacheValue - = m_Makefile->GetDefinition(define); - if(cacheValue && !cmSystemTools::IsNOTFOUND(cacheValue)) - { - return true; - } - - // The location is not in the cache. Create a search path. - std::vector path; - std::vector callPaths; - for (unsigned int j = 2; j < args.size(); j++) - { - // Glob the entry in case of wildcards. - cmSystemTools::GlobDirs(args[j].c_str(), callPaths); - } - m_Makefile->GetLibrarySearchPath(callPaths, path); - - // Use the search path to find the file. - for(unsigned int k=0; k < path.size(); k++) - { - std::string tryPath = path[k]; - tryPath += "/"; - tryPath += *i; - if(cmSystemTools::FileExists(tryPath.c_str())) - { - // Save the value in the cache - m_Makefile->AddCacheDefinition(define, - tryPath.c_str(), - helpString.c_str(), - cmCacheManager::FILEPATH); - return true; - } - } - std::string s = args[0] + "-NOTFOUND"; - m_Makefile->AddCacheDefinition(args[0].c_str(), - s.c_str(), - helpString.c_str(), - cmCacheManager::FILEPATH); - return true; + this->IncludeFileInPath = true; + cmSystemTools::ReplaceString(this->GenericDocumentation, + "FIND_PATH", "FIND_FILE"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "directory containing the named file", "full path to named file"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "file in a directory", "full path to a file"); } - diff --git a/Source/cmFindFileCommand.h b/Source/cmFindFileCommand.h index 1d4a600f5..d65a51ea2 100644 --- a/Source/cmFindFileCommand.h +++ b/Source/cmFindFileCommand.h @@ -17,7 +17,7 @@ #ifndef cmFindFileCommand_h #define cmFindFileCommand_h -#include "cmCommand.h" +#include "cmFindPathCommand.h" /** \class cmFindFileCommand * \brief Define a command to search for an executable program. @@ -27,9 +27,10 @@ * in the current path (e.g., PATH environment variable) for * an executable that matches one of the supplied names. */ -class cmFindFileCommand : public cmCommand +class cmFindFileCommand : public cmFindPathCommand { public: + cmFindFileCommand(); /** * This is a virtual constructor for the command. */ @@ -37,21 +38,6 @@ public: { return new cmFindFileCommand; } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - virtual bool InitialPass(std::vector const& args); - - /** - * This determines if the command is invoked when in script mode. - */ - virtual bool IsScriptable() { return true; } - - /** - * The name of the command as specified in CMakeList.txt. - */ virtual const char* GetName() { return "FIND_FILE";} /** @@ -62,24 +48,7 @@ public: return "Find the full path to a file."; } - /** - * More documentation. - */ - virtual const char* GetFullDocumentation() - { - return - " FIND_FILE( fileName path1 [path2 ...]\n" - " [DOC \"docstring\"])\n" - "Find the full path to a file named by fileName. Paths " - "are searched in the order specified. A cache entry named by " - " is created to store the result. If the file is not " - "found, the result will be -NOTFOUND. If DOC is specified " - "then the next argument is treated as a documentation string for " - "the cache entry . Note that since executables can have " - "different extensions on different platforms, FIND_PROGRAM " - "should be used instead of FIND_FILE when looking for them."; - } - cmTypeMacro(cmFindFileCommand, cmCommand); + cmTypeMacro(cmFindFileCommand, cmFindPathCommand); }; diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx index 87282732f..1e919dcc3 100644 --- a/Source/cmFindLibraryCommand.cxx +++ b/Source/cmFindLibraryCommand.cxx @@ -17,129 +17,182 @@ #include "cmFindLibraryCommand.h" #include "cmCacheManager.h" +cmFindLibraryCommand::cmFindLibraryCommand() +{ + cmSystemTools::ReplaceString(this->GenericDocumentation, + "FIND_XXX", "FIND_LIBRARY"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "CMAKE_XXX_PATH", "CMAKE_LIBRARY_PATH"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "XXX_SYSTEM", "LIB"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "CMAKE_SYSTEM_XXX_PATH", "CMAKE_SYSTEM_LIBRARY_PATH"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "SEARCH_XXX_DESC", "library"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "SEARCH_XXX", "library"); + this->GenericDocumentation += + "\n" + "If the library found is a framework, then VAR will be set to the " + "the full path to the framework /A.framework. " + "When a full path to a framework is used as a library, " + "CMake will use a -framework A, and a -F to " + "link the framework to the target. "; +} + // cmFindLibraryCommand bool cmFindLibraryCommand::InitialPass(std::vector const& argsIn) { - if(argsIn.size() < 2) + this->VariableDocumentation = "Path to a library."; + this->CMakePathName = "LIBRARY"; + if(!this->ParseArguments(argsIn)) { - this->SetError("called with incorrect number of arguments"); return false; - } - std::string helpString; - size_t size = argsIn.size(); - std::vector args; - for(unsigned int j = 0; j < size; ++j) - { - if(argsIn[j] != "DOC") - { - args.push_back(argsIn[j]); - } - else - { - if(j+1 < size) - { - helpString = argsIn[j+1]; - } - break; - } } - - std::vector path; - std::vector names; - bool foundName = false; - bool foundPath = false; - bool doingNames = true; - for (unsigned int j = 1; j < args.size(); ++j) + if(this->AlreadyInCache) { - if(args[j] == "NAMES") - { - doingNames = true; - foundName = true; - } - else if (args[j] == "PATHS") - { - doingNames = false; - foundPath = true; - } - else - { - if(doingNames) - { - names.push_back(args[j]); - } - else - { - cmSystemTools::ExpandRegistryValues(args[j]); - // Glob the entry in case of wildcards. - cmSystemTools::GlobDirs(args[j].c_str(), path); - } - } - } - // old style name path1 path2 path3 - if(!foundPath && !foundName) - { - names.clear(); - path.clear(); - names.push_back(args[1]); - // add any user specified paths - for (unsigned int j = 2; j < args.size(); j++) - { - // expand variables - std::string exp = args[j]; - cmSystemTools::ExpandRegistryValues(exp); - - // Glob the entry in case of wildcards. - cmSystemTools::GlobDirs(exp.c_str(), path); - } - } - if(helpString.size() == 0) - { - helpString = "Where can "; - if (names.size() == 0) - { - helpString += "the (unknown) library be found"; - } - else if (names.size() == 1) - { - helpString += "the " + names[0] + " library be found"; - } - else - { - helpString += "one of the " + names[0]; - for (unsigned int j = 1; j < names.size() - 1; ++j) - { - helpString += ", " + names[j]; - } - helpString += " or " + names[names.size() - 1] + " libraries be found"; - } - } - - const char* cacheValue - = m_Makefile->GetDefinition(args[0].c_str()); - if(cacheValue && !cmSystemTools::IsNOTFOUND(cacheValue)) - { return true; } - + // add special 64 bit paths if this is a 64 bit compile. + this->AddLib64Paths(); std::string library; - for(std::vector::iterator i = names.begin(); - i != names.end() ; ++i) + for(std::vector::iterator i = this->Names.begin(); + i != this->Names.end() ; ++i) { - library = m_Makefile->FindLibrary(i->c_str(), path); + library = this->FindLibrary(i->c_str()); if(library != "") { - m_Makefile->AddCacheDefinition(args[0].c_str(), + m_Makefile->AddCacheDefinition(this->VariableName.c_str(), library.c_str(), - helpString.c_str(), + this->VariableDocumentation.c_str(), cmCacheManager::FILEPATH); return true; } } - std::string s = args[0] + "-NOTFOUND"; - m_Makefile->AddCacheDefinition(args[0].c_str(), - s.c_str(), - helpString.c_str(), + std::string notfound = this->VariableName + "-NOTFOUND"; + m_Makefile->AddCacheDefinition(this->VariableName.c_str(), + notfound.c_str(), + this->VariableDocumentation.c_str(), cmCacheManager::FILEPATH); return true; } + +void cmFindLibraryCommand::AddLib64Paths() +{ + if(!m_Makefile->GetLocalGenerator()->GetGlobalGenerator()->GetLanguageEnabled("C")) + { + return; + } + std::string voidsize = m_Makefile->GetRequiredDefinition("CMAKE_SIZEOF_VOID_P"); + int size = atoi(voidsize.c_str()); + std::vector path64; + if(size != 8) + { + return; + } + bool found64 = false; + for(std::vector::iterator i = this->SearchPaths.begin(); + i != this->SearchPaths.end(); ++i) + { + std::string s = *i; + std::string s2 = *i; + cmSystemTools::ReplaceString(s, "lib/", "lib64/"); + // try to replace lib with lib64 and see if it is there, + // then prepend it to the path + if((s != *i) && cmSystemTools::FileIsDirectory(s.c_str())) + { + path64.push_back(s); + found64 = true; + } + // now just add a 64 to the path name and if it is there, + // add it to the path + s2 += "64"; + if(cmSystemTools::FileIsDirectory(s2.c_str())) + { + found64 = true; + path64.push_back(s2); + } + // now add the original unchanged path + if(cmSystemTools::FileIsDirectory(i->c_str())) + { + path64.push_back(*i); + } + } + // now replace the SearchPaths with the 64 bit converted path + // if any 64 bit paths were discovered + if(found64) + { + this->SearchPaths = path64; + } +} + +std::string cmFindLibraryCommand::FindLibrary(const char* name) +{ + bool supportFrameworks = false; + bool onlyFrameworks = false; + std::string ff = m_Makefile->GetSafeDefinition("CMAKE_FIND_FRAMEWORK"); + if(ff == "FIRST" || ff == "LAST") + { + supportFrameworks = true; + } + if(ff == "ONLY") + { + onlyFrameworks = true; + supportFrameworks = true; + } + + const char* prefixes_list = + m_Makefile->GetRequiredDefinition("CMAKE_FIND_LIBRARY_PREFIXES"); + const char* suffixes_list = + m_Makefile->GetRequiredDefinition("CMAKE_FIND_LIBRARY_SUFFIXES"); + std::vector prefixes; + std::vector suffixes; + cmSystemTools::ExpandListArgument(prefixes_list, prefixes, true); + cmSystemTools::ExpandListArgument(suffixes_list, suffixes, true); + std::string tryPath; + for(std::vector::const_iterator p = this->SearchPaths.begin(); + p != this->SearchPaths.end(); ++p) + { + if(supportFrameworks) + { + tryPath = *p; + tryPath += "/"; + tryPath += name; + tryPath += ".framework"; + if(cmSystemTools::FileExists(tryPath.c_str()) + && cmSystemTools::FileIsDirectory(tryPath.c_str())) + { + tryPath = cmSystemTools::CollapseFullPath(tryPath.c_str()); + cmSystemTools::ConvertToUnixSlashes(tryPath); + return tryPath; + } + } + if(!onlyFrameworks) + { + // Try various library naming conventions. + for(std::vector::iterator prefix = prefixes.begin(); + prefix != prefixes.end(); ++prefix) + { + for(std::vector::iterator suffix = suffixes.begin(); + suffix != suffixes.end(); ++suffix) + { + tryPath = *p; + tryPath += "/"; + tryPath += *prefix; + tryPath += name; + tryPath += *suffix; + if(cmSystemTools::FileExists(tryPath.c_str()) + && !cmSystemTools::FileIsDirectory(tryPath.c_str())) + { + tryPath = cmSystemTools::CollapseFullPath(tryPath.c_str()); + cmSystemTools::ConvertToUnixSlashes(tryPath); + return tryPath; + } + } + } + } + } + // Couldn't find the library. + return ""; +} diff --git a/Source/cmFindLibraryCommand.h b/Source/cmFindLibraryCommand.h index 885405dd2..52f4a45e1 100644 --- a/Source/cmFindLibraryCommand.h +++ b/Source/cmFindLibraryCommand.h @@ -17,7 +17,7 @@ #ifndef cmFindLibraryCommand_h #define cmFindLibraryCommand_h -#include "cmCommand.h" +#include "cmFindBase.h" /** \class cmFindLibraryCommand @@ -27,9 +27,10 @@ * that specifies a library. The command searches for a given * file in a list of directories. */ -class cmFindLibraryCommand : public cmCommand +class cmFindLibraryCommand : public cmFindBase { public: + cmFindLibraryCommand(); /** * This is a virtual constructor for the command. */ @@ -61,34 +62,11 @@ public: { return "Find a library."; } + cmTypeMacro(cmFindLibraryCommand, cmFindBase); - /** - * More documentation. - */ - virtual const char* GetFullDocumentation() - { - return - " FIND_LIBRARY( NAMES name1 [name2 ...]\n" - " [PATHS path1 path2 ...]\n" - " [DOC \"docstring\"])\n" - "Find a library named by one of the names given after the NAMES " - "argument. A cache entry named by is created " - "to store the result. If the library is not found, the result " - "will be -NOTFOUND. If DOC is specified then the next " - "argument is treated as a documentation string for the cache " - "entry .\n" - " FIND_LIBRARY(VAR libraryName [path1 path2 ...])\n" - "Find a library with the given name by searching in the specified " - "paths. This is a short-hand signature for the command that is " - "sufficient in many cases. " - "The search proceeds first in paths listed in the CMAKE_LIBRARY_PATH " - "CMake variable (which is generally set by the user on the command line), " - "then in paths listed in the CMAKE_LIBRARY_PATH environment variable, " - "then in paths given to the PATHS option of the command, " - "and finally in paths listed in the PATH environment variable."; - } - - cmTypeMacro(cmFindLibraryCommand, cmCommand); +protected: + void AddLib64Paths();\ + std::string FindLibrary(const char* name); }; diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx index 83d5faa63..6ece32a75 100644 --- a/Source/cmFindPathCommand.cxx +++ b/Source/cmFindPathCommand.cxx @@ -17,123 +17,123 @@ #include "cmFindPathCommand.h" #include "cmCacheManager.h" + +cmFindPathCommand::cmFindPathCommand() +{ + this->IncludeFileInPath = false; + cmSystemTools::ReplaceString(this->GenericDocumentation, + "FIND_XXX", "FIND_PATH"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "CMAKE_XXX_PATH", "CMAKE_INCLUDE_PATH"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "XXX_SYSTEM", "INCLUDE"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "CMAKE_SYSTEM_XXX_PATH", "CMAKE_SYSTEM_INCLUDE_PATH"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "SEARCH_XXX_DESC", "directory containing the named file"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "SEARCH_XXX", "file in a directory"); + this->ExtraDocAdded = false; +} + +const char* cmFindPathCommand::GetFullDocumentation() +{ + if(!this->ExtraDocAdded && !this->IncludeFileInPath) + { + this->GenericDocumentation += + "\n" + "When searching for frameworks, if the file is specified as " + "A/b.h, then the framework search will look for A.framework/Headers/b.h. " + "If that is found the path will be set to the path to the framework. " + "CMake will convert this to the correct -F option to include the file. "; + this->ExtraDocAdded = true; + } + return this->GenericDocumentation.c_str(); +} + // cmFindPathCommand bool cmFindPathCommand::InitialPass(std::vector const& argsIn) { - if(argsIn.size() < 2) + this->VariableDocumentation = "Path to a file."; + this->CMakePathName = "INCLUDE"; + if(!this->ParseArguments(argsIn)) { - this->SetError("called with incorrect number of arguments"); return false; } - - // Now check and see if the value has been stored in the cache - // already, if so use that value and don't look for the program - std::string helpString = "What is the path where the file "; - helpString += argsIn[1] + " can be found"; - std::vector args; - size_t size = argsIn.size(); - for(unsigned int j = 0; j < size; ++j) + if(this->AlreadyInCache) { - if(argsIn[j] != "DOC") - { - args.push_back(argsIn[j]); - } - else - { - if(j+1 < size) - { - helpString = argsIn[j+1]; - } - break; - } - } - - const char* cacheValue - = m_Makefile->GetDefinition(args[0].c_str()); - if(cacheValue && !cmSystemTools::IsNOTFOUND(cacheValue)) - { return true; } - if(cacheValue) + std::string ff = m_Makefile->GetSafeDefinition("CMAKE_FIND_FRAMEWORK"); + bool supportFrameworks = true; + if( ff.size() == 0 || ff == "NEVER" ) { - cmCacheManager::CacheIterator it = - m_Makefile->GetCacheManager()->GetCacheIterator(args[0].c_str()); - if(!it.IsAtEnd()) - { - const char* hs = it.GetProperty("HELPSTRING"); - helpString = hs?hs:"(none)"; - } + supportFrameworks = false; } - - // Construct a search path. - std::vector path; - std::vector callPaths; - for (unsigned int j = 2; j < args.size(); j++) - { - // expand variables - std::string exp = args[j]; - cmSystemTools::ExpandRegistryValues(exp); - - // Glob the entry in case of wildcards. - cmSystemTools::GlobDirs(exp.c_str(), callPaths); - } - m_Makefile->GetIncludeSearchPath(callPaths, path); - + std::string framework; // Use the search path to find the file. unsigned int k; - for(k=0; k < path.size(); k++) + std::string result; + for(k=0; k < this->SearchPaths.size(); k++) { - std::string tryPath = path[k]; - tryPath += "/"; - tryPath += args[1]; - if(cmSystemTools::FileExists(tryPath.c_str())) + for(unsigned int j =0; j < this->Names.size(); ++j) { - path[k] = cmSystemTools::CollapseFullPath(path[k].c_str()); - if(path[k].size() && path[k][path[k].size()-1] == '/') + // if frameworks are supported try to find the header in a framework + std::string tryPath; + if(supportFrameworks) { - path[k] = path[k].substr(0, path[k].size()-1); + tryPath = this->FindHeaderInFramework(this->Names[j], + this->SearchPaths[k]); + if(tryPath.size()) + { + result = tryPath; + } + } + if(result.size() == 0) + { + tryPath = this->SearchPaths[k]; + tryPath += "/"; + tryPath += this->Names[j]; + if(cmSystemTools::FileExists(tryPath.c_str())) + { + if(this->IncludeFileInPath) + { + result = tryPath; + } + else + { + result = this->SearchPaths[k]; + } + } + } + if(result.size() != 0) + { + m_Makefile->AddCacheDefinition(this->VariableName.c_str(), + result.c_str(), + this->VariableDocumentation.c_str(), + (this->IncludeFileInPath) ? + cmCacheManager::FILEPATH :cmCacheManager::PATH); + return true; } - m_Makefile->AddCacheDefinition(args[0].c_str(), - path[k].c_str(), - helpString.c_str(), - cmCacheManager::PATH); - return true; } } -#if defined (__APPLE__) - cmStdString fpath = this->FindHeaderInFrameworks(path, args[0].c_str(), args[1].c_str()); - if(fpath.size()) - { - m_Makefile->AddCacheDefinition(args[0].c_str(), - fpath.c_str(), - helpString.c_str(), - cmCacheManager::FILEPATH); - return true; - } -#endif - - m_Makefile->AddCacheDefinition(args[0].c_str(), - (args[0] + "-NOTFOUND").c_str(), - helpString.c_str(), - cmCacheManager::PATH); + m_Makefile->AddCacheDefinition(this->VariableName.c_str(), + (this->VariableName + "-NOTFOUND").c_str(), + this->VariableDocumentation.c_str(), + (this->IncludeFileInPath) ? + cmCacheManager::FILEPATH :cmCacheManager::PATH); return true; } -cmStdString cmFindPathCommand::FindHeaderInFrameworks( - std::vector path, - const char* defineVar, - const char* file) +std::string cmFindPathCommand::FindHeaderInFramework(std::string& file, + std::string& dir) { - (void)defineVar; - -#ifndef __APPLE__ - (void)path; - (void)file; - return cmStdString(""); -#else cmStdString fileName = file; cmStdString frameWorkName; cmStdString::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; @@ -145,18 +145,10 @@ cmStdString cmFindPathCommand::FindHeaderInFrameworks( { fileName = file; frameWorkName = ""; - } - } - path.push_back("~/Library/Frameworks"); - path.push_back("/Library/Frameworks"); - path.push_back("/Network/Library/Frameworks"); - path.push_back("/System/Library/Frameworks"); - for( std::vector::iterator i = path.begin(); - i != path.end(); ++i) - { + } if(frameWorkName.size()) { - std::string fpath = *i; + std::string fpath = dir; fpath += "/"; fpath += frameWorkName; fpath += ".framework"; @@ -164,11 +156,17 @@ cmStdString cmFindPathCommand::FindHeaderInFrameworks( intPath += "/Headers/"; intPath += fileName; if(cmSystemTools::FileExists(intPath.c_str())) - { + { + if(this->IncludeFileInPath) + { + return intPath; + } return fpath; } } - cmStdString glob = *i; + // if it is not found yet or not a framework header, then do a glob search + // for all files in dir/*/Headers/ + cmStdString glob = dir; glob += "/*/Headers/"; glob += file; cmGlob globIt; @@ -177,11 +175,14 @@ cmStdString cmFindPathCommand::FindHeaderInFrameworks( if(files.size()) { cmStdString fheader = cmSystemTools::CollapseFullPath(files[0].c_str()); + if(this->IncludeFileInPath) + { + return fheader; + } fheader = cmSystemTools::GetFilenamePath(fheader); return fheader; } } - return cmStdString(""); -#endif - + return ""; } + diff --git a/Source/cmFindPathCommand.h b/Source/cmFindPathCommand.h index 3c44221a8..5e9c83b1b 100644 --- a/Source/cmFindPathCommand.h +++ b/Source/cmFindPathCommand.h @@ -17,7 +17,7 @@ #ifndef cmFindPathCommand_h #define cmFindPathCommand_h -#include "cmCommand.h" +#include "cmFindBase.h" /** \class cmFindPathCommand @@ -27,9 +27,10 @@ * that specifies a library. The command searches for a given * file in a list of directories. */ -class cmFindPathCommand : public cmCommand +class cmFindPathCommand : public cmFindBase { public: + cmFindPathCommand(); /** * This is a virtual constructor for the command. */ @@ -61,31 +62,13 @@ public: { return "Find the directory containing a file."; } - - /** - * More documentation. - */ - virtual const char* GetFullDocumentation() - { - return - " FIND_PATH( fileName path1 [path2 ...]\n" - " [DOC \"docstring\"])\n" - "Find the directory containing a file named by fileName. " - "A cache entry named by " - " is created to store the result. If the file is not " - "found, the result will be -NOTFOUND. If DOC is specified " - "then the next argument is treated as a documentation string for " - "the cache entry . " - "The search proceeds first in paths listed in the CMAKE_INCLUDE_PATH " - "CMake variable (which is generally set by the user on the command line), " - "then in paths listed in the CMAKE_INCLUDE_PATH environment variable, " - "then in paths given to the command, and finally in paths listed in the " - "PATH environment variable."; - } - cmStdString FindHeaderInFrameworks( std::vector path, - const char* var, const char* file); - cmTypeMacro(cmFindPathCommand, cmCommand); + std::string FindHeaderInFramework( std::string& file, + std::string& dir); + virtual const char* GetFullDocumentation(); + cmTypeMacro(cmFindPathCommand, cmFindBase); + bool IncludeFileInPath; + bool ExtraDocAdded; }; diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx index ad9a4d880..436d590ff 100644 --- a/Source/cmFindProgramCommand.cxx +++ b/Source/cmFindProgramCommand.cxx @@ -18,130 +18,51 @@ #include "cmCacheManager.h" #include +cmFindProgramCommand::cmFindProgramCommand() +{ + cmSystemTools::ReplaceString(this->GenericDocumentation, + "FIND_XXX", "FIND_PROGRAM"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "CMAKE_XXX_PATH", "CMAKE_PROGRAM_PATH"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "XXX_SYSTEM", ""); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "CMAKE_SYSTEM_XXX_PATH", "CMAKE_SYSTEM_PROGRAM_PATH"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "SEARCH_XXX_DESC", "program"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "SEARCH_XXX", "program"); +} // cmFindProgramCommand bool cmFindProgramCommand::InitialPass(std::vector const& argsIn) { - if(argsIn.size() < 2 ) + this->VariableDocumentation = "Path to a program."; + this->CMakePathName = "PROGRAM"; + // call cmFindBase::ParseArguments + if(!this->ParseArguments(argsIn)) { - this->SetError("called with incorrect number of arguments"); return false; } - std::string doc = "Path to a program."; - size_t size = argsIn.size(); - std::vector args; - for(unsigned int j = 0; j < size; ++j) - { - if(argsIn[j] != "DOC") - { - args.push_back(argsIn[j]); - } - else - { - if(j+1 < size) - { - doc = argsIn[j+1]; - } - break; - } - } - - std::vector::iterator i = args.begin(); - // Use the first argument as the name of something to be defined - const char* define = (*i).c_str(); - i++; // move iterator to next arg - // Now check and see if the value has been stored in the cache - // already, if so use that value and don't look for the program - const char* cacheValue - = m_Makefile->GetDefinition(define); - if(cacheValue && !cmSystemTools::IsNOTFOUND(cacheValue)) + if(this->AlreadyInCache) { return true; } - if(cacheValue) + std::string result = cmSystemTools::FindProgram(this->Names, + this->SearchPaths); + if(result != "") { - cmCacheManager::CacheIterator it = - m_Makefile->GetCacheManager()->GetCacheIterator(args[0].c_str()); - if(!it.IsAtEnd()) - { - const char* hs = it.GetProperty("HELPSTRING"); - doc = hs?hs:"(none)"; - } + // Save the value in the cache + m_Makefile->AddCacheDefinition(this->VariableName.c_str(), + result.c_str(), + this->VariableDocumentation.c_str(), + cmCacheManager::FILEPATH); + + return true; } - std::vector path; - std::vector names; - bool foundName = false; - bool foundPath = false; - bool doingNames = true; - bool no_system_path = false; - for (unsigned int j = 1; j < args.size(); ++j) - { - if(args[j] == "NAMES") - { - doingNames = true; - foundName = true; - } - else if (args[j] == "PATHS") - { - doingNames = false; - foundPath = true; - } - else if (args[j] == "NO_SYSTEM_PATH") - { - no_system_path = true; - } - else - { - if(doingNames) - { - names.push_back(args[j]); - } - else - { - cmSystemTools::ExpandRegistryValues(args[j]); - // Glob the entry in case of wildcards. - cmSystemTools::GlobDirs(args[j].c_str(), path); - } - } - } - // if it is not in the cache, then search the system path - // add any user specified paths - if(!foundPath && !foundName) - { - path.clear(); - names.clear(); - names.push_back(args[1]); - for (unsigned int j = 2; j < args.size(); j++) - { - // expand variables - std::string exp = args[j]; - cmSystemTools::ExpandRegistryValues(exp); - - // Glob the entry in case of wildcards. - cmSystemTools::GlobDirs(exp.c_str(), path); - } - } - for(std::vector::iterator it = names.begin(); - it != names.end() ; ++it) - { - // Try to find the program. - std::string result = cmSystemTools::FindProgram(it->c_str(), - path, - no_system_path); - if(result != "") - { - // Save the value in the cache - m_Makefile->AddCacheDefinition(define, - result.c_str(), - doc.c_str(), - cmCacheManager::FILEPATH); - - return true; - } - } - m_Makefile->AddCacheDefinition(args[0].c_str(), - (args[0] + "-NOTFOUND").c_str(), - doc.c_str(), + m_Makefile->AddCacheDefinition(this->VariableName.c_str(), + (this->VariableName + "-NOTFOUND").c_str(), + this->VariableDocumentation.c_str(), cmCacheManager::FILEPATH); return true; } diff --git a/Source/cmFindProgramCommand.h b/Source/cmFindProgramCommand.h index dd2aa1013..af5c6de88 100644 --- a/Source/cmFindProgramCommand.h +++ b/Source/cmFindProgramCommand.h @@ -17,7 +17,7 @@ #ifndef cmFindProgramCommand_h #define cmFindProgramCommand_h -#include "cmCommand.h" +#include "cmFindBase.h" /** \class cmFindProgramCommand * \brief Define a command to search for an executable program. @@ -27,9 +27,10 @@ * in the current path (e.g., PATH environment variable) for * an executable that matches one of the supplied names. */ -class cmFindProgramCommand : public cmCommand +class cmFindProgramCommand : public cmFindBase { public: + cmFindProgramCommand(); /** * This is a virtual constructor for the command. */ @@ -62,32 +63,7 @@ public: return "Find an executable program."; } - /** - * More documentation. - */ - virtual const char* GetFullDocumentation() - { - return - " FIND_PROGRAM( NAMES name1 [name2 ...]\n" - " [PATHS path1 path2 ...]\n" - " [NO_SYSTEM_PATH]\n" - " [DOC \"docstring\"])\n" - "Find an executable named by one of the names given after the NAMES " - "argument. Paths specified after the PATHS argument are searched " - "in the order specified. If the NO_SYSTEM_PATH argument is not " - "specified, the search continues with the system search path " - "specified by the PATH environment variable. A cache entry named " - "by is created to store the result. If the program is not " - "found, the result will be -NOTFOUND. If DOC is specified " - "then the next argument is treated as a documentation string for " - "the cache entry .\n" - " FIND_PROGRAM(VAR executableName [path1 path2 ...])\n" - "Find a program with the given name by searching in the specified " - "paths. This is a short-hand signature for the command that is " - "sufficient in many cases."; - } - - cmTypeMacro(cmFindProgramCommand, cmCommand); + cmTypeMacro(cmFindProgramCommand, cmFindBase); }; diff --git a/Source/kwsys/Registry.cxx b/Source/kwsys/Registry.cxx index 3c0be2674..414b06677 100644 --- a/Source/kwsys/Registry.cxx +++ b/Source/kwsys/Registry.cxx @@ -267,6 +267,7 @@ bool Registry::DeleteValue(const char *subkey, const char *key) if ( !this->Open(this->GetTopLevel(), subkey, Registry::READWRITE) ) { + std::cerr << "Failed to open\n"; return res; } open = true; diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index e30cc5198..abc3cd1e6 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -1923,21 +1923,35 @@ kwsys_stl::string SystemTools::FindProgram( { return ""; } + std::string ext = SystemTools::GetExecutableExtension(); + if(ext.size()) + { + unsigned int len = strlen(name); + if(len > ext.size()) + { + if(strcmp(name+(len-ext.size()), ext.c_str()) == 0) + { + ext = ""; // name already has Executable extension + } + } + } // See if the executable exists as written. if(SystemTools::FileExists(name) && !SystemTools::FileIsDirectory(name)) { return SystemTools::CollapseFullPath(name); } - kwsys_stl::string tryPath = name; - tryPath += SystemTools::GetExecutableExtension(); - if(SystemTools::FileExists(tryPath.c_str()) && - !SystemTools::FileIsDirectory(tryPath.c_str())) + if(ext.size()) { - return SystemTools::CollapseFullPath(tryPath.c_str()); + kwsys_stl::string tryPath = name; + tryPath += ext; + if(SystemTools::FileExists(tryPath.c_str()) && + !SystemTools::FileIsDirectory(tryPath.c_str())) + { + return SystemTools::CollapseFullPath(tryPath.c_str()); + } } kwsys_stl::vector path; - SystemTools::GetPath(path, "CMAKE_PROGRAM_PATH"); // Add the system search path to our path. if (!no_system_path) { @@ -1954,9 +1968,10 @@ kwsys_stl::string SystemTools::FindProgram( p != path.end(); ++p) { #ifdef _WIN32 + // Remove double quotes from the path on windows SystemTools::ReplaceString(*p, "\"", ""); #endif - tryPath = *p; + kwsys_stl::string tryPath = *p; tryPath += "/"; tryPath += name; if(SystemTools::FileExists(tryPath.c_str()) && @@ -1965,21 +1980,34 @@ kwsys_stl::string SystemTools::FindProgram( return SystemTools::CollapseFullPath(tryPath.c_str()); } #ifdef _WIN32 - tryPath += ".com"; + // on windows try .com before .exe + if(ext.size() == 0) + { + SystemTools::ReplaceString(tryPath, ".exe", ".com"); + SystemTools::ReplaceString(tryPath, ".EXE", ".com"); + } + else + { + tryPath += ".com"; + } if(SystemTools::FileExists(tryPath.c_str()) && !SystemTools::FileIsDirectory(tryPath.c_str())) { return SystemTools::CollapseFullPath(tryPath.c_str()); } - tryPath = *p; - tryPath += "/"; - tryPath += name; #endif - tryPath += SystemTools::GetExecutableExtension(); - if(SystemTools::FileExists(tryPath.c_str()) && - !SystemTools::FileIsDirectory(tryPath.c_str())) + // now try to add ext if it is different than name + if(ext.size()) { - return SystemTools::CollapseFullPath(tryPath.c_str()); + tryPath = *p; + tryPath += "/"; + tryPath += name; + tryPath += ext; + if(SystemTools::FileExists(tryPath.c_str()) && + !SystemTools::FileIsDirectory(tryPath.c_str())) + { + return SystemTools::CollapseFullPath(tryPath.c_str()); + } } }