diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index a54bf7c4a..1de3982f4 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -15,6 +15,8 @@ cmFindBase::cmFindBase() { this->AlreadyInCache = false; this->AlreadyInCacheWithoutMetaInfo = false; + this->NamesPerDir = false; + this->NamesPerDirAllowed = false; } //---------------------------------------------------------------------------- @@ -213,6 +215,19 @@ bool cmFindBase::ParseArguments(std::vector const& argsIn) compatibility = false; newStyle = true; } + else if (args[j] == "NAMES_PER_DIR") + { + doing = DoingNone; + if(this->NamesPerDirAllowed) + { + this->NamesPerDir = true; + } + else + { + this->SetError("does not support NAMES_PER_DIR"); + return false; + } + } else if (args[j] == "NO_SYSTEM_PATH") { doing = DoingNone; diff --git a/Source/cmFindBase.h b/Source/cmFindBase.h index eac1885f3..84b03300c 100644 --- a/Source/cmFindBase.h +++ b/Source/cmFindBase.h @@ -49,6 +49,8 @@ protected: cmStdString VariableDocumentation; cmStdString VariableName; std::vector Names; + bool NamesPerDir; + bool NamesPerDirAllowed; // CMAKE_*_PATH CMAKE_SYSTEM_*_PATH FRAMEWORK|LIBRARY|INCLUDE|PROGRAM cmStdString EnvironmentPath; // LIB,INCLUDE diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx index d0f75197d..4af7e11bf 100644 --- a/Source/cmFindLibraryCommand.cxx +++ b/Source/cmFindLibraryCommand.cxx @@ -17,6 +17,7 @@ cmFindLibraryCommand::cmFindLibraryCommand() { this->EnvironmentPath = "LIB"; + this->NamesPerDirAllowed = true; } //---------------------------------------------------------------------------- @@ -44,6 +45,9 @@ void cmFindLibraryCommand::GenerateDocumentation() "SEARCH_XXX", "library"); cmSystemTools::ReplaceString(this->GenericDocumentation, "XXX_SUBDIR", "lib"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "NAMES name1 [name2 ...]", + "NAMES name1 [name2 ...] [NAMES_PER_DIR]"); cmSystemTools::ReplaceString( this->GenericDocumentation, "XXX_EXTRA_PREFIX_ENTRY", @@ -52,6 +56,12 @@ void cmFindLibraryCommand::GenerateDocumentation() "CMAKE_FIND_ROOT_PATH_MODE_XXX", "CMAKE_FIND_ROOT_PATH_MODE_LIBRARY"); this->GenericDocumentation += + "\n" + "When more than one value is given to the NAMES option this command " + "by default will consider one name at a time and search every directory " + "for it. " + "The NAMES_PER_DIR option tells this command to consider one directory " + "at a time and search for all names in it." "\n" "If the library found is a framework, then VAR will be set to " "the full path to the framework /A.framework. " @@ -464,6 +474,42 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path, //---------------------------------------------------------------------------- std::string cmFindLibraryCommand::FindNormalLibrary() +{ + if(this->NamesPerDir) + { + return this->FindNormalLibraryNamesPerDir(); + } + else + { + return this->FindNormalLibraryDirsPerName(); + } +} + +//---------------------------------------------------------------------------- +std::string cmFindLibraryCommand::FindNormalLibraryNamesPerDir() +{ + // Search for all names in each directory. + cmFindLibraryHelper helper(this->Makefile); + for(std::vector::const_iterator ni = this->Names.begin(); + ni != this->Names.end() ; ++ni) + { + helper.AddName(*ni); + } + // Search every directory. + for(std::vector::const_iterator + p = this->SearchPaths.begin(); p != this->SearchPaths.end(); ++p) + { + if(helper.CheckDirectory(*p)) + { + return helper.BestPath; + } + } + // Couldn't find the library. + return ""; +} + +//---------------------------------------------------------------------------- +std::string cmFindLibraryCommand::FindNormalLibraryDirsPerName() { // Search the entire path for each name. cmFindLibraryHelper helper(this->Makefile); @@ -491,6 +537,44 @@ std::string cmFindLibraryCommand::FindNormalLibrary() //---------------------------------------------------------------------------- std::string cmFindLibraryCommand::FindFrameworkLibrary() +{ + if(this->NamesPerDir) + { + return this->FindFrameworkLibraryNamesPerDir(); + } + else + { + return this->FindFrameworkLibraryDirsPerName(); + } +} + +//---------------------------------------------------------------------------- +std::string cmFindLibraryCommand::FindFrameworkLibraryNamesPerDir() +{ + std::string fwPath; + // Search for all names in each search path. + for(std::vector::const_iterator di = this->SearchPaths.begin(); + di != this->SearchPaths.end(); ++di) + { + for(std::vector::const_iterator ni = this->Names.begin(); + ni != this->Names.end() ; ++ni) + { + fwPath = *di; + fwPath += *ni; + fwPath += ".framework"; + if(cmSystemTools::FileIsDirectory(fwPath.c_str())) + { + return cmSystemTools::CollapseFullPath(fwPath.c_str()); + } + } + } + + // No framework found. + return ""; +} + +//---------------------------------------------------------------------------- +std::string cmFindLibraryCommand::FindFrameworkLibraryDirsPerName() { std::string fwPath; // Search for each name in all search paths. diff --git a/Source/cmFindLibraryCommand.h b/Source/cmFindLibraryCommand.h index 455348aaf..cd0fce8ad 100644 --- a/Source/cmFindLibraryCommand.h +++ b/Source/cmFindLibraryCommand.h @@ -70,7 +70,11 @@ protected: virtual void GenerateDocumentation(); private: std::string FindNormalLibrary(); + std::string FindNormalLibraryNamesPerDir(); + std::string FindNormalLibraryDirsPerName(); std::string FindFrameworkLibrary(); + std::string FindFrameworkLibraryNamesPerDir(); + std::string FindFrameworkLibraryDirsPerName(); }; diff --git a/Tests/CMakeOnly/find_library/A/libtestA.a b/Tests/CMakeOnly/find_library/A/libtestA.a new file mode 100644 index 000000000..e69de29bb diff --git a/Tests/CMakeOnly/find_library/B/libtestB.a b/Tests/CMakeOnly/find_library/B/libtestB.a new file mode 100644 index 000000000..e69de29bb diff --git a/Tests/CMakeOnly/find_library/CMakeLists.txt b/Tests/CMakeOnly/find_library/CMakeLists.txt index 9120f69ba..2d4ecaf14 100644 --- a/Tests/CMakeOnly/find_library/CMakeLists.txt +++ b/Tests/CMakeOnly/find_library/CMakeLists.txt @@ -59,3 +59,16 @@ foreach(lib64 ) test_find_library_subst(${lib64}) endforeach() + +test_find_library("" A/libtestA.a + NAMES testA testB + PATHS ${CMAKE_CURRENT_SOURCE_DIR}/A ${CMAKE_CURRENT_SOURCE_DIR}/B + ) +test_find_library("" B/libtestB.a + NAMES testB testA + PATHS ${CMAKE_CURRENT_SOURCE_DIR}/A ${CMAKE_CURRENT_SOURCE_DIR}/B + ) +test_find_library("" A/libtestA.a + NAMES testB testA NAMES_PER_DIR + PATHS ${CMAKE_CURRENT_SOURCE_DIR}/A ${CMAKE_CURRENT_SOURCE_DIR}/B + )