ENH: Implement version support in the find_package command module mode. Version numbers provided to the command are converted to variable settings to tell the FindXXX.cmake module what version is requested. This addresses issue #1645.
This commit is contained in:
parent
9198a92af9
commit
f41b1e8e91
|
@ -18,6 +18,10 @@ XXX_FOUND Set to false, or undefined, if we haven't found, or don'
|
|||
XXX_RUNTIME_LIBRARY_DIRS Optionally, the runtime library search path for use when running an executable linked to shared libraries.
|
||||
The list should be used by user code to create the PATH on windows or LD_LIBRARY_PATH on unix.
|
||||
This should not be a cache entry.
|
||||
XXX_VERSION_STRING A human-readable string containing the version of the package found, if any.
|
||||
XXX_VERSION_MAJOR The major version of the package found, if any.
|
||||
XXX_VERSION_MINOR The minor version of the package found, if any.
|
||||
XXX_VERSION_PATCH The patch version of the package found, if any.
|
||||
|
||||
You do not have to provide all of the above variables. You should provide XXX_FOUND under most circumstances. If XXX is a library, then XXX_LIBRARIES, should also be defined, and XXX_INCLUDE_DIRS should usually be defined (I guess libm.a might be an exception)
|
||||
|
||||
|
@ -63,7 +67,19 @@ line.
|
|||
|
||||
A FindXXX.cmake module will typically be loaded by the command
|
||||
|
||||
FIND_PACKAGE(XXX [QUIET] [REQUIRED [components...]])
|
||||
FIND_PACKAGE(XXX [major[.minor[.patch]]]
|
||||
[QUIET] [REQUIRED [components...]])
|
||||
|
||||
If any version numbers are given to the command it will set the
|
||||
variable XXX_FIND_VERSION to contain the whole version. The variables
|
||||
XXX_FIND_VERSION_MAJOR, XXX_FIND_VERSION_MINOR, and
|
||||
XXX_FIND_VERSION_PATCH will be set to contain the corresponding
|
||||
portions of the version number. If the find module supports
|
||||
versioning it should locate a version of the package that is
|
||||
compatible with the version requested. If a compatible version of the
|
||||
package cannot be found the module should not report success. The
|
||||
version of the package found should be stored in the version variables
|
||||
named above.
|
||||
|
||||
If the QUIET option is given to the command it will set the variable
|
||||
XXX_FIND_QUIETLY to true before loading the FindXXX.cmake module. If
|
||||
|
|
|
@ -63,8 +63,12 @@ cmFindPackageCommand::cmFindPackageCommand()
|
|||
this->NoBuilds = false;
|
||||
this->NoModule = false;
|
||||
this->DebugMode = false;
|
||||
this->VersionMajor = 0;
|
||||
this->VersionMinor = 0;
|
||||
this->VersionPatch = 0;
|
||||
this->VersionCount = 0;
|
||||
this->CommandDocumentation =
|
||||
" find_package(<package> [major.minor] [QUIET] [NO_MODULE]\n"
|
||||
" find_package(<package> [major[.minor[.patch]]] [QUIET] [NO_MODULE]\n"
|
||||
" [[REQUIRED|COMPONENTS] [components...]]\n"
|
||||
" [NAMES name1 [name2 ...]]\n"
|
||||
" [CONFIGS config1 [config2 ...]]\n"
|
||||
|
@ -84,13 +88,15 @@ cmFindPackageCommand::cmFindPackageCommand()
|
|||
"can be used when <package>_FOUND is true are package-specific. "
|
||||
"A package-specific list of components may be listed after the "
|
||||
"REQUIRED option, or after the COMPONENTS option if no REQUIRED "
|
||||
"option is given. The \"major.minor\" version argument is currently "
|
||||
"a placeholder for future use and is ignored. "
|
||||
"option is given. The \"[major[.minor[.patch]]]\" version argument "
|
||||
"specifies a desired version with which the package found should be "
|
||||
"compatible. Version support is currently provided only on a "
|
||||
"package-by-package basis and is not enforced by the command. "
|
||||
"The command has two modes by which it searches for packages: "
|
||||
"\"Module\" mode and \"Config\" mode."
|
||||
"\n"
|
||||
"Module mode has a reduced signature:\n"
|
||||
" find_package(<package> [major.minor] [QUIET]\n"
|
||||
" find_package(<package> [major[.minor[.patch]]] [QUIET]\n"
|
||||
" [[REQUIRED|COMPONENTS] [components...]])\n"
|
||||
"CMake searches for a file called \"Find<package>.cmake\" in "
|
||||
"the CMAKE_MODULE_PATH followed by the CMake installation. "
|
||||
|
@ -104,6 +110,7 @@ cmFindPackageCommand::cmFindPackageCommand()
|
|||
"Config mode attempts to locate a configuration file provided by the "
|
||||
"package to be found. A cache entry called <package>_DIR is created to "
|
||||
"hold the directory containing the file. "
|
||||
"Currently versioning is not implemented by Config mode. "
|
||||
"By default the command searches for a package with the name <package>. "
|
||||
"If the NAMES option is given the names following it are used instead "
|
||||
"of <package>. "
|
||||
|
@ -338,6 +345,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
|
|||
else if(!haveVersion && version.find(args[i].c_str()))
|
||||
{
|
||||
haveVersion = true;
|
||||
this->Version = args[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -348,6 +356,24 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
|
|||
}
|
||||
}
|
||||
|
||||
if(!this->Version.empty())
|
||||
{
|
||||
// Try to parse the version number and store the results that were
|
||||
// successfully parsed.
|
||||
unsigned int parsed_major;
|
||||
unsigned int parsed_minor;
|
||||
unsigned int parsed_patch;
|
||||
this->VersionCount = sscanf(this->Version.c_str(), "%u.%u.%u",
|
||||
&parsed_major, &parsed_minor, &parsed_patch);
|
||||
switch(this->VersionCount)
|
||||
{
|
||||
case 3: this->VersionPatch = parsed_patch; // no break!
|
||||
case 2: this->VersionMinor = parsed_minor; // no break!
|
||||
case 1: this->VersionMajor = parsed_major; // no break!
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
// Store the list of components.
|
||||
std::string components_var = Name + "_FIND_COMPONENTS";
|
||||
this->Makefile->AddDefinition(components_var.c_str(), components.c_str());
|
||||
|
@ -428,6 +454,35 @@ bool cmFindPackageCommand::FindModule(bool& found)
|
|||
this->Makefile->AddDefinition(req.c_str(), "1");
|
||||
}
|
||||
|
||||
if(!this->Version.empty())
|
||||
{
|
||||
// Tell the module that is about to be read what version of the
|
||||
// package has been requested.
|
||||
std::string ver = this->Name;
|
||||
ver += "_FIND_VERSION";
|
||||
this->Makefile->AddDefinition(ver.c_str(), this->Version.c_str());
|
||||
char buf[64];
|
||||
switch(this->VersionCount)
|
||||
{
|
||||
case 3:
|
||||
{
|
||||
snprintf(buf, 64, "%u", this->VersionPatch);
|
||||
this->Makefile->AddDefinition((ver+"_PATCH").c_str(), buf);
|
||||
} // no break
|
||||
case 2:
|
||||
{
|
||||
snprintf(buf, 64, "%u", this->VersionMinor);
|
||||
this->Makefile->AddDefinition((ver+"_MINOR").c_str(), buf);
|
||||
} // no break
|
||||
case 1:
|
||||
{
|
||||
snprintf(buf, 64, "%u", this->VersionMajor);
|
||||
this->Makefile->AddDefinition((ver+"_MAJOR").c_str(), buf);
|
||||
} // no break
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
// Load the module we found.
|
||||
found = true;
|
||||
return this->ReadListFile(mfile.c_str());
|
||||
|
|
|
@ -94,6 +94,11 @@ private:
|
|||
std::string CommandDocumentation;
|
||||
cmStdString Name;
|
||||
cmStdString Variable;
|
||||
cmStdString Version;
|
||||
unsigned int VersionMajor;
|
||||
unsigned int VersionMinor;
|
||||
unsigned int VersionPatch;
|
||||
unsigned int VersionCount;
|
||||
cmStdString FileFound;
|
||||
bool Quiet;
|
||||
bool Required;
|
||||
|
|
|
@ -22,6 +22,13 @@ IF(NOT FOO_DIR)
|
|||
CMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}")
|
||||
ENDIF(NOT FOO_DIR)
|
||||
|
||||
LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
FIND_PACKAGE(VersionTestA 1)
|
||||
FIND_PACKAGE(VersionTestB 1.2)
|
||||
FIND_PACKAGE(VersionTestC 1.2.3)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
#SET(CMAKE_FIND_DEBUG_MODE 1)
|
||||
|
||||
# For purposes of the test wipe out previous find results.
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
IF(NOT "${VersionTestA_FIND_VERSION}" STREQUAL "1")
|
||||
MESSAGE(SEND_ERROR "VersionTestA_FIND_VERSION=${VersionTestA_FIND_VERSION} is not 1")
|
||||
ENDIF(NOT "${VersionTestA_FIND_VERSION}" STREQUAL "1")
|
||||
IF(NOT "${VersionTestA_FIND_VERSION_MAJOR}" STREQUAL "1")
|
||||
MESSAGE(SEND_ERROR "VersionTestA_FIND_VERSION_MAJOR=${VersionTestA_FIND_VERSION_MAJOR} is not 1")
|
||||
ENDIF(NOT "${VersionTestA_FIND_VERSION_MAJOR}" STREQUAL "1")
|
||||
IF(DEFINED VersionTestA_FIND_VERSION_MINOR)
|
||||
MESSAGE(SEND_ERROR "VersionTestA_FIND_VERSION_MINOR should not be defined")
|
||||
ENDIF(DEFINED VersionTestA_FIND_VERSION_MINOR)
|
||||
IF(DEFINED VersionTestA_FIND_VERSION_PATCH)
|
||||
MESSAGE(SEND_ERROR "VersionTestA_FIND_VERSION_PATCH should not be defined")
|
||||
ENDIF(DEFINED VersionTestA_FIND_VERSION_PATCH)
|
|
@ -0,0 +1,12 @@
|
|||
IF(NOT "${VersionTestB_FIND_VERSION}" STREQUAL "1.2")
|
||||
MESSAGE(SEND_ERROR "VersionTestB_FIND_VERSION=${VersionTestB_FIND_VERSION} is not 1.2")
|
||||
ENDIF(NOT "${VersionTestB_FIND_VERSION}" STREQUAL "1.2")
|
||||
IF(NOT "${VersionTestB_FIND_VERSION_MAJOR}" STREQUAL "1")
|
||||
MESSAGE(SEND_ERROR "VersionTestB_FIND_VERSION_MAJOR=${VersionTestB_FIND_VERSION_MAJOR} is not 1")
|
||||
ENDIF(NOT "${VersionTestB_FIND_VERSION_MAJOR}" STREQUAL "1")
|
||||
IF(NOT "${VersionTestB_FIND_VERSION_MINOR}" STREQUAL "2")
|
||||
MESSAGE(SEND_ERROR "VersionTestB_FIND_VERSION_MINOR=${VersionTestB_FIND_VERSION_MINOR} is not 2")
|
||||
ENDIF(NOT "${VersionTestB_FIND_VERSION_MINOR}" STREQUAL "2")
|
||||
IF(DEFINED VersionTestB_FIND_VERSION_PATCH)
|
||||
MESSAGE(SEND_ERROR "VersionTestB_FIND_VERSION_PATCH should not be defined")
|
||||
ENDIF(DEFINED VersionTestB_FIND_VERSION_PATCH)
|
|
@ -0,0 +1,12 @@
|
|||
IF(NOT "${VersionTestC_FIND_VERSION}" STREQUAL "1.2.3")
|
||||
MESSAGE(SEND_ERROR "VersionTestC_FIND_VERSION=${VersionTestC_FIND_VERSION} is not 1.2.3")
|
||||
ENDIF(NOT "${VersionTestC_FIND_VERSION}" STREQUAL "1.2.3")
|
||||
IF(NOT "${VersionTestC_FIND_VERSION_MAJOR}" STREQUAL "1")
|
||||
MESSAGE(SEND_ERROR "VersionTestC_FIND_VERSION_MAJOR=${VersionTestC_FIND_VERSION_MAJOR} is not 1")
|
||||
ENDIF(NOT "${VersionTestC_FIND_VERSION_MAJOR}" STREQUAL "1")
|
||||
IF(NOT "${VersionTestC_FIND_VERSION_MINOR}" STREQUAL "2")
|
||||
MESSAGE(SEND_ERROR "VersionTestC_FIND_VERSION_MINOR=${VersionTestC_FIND_VERSION_MINOR} is not 2")
|
||||
ENDIF(NOT "${VersionTestC_FIND_VERSION_MINOR}" STREQUAL "2")
|
||||
IF(NOT "${VersionTestC_FIND_VERSION_PATCH}" STREQUAL "3")
|
||||
MESSAGE(SEND_ERROR "VersionTestC_FIND_VERSION_PATCH=${VersionTestC_FIND_VERSION_PATCH} is not 3")
|
||||
ENDIF(NOT "${VersionTestC_FIND_VERSION_PATCH}" STREQUAL "3")
|
Loading…
Reference in New Issue