find_* commands: add control over Windows registry views

Fixes: #22775
This commit is contained in:
Marc Chevrier
2022-04-29 22:00:02 +02:00
parent 08941a9a40
commit 8d7e80cf3d
115 changed files with 1926 additions and 57 deletions
+13
View File
@@ -13,6 +13,7 @@ The general signature is:
name | |NAMES|
[HINTS [path | ENV var]... ]
[PATHS [path | ENV var]... ]
[REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[DOC "cache documentation string"]
[NO_CACHE]
@@ -51,6 +52,18 @@ Options include:
The ``ENV var`` sub-option reads paths from a system environment
variable.
.. versionchanged:: 3.24
On ``Windows`` platform, it is possible to include registry queries as part
of the directories. Such specifications will be ignored on all other
platforms.
.. include:: FIND_XXX_REGISTRY_QUERY.txt
``REGISTRY_VIEW``
.. versionadded:: 3.24
.. include:: FIND_XXX_REGISTRY_VIEW.txt
``PATH_SUFFIXES``
Specify additional subdirectories to check below each directory
location otherwise considered.
+43
View File
@@ -0,0 +1,43 @@
The formal syntax, as specified using
`BNF <https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form>`_ notation with
the regular extensions, for registry query is the following:
.. parsed-literal::
registry_query ::= '[' `sep_definition`_? `root_key`_
((`key_separator`_ `sub_key`_)? (`value_separator`_ `value_name`_)?)? ']'
_`sep_definition` ::= '{' `value_separator`_ '}'
_`root_key` ::= 'HKLM' | 'HKEY_LOCAL_MACHINE' | 'HKCU' | 'HKEY_CURRENT_USER' |
'HKCR' | 'HKEY_CLASSES_ROOT' | 'HKCC' | 'HKEY_CURRENT_CONFIG' |
'HKU' | 'HKEY_USERS'
_`sub_key` ::= `element`_ (`key_separator`_ `element`_)*
_`key_separator` ::= '/' | '\\'
_`value_separator` ::= `element`_ | ';'
_`value_name` ::= `element`_ | '(default)'
_`element` ::= `character`_\+
_`character` ::= <any character except `key_separator`_ and `value_separator`_>
The `sep_definition`_ optional item offers the possibility to specify the
string used to separate the `sub_key`_ from the `value_name`_ item. If
not specified, the character ``;`` is used.
.. parsed-literal::
# example using default separator
|FIND_XXX| (... **PATHS** "/root/[HKLM/Stuff;InstallDir]/lib[HKLM\\\\Stuff;Architecture]")
# example using different specified separators
|FIND_XXX| (... **HINTS** "/root/[{|}HKCU/Stuff|InstallDir]/lib[{@@}HKCU\\\\Stuff@@Architecture]")
If the `value_name`_ item is not specified or has the special name
``(default)``, the content of the default value, if any, will be returned. The
supported types for the `value_name`_ are:
* ``REG_SZ``.
* ``REG_EXPAND_SZ``. The returned data is expanded.
* ``REG_DWORD``.
* ``REG_QWORD``.
When the registry query failed, typically because the key does not exist or
the data type is not supported, the string ``/REGISTRY-NOTFOUND`` is substituted
to the ``[]`` query expression.
+41
View File
@@ -0,0 +1,41 @@
Specify which registry views must be queried. This option is only meaningful
on ``Windows`` platform and will be ignored on other ones. When not
specified, |FIND_XXX_REGISTRY_VIEW_DEFAULT| view is used when :policy:`CMP0134`
policy is ``NEW``. Refer to :policy:`CMP0134` policy for default view when
policy is ``OLD`` or undefined.
``64``
Query the 64bit registry. On ``32bit Windows``, returns always the string
``/REGISTRY-NOTFOUND``.
``32``
Query the 32bit registry.
``64_32``
Query both views (``64`` and ``32``) and generate a path for each.
``32_64``
Query both views (``32`` and ``64``) and generate a path for each.
``HOST``
Query the registry matching the architecture of the host: ``64`` on ``64bit
Windows`` and ``32`` on ``32bit Windows``.
``TARGET``
Query the registry matching the architecture specified by
:variable:`CMAKE_SIZEOF_VOID_P` variable. If not defined, fallback to
``HOST`` view.
``BOTH``
Query both views (``32`` and ``64``). The order depends of the following
rules: If :variable:`CMAKE_SIZEOF_VOID_P` variable is defined. Use the
following view depending of the content of this variable:
* ``8``: ``64_32``
* ``4``: ``32_64``
If :variable:`CMAKE_SIZEOF_VOID_P` variable is not defined, rely on
architecture of the host:
* ``64bit``: ``64_32``
* ``32bit``: ``32``
+2 -2
View File
@@ -288,12 +288,12 @@ The options are:
.. productionlist:: depfile
depfile: `rule`*
rule: `targets` (`:` (`separator` `dependencies`?)?)? `eol`
rule: `targets` (':' (`separator` `dependencies`?)?)? `eol`
targets: `target` (`separator` `target`)* `separator`*
target: `pathname`
dependencies: `dependency` (`separator` `dependency`)* `separator`*
dependency: `pathname`
separator: (space | line_continue)+
separator: (`space` | `line_continue`)+
line_continue: '\' `eol`
space: ' ' | '\t'
pathname: `character`+
+2
View File
@@ -8,6 +8,8 @@ find_file
.. |prefix_XXX_SUBDIR| replace:: ``<prefix>/include``
.. |entry_XXX_SUBDIR| replace:: ``<entry>/include``
.. |FIND_XXX_REGISTRY_VIEW_DEFAULT| replace:: ``TARGET``
.. |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX| replace::
``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE`
is set, and |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX_SUBDIR|
+2
View File
@@ -8,6 +8,8 @@ find_library
.. |prefix_XXX_SUBDIR| replace:: ``<prefix>/lib``
.. |entry_XXX_SUBDIR| replace:: ``<entry>/lib``
.. |FIND_XXX_REGISTRY_VIEW_DEFAULT| replace:: ``TARGET``
.. |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX| replace::
``<prefix>/lib/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` is set,
and |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX_SUBDIR|
+31 -7
View File
@@ -1,6 +1,12 @@
find_package
------------
.. |FIND_XXX| replace:: find_package
.. |FIND_ARGS_XXX| replace:: <PackageName>
.. |FIND_XXX_REGISTRY_VIEW_DEFAULT| replace:: ``TARGET``
.. |CMAKE_FIND_ROOT_PATH_MODE_XXX| replace::
:variable:`CMAKE_FIND_ROOT_PATH_MODE_PACKAGE`
.. only:: html
.. contents::
@@ -74,11 +80,12 @@ sections on this page.
Basic Signature
^^^^^^^^^^^^^^^
.. code-block:: cmake
.. parsed-literal::
find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
[REQUIRED] [[COMPONENTS] [components...]]
[OPTIONAL_COMPONENTS components...]
[REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)]
[NO_POLICY_SCOPE]
[GLOBAL])
@@ -116,6 +123,12 @@ define what occurs in such cases. Common arrangements include assuming it
should find all components, no components or some well-defined subset of the
available components.
.. versionadded:: 3.24
The ``REGISTRY_VIEW`` keyword enables to specify which registry views must be
queried. This keyword is only meaningful on ``Windows`` platform and will be
ignored on all other ones. Formally, it is up to the target package how to
interpret the registry view information given to it.
Specifying the ``GLOBAL`` keyword will promote all imported targets to
a global scope in the importing project. Alternatively this functionality
can be enabled by setting the variable
@@ -155,7 +168,7 @@ of the ``NO_POLICY_SCOPE`` option.
Full Signature
^^^^^^^^^^^^^^
.. code-block:: cmake
.. parsed-literal::
find_package(<PackageName> [version] [EXACT] [QUIET]
[REQUIRED] [[COMPONENTS] [components...]]
@@ -167,6 +180,7 @@ Full Signature
[CONFIGS config1 [config2 ...]]
[HINTS path1 [path2 ... ]]
[PATHS path1 [path2 ... ]]
[REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[NO_DEFAULT_PATH]
[NO_PACKAGE_ROOT_PATH]
@@ -272,6 +286,19 @@ that order).
if the :prop_gbl:`FIND_LIBRARY_USE_LIBX32_PATHS` property is set to ``TRUE``.
* The ``lib`` path is always searched.
.. versionchanged:: 3.24
On ``Windows`` platform, it is possible to include registry queries as part
of the directories specified through ``HINTS`` and ``PATHS`` keywords. Such
specifications will be ignored on all other platforms.
.. include:: FIND_XXX_REGISTRY_QUERY.txt
.. versionadded:: 3.24
``REGISTRY_VIEW`` can be specified to manage ``Windows`` registry queries
specified as part of ``PATHS`` and ``HINTS``.
.. include:: FIND_XXX_REGISTRY_VIEW.txt
If ``PATH_SUFFIXES`` is specified, the suffixes are appended to each
(``W``) or (``U``) directory entry one-by-one.
@@ -382,11 +409,6 @@ of the above locations to be ignored.
Added the ``CMAKE_FIND_USE_<CATEGORY>`` variables to globally disable
various search locations.
.. |FIND_XXX| replace:: find_package
.. |FIND_ARGS_XXX| replace:: <PackageName>
.. |CMAKE_FIND_ROOT_PATH_MODE_XXX| replace::
:variable:`CMAKE_FIND_ROOT_PATH_MODE_PACKAGE`
.. include:: FIND_XXX_ROOT.txt
.. include:: FIND_XXX_ORDER.txt
@@ -557,6 +579,8 @@ restores their original state before returning):
True if ``REQUIRED`` option was given
``<PackageName>_FIND_QUIETLY``
True if ``QUIET`` option was given
``<PackageName>_FIND_REGISTRY_VIEW``
The requested view if ``REGISTRY_VIEW`` option was given
``<PackageName>_FIND_VERSION``
Full requested version string
``<PackageName>_FIND_VERSION_MAJOR``
+2
View File
@@ -8,6 +8,8 @@ find_path
.. |prefix_XXX_SUBDIR| replace:: ``<prefix>/include``
.. |entry_XXX_SUBDIR| replace:: ``<entry>/include``
.. |FIND_XXX_REGISTRY_VIEW_DEFAULT| replace:: ``TARGET``
.. |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX| replace::
``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE`
is set, and |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX_SUBDIR|
+2
View File
@@ -8,6 +8,8 @@ find_program
.. |prefix_XXX_SUBDIR| replace:: ``<prefix>/[s]bin``
.. |entry_XXX_SUBDIR| replace:: ``<entry>/[s]bin``
.. |FIND_XXX_REGISTRY_VIEW_DEFAULT| replace:: ``BOTH``
.. |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX| replace::
|FIND_PACKAGE_ROOT_PREFIX_PATH_XXX_SUBDIR|
.. |CMAKE_PREFIX_PATH_XXX| replace::
+1
View File
@@ -58,6 +58,7 @@ Policies Introduced by CMake 3.24
.. toctree::
:maxdepth: 1
CMP0134: Fallback to \"HOST\" Windows registry view when \"TARGET\" view is not usable. </policy/CMP0134>
CMP0133: The CPack module disables SLA by default in the CPack DragNDrop Generator. </policy/CMP0133>
CMP0132: Do not set compiler environment variables on first run. </policy/CMP0132>
CMP0131: LINK_LIBRARIES supports the LINK_ONLY generator expression. </policy/CMP0131>
+39
View File
@@ -0,0 +1,39 @@
CMP0134
-------
.. versionadded:: 3.24
The default registry view is ``TARGET`` for the :command:`find_file`,
:command:`find_path`, :command:`find_library`, and :command:`find_package`
commands and ``BOTH`` for the :command:`find_program` command.
The default registry views in CMake 3.23 and below are selected using the
following rules:
* if :variable:`CMAKE_SIZEOF_VOID_P` has value ``8``:
* Use view ``64`` for all ``find_*`` commands except :command:`find_program`
command.
* Use view ``64_32`` for :command:`find_program` command.
* if :variable:`CMAKE_SIZEOF_VOID_P` has value ``4`` or is undefined:
* Use view ``32`` for all ``find_*`` commands except :command:`find_program`
command.
* Use view ``32_64`` for :command:`find_program` command.
The ``OLD`` behavior for this policy is to use registry views ``64`` and
``64_32`` or ``32_64`` and ``32`` as default, depending of
:variable:`CMAKE_SIZEOF_VOID_P` variable value.
The ``NEW`` behavior for this policy is to use registry views ``TARGET`` and
``BOTH`` as default.
This policy was introduced in CMake version 3.24. Use the
:command:`cmake_policy` command to set this policy to ``OLD`` or ``NEW``
explicitly. Unlike many policies, CMake version |release| does *not* warn
by default when this policy is not set and simply uses ``OLD`` behavior.
See documentation of the
:variable:`CMAKE_POLICY_WARNING_CMP0133 <CMAKE_POLICY_WARNING_CMP<NNNN>>`
variable to control the warning.
.. include:: DEPRECATED.txt
@@ -0,0 +1,6 @@
find_item-query-windows-registry.rst
------------------------------------
* :command:`find_file`, :command:`find_path`, :command:`find_library`,
:command:`find_program`, and :command:`find_package` commands gain the
capability to specify which registry views must be queried.
+15
View File
@@ -7,6 +7,7 @@
#include <map>
#include <utility>
#include <cm/optional>
#include <cmext/algorithm>
#include "cmCMakePath.h"
@@ -20,6 +21,7 @@
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
#include "cmWindowsRegistry.h"
#include "cmake.h"
class cmExecutionStatus;
@@ -123,6 +125,19 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
doing = DoingNone;
this->Required = true;
newStyle = true;
} else if (args[j] == "REGISTRY_VIEW") {
if (++j == args.size()) {
this->SetError("missing required argument for \"REGISTRY_VIEW\"");
return false;
}
auto view = cmWindowsRegistry::ToView(args[j]);
if (view) {
this->RegistryView = *view;
} else {
this->SetError(
cmStrCat("given invalid value for \"REGISTRY_VIEW\": ", args[j]));
return false;
}
} else if (this->CheckCommonArgument(args[j])) {
doing = DoingNone;
} else {
+12
View File
@@ -11,6 +11,7 @@
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -58,6 +59,17 @@ cmFindCommon::cmFindCommon(cmExecutionStatus& status)
this->InitializeSearchPathGroups();
this->DebugMode = false;
// Windows Registry views
// When policy CMP0134 is not NEW, rely on previous behavior:
if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0134) !=
cmPolicies::NEW) {
if (this->Makefile->GetDefinition("CMAKE_SIZEOF_VOID_P") == "8") {
this->RegistryView = cmWindowsRegistry::View::Reg64;
} else {
this->RegistryView = cmWindowsRegistry::View::Reg32;
}
}
}
void cmFindCommon::SetError(std::string const& e)
+2
View File
@@ -11,6 +11,7 @@
#include "cmPathLabel.h"
#include "cmSearchPath.h"
#include "cmWindowsRegistry.h"
class cmExecutionStatus;
class cmMakefile;
@@ -131,6 +132,7 @@ protected:
bool NoSystemEnvironmentPath;
bool NoCMakeSystemPath;
bool NoCMakeInstallPath;
cmWindowsRegistry::View RegistryView = cmWindowsRegistry::View::Target;
std::vector<std::string> SearchPathSuffixes;
+21
View File
@@ -13,6 +13,7 @@
#include <utility>
#include <cm/memory>
#include <cm/optional>
#include <cmext/string_view>
#include "cmsys/Directory.hxx"
@@ -33,6 +34,7 @@
#include "cmSystemTools.h"
#include "cmValue.h"
#include "cmVersion.h"
#include "cmWindowsRegistry.h"
#if defined(__HAIKU__)
# include <FindDirectory.h>
@@ -317,6 +319,20 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
// Ignore legacy option.
configArgs.insert(i);
doing = DoingNone;
} else if (args[i] == "REGISTRY_VIEW") {
if (++i == args.size()) {
this->SetError("missing required argument for \"REGISTRY_VIEW\"");
return false;
}
auto view = cmWindowsRegistry::ToView(args[i]);
if (view) {
this->RegistryView = *view;
this->RegistryViewDefined = true;
} else {
this->SetError(
cmStrCat("given invalid value for \"REGISTRY_VIEW\": ", args[i]));
return false;
}
} else if (this->CheckCommonArgument(args[i])) {
configArgs.insert(i);
doing = DoingNone;
@@ -767,6 +783,11 @@ void cmFindPackageCommand::SetModuleVariables(const std::string& components)
id = cmStrCat(this->Name, "_FIND_VERSION_RANGE_MAX");
this->AddFindDefinition(id, this->VersionRangeMax);
}
if (this->RegistryViewDefined) {
this->AddFindDefinition(cmStrCat(this->Name, "_FIND_REGISTRY_VIEW"),
cmWindowsRegistry::FromView(this->RegistryView));
}
}
void cmFindPackageCommand::AddFindDefinition(const std::string& var,
+1
View File
@@ -200,6 +200,7 @@ private:
bool UseRealPath = false;
bool PolicyScope = true;
bool GlobalScope = false;
bool RegistryViewDefined = false;
std::string LibraryArchitecture;
std::vector<std::string> Names;
std::vector<std::string> Configs;
+14
View File
@@ -12,6 +12,8 @@
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
#include "cmWindowsRegistry.h"
class cmExecutionStatus;
@@ -172,6 +174,18 @@ cmFindProgramCommand::cmFindProgramCommand(cmExecutionStatus& status)
this->NamesPerDirAllowed = true;
this->VariableDocumentation = "Path to a program.";
this->VariableType = cmStateEnums::FILEPATH;
// Windows Registry views
// When policy CMP0134 is not NEW, rely on previous behavior:
if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0134) !=
cmPolicies::NEW) {
if (this->Makefile->GetDefinition("CMAKE_SIZEOF_VOID_P") == "8") {
this->RegistryView = cmWindowsRegistry::View::Reg64_32;
} else {
this->RegistryView = cmWindowsRegistry::View::Reg32_64;
}
} else {
this->RegistryView = cmWindowsRegistry::View::Both;
}
}
// cmFindProgramCommand
+4
View File
@@ -400,6 +400,10 @@ class cmMakefile;
SELECT(POLICY, CMP0133, \
"The CPack module disables SLA by default in the CPack DragNDrop " \
"Generator.", \
3, 24, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0134, \
"Fallback to \"HOST\" Windows registry view when \"TARGET\" view " \
"is not usable.", \
3, 24, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
+10 -20
View File
@@ -6,11 +6,14 @@
#include <cassert>
#include <utility>
#include <cm/optional>
#include "cmFindCommon.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
#include "cmWindowsRegistry.h"
cmSearchPath::cmSearchPath(cmFindCommon* findCmd)
: FC(findCmd)
@@ -46,26 +49,13 @@ void cmSearchPath::AddUserPath(const std::string& path)
std::vector<std::string> outPaths;
// We should view the registry as the target application would view
// it.
cmSystemTools::KeyWOW64 view = cmSystemTools::KeyWOW64_32;
cmSystemTools::KeyWOW64 other_view = cmSystemTools::KeyWOW64_64;
if (this->FC->Makefile->PlatformIs64Bit()) {
view = cmSystemTools::KeyWOW64_64;
other_view = cmSystemTools::KeyWOW64_32;
}
// Expand using the view of the target application.
std::string expanded = path;
cmSystemTools::ExpandRegistryValues(expanded, view);
cmSystemTools::GlobDirs(expanded, outPaths);
// Executables can be either 32-bit or 64-bit, so expand using the
// alternative view.
if (expanded != path && this->FC->CMakePathName == "PROGRAM") {
expanded = path;
cmSystemTools::ExpandRegistryValues(expanded, other_view);
cmSystemTools::GlobDirs(expanded, outPaths);
cmWindowsRegistry registry(*this->FC->Makefile,
cmWindowsRegistry::SimpleTypes);
auto expandedPaths = registry.ExpandExpression(path, this->FC->RegistryView);
if (expandedPaths) {
for (const auto& expandedPath : expandedPaths.value()) {
cmSystemTools::GlobDirs(expandedPath, outPaths);
}
}
// Process them all from the current directory
+255 -26
View File
@@ -1,33 +1,61 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmConfigure.h" // IWYU pragma: keep
#include "cmWindowsRegistry.h"
#include <cctype>
#include <cstddef>
#include <functional>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
#if defined(_WIN32) && !defined(__CYGWIN__)
# include <algorithm>
# include <cstdint>
# include <cstring>
# include <exception>
# include <iterator>
# include <utility>
# include <vector>
# include <cm/memory>
# include <cmext/string_view>
# include <windows.h>
# include "cmsys/Encoding.hxx"
# include "cmsys/SystemTools.hxx"
# include "cmMakefile.h"
# include "cmStringAlgorithms.h"
# include "cmValue.h"
#endif
#if defined(_WIN32) && !defined(__CYGWIN__)
namespace {
// Case-independent string comparison
int Strucmp(cm::string_view l, cm::string_view r)
{
if (l.empty() && r.empty()) {
return 0;
}
if (l.empty() || r.empty()) {
return static_cast<int>(l.size() - r.size());
}
int lc;
int rc;
cm::string_view::size_type li = 0;
cm::string_view::size_type ri = 0;
do {
lc = std::tolower(l[li++]);
rc = std::tolower(r[ri++]);
} while (lc == rc && li < l.size() && ri < r.size());
return lc == rc ? static_cast<int>(l.size() - r.size()) : lc - rc;
}
#if defined(_WIN32) && !defined(__CYGWIN__)
bool Is64BitWindows()
{
# if defined(_WIN64)
@@ -40,6 +68,26 @@ bool Is64BitWindows()
# endif
}
// Helper to translate Windows registry value type to enum ValueType
cm::optional<cmWindowsRegistry::ValueType> ToValueType(DWORD type)
{
using ValueType = cmWindowsRegistry::ValueType;
static std::unordered_map<DWORD, ValueType> ValueTypes{
{ REG_SZ, ValueType::Reg_SZ },
{ REG_EXPAND_SZ, ValueType::Reg_EXPAND_SZ },
{ REG_MULTI_SZ, ValueType::Reg_MULTI_SZ },
{ REG_DWORD, ValueType::Reg_DWORD },
{ REG_QWORD, ValueType::Reg_QWORD }
};
auto it = ValueTypes.find(type);
return it == ValueTypes.end()
? cm::nullopt
: cm::optional<cmWindowsRegistry::ValueType>{ it->second };
}
// class registry_exception
class registry_error : public std::exception
{
@@ -61,6 +109,7 @@ class KeyHandler
{
public:
using View = cmWindowsRegistry::View;
using ValueTypeSet = cmWindowsRegistry::ValueTypeSet;
KeyHandler(HKEY hkey)
: Handler(hkey)
@@ -68,9 +117,14 @@ public:
}
~KeyHandler() { RegCloseKey(this->Handler); }
static KeyHandler OpenKey(cm::string_view rootKey, cm::string_view subKey,
View view);
static KeyHandler OpenKey(cm::string_view key, View view);
std::string ReadValue(cm::string_view name, cm::string_view separator);
std::string ReadValue(
cm::string_view name,
ValueTypeSet supportedTypes = cmWindowsRegistry::AllTypes,
cm::string_view separator = "\0"_s);
std::vector<std::string> GetValueNames();
std::vector<std::string> GetSubKeys();
@@ -83,16 +137,14 @@ private:
HKEY Handler;
};
KeyHandler KeyHandler::OpenKey(cm::string_view key, View view)
KeyHandler KeyHandler::OpenKey(cm::string_view rootKey, cm::string_view subKey,
View view)
{
if (view == View::Reg64 && !Is64BitWindows()) {
throw registry_error("No 64bit registry on Windows32.");
}
auto start = key.find_first_of("\\/"_s);
auto rootKey = key.substr(0, start);
HKEY hRootKey;
if (rootKey == "HKCU"_s || rootKey == "HKEY_CURRENT_USER"_s) {
hRootKey = HKEY_CURRENT_USER;
} else if (rootKey == "HKLM"_s || rootKey == "HKEY_LOCAL_MACHINE"_s) {
@@ -106,12 +158,9 @@ KeyHandler KeyHandler::OpenKey(cm::string_view key, View view)
} else {
throw registry_error(cmStrCat(rootKey, ": invalid root key."));
}
std::wstring subKey;
if (start != cm::string_view::npos) {
subKey = ToWide(key.substr(start + 1));
}
// Update path format
std::replace(subKey.begin(), subKey.end(), L'/', L'\\');
auto key = ToWide(subKey);
std::replace(key.begin(), key.end(), L'/', L'\\');
REGSAM options = KEY_READ;
if (Is64BitWindows()) {
@@ -119,14 +168,25 @@ KeyHandler KeyHandler::OpenKey(cm::string_view key, View view)
}
HKEY hKey;
if (LSTATUS status = RegOpenKeyExW(hRootKey, subKey.c_str(), 0, options,
&hKey) != ERROR_SUCCESS) {
LSTATUS status;
if ((status = RegOpenKeyExW(hRootKey, key.c_str(), 0, options, &hKey)) !=
ERROR_SUCCESS) {
throw registry_error(FormatSystemError(status));
}
return KeyHandler(hKey);
}
KeyHandler KeyHandler::OpenKey(cm::string_view key, View view)
{
auto start = key.find_first_of("\\/"_s);
return OpenKey(key.substr(0, start),
start == cm::string_view::npos ? cm::string_view{ ""_s }
: key.substr(start + 1),
view);
}
std::string KeyHandler::FormatSystemError(LSTATUS status)
{
std::string formattedMessage{ "Windows Registry: unexpected error." };
@@ -208,6 +268,7 @@ std::string KeyHandler::ToNarrow(const wchar_t* wstr, int size)
}
std::string KeyHandler::ReadValue(cm::string_view name,
ValueTypeSet supportedTypes,
cm::string_view separator)
{
LSTATUS status;
@@ -225,6 +286,12 @@ std::string KeyHandler::ReadValue(cm::string_view name,
&type, data.get(), &size)) != ERROR_SUCCESS) {
throw registry_error(this->FormatSystemError(status));
}
auto valueType = ToValueType(type);
if (!valueType || !supportedTypes.contains(*valueType)) {
throw registry_error(cmStrCat(type, ": unsupported type."));
}
switch (type) {
case REG_SZ:
return this->ToNarrow(reinterpret_cast<wchar_t*>(data.get()));
@@ -319,12 +386,109 @@ std::vector<std::string> KeyHandler::GetSubKeys()
return subKeys;
}
}
#endif
// ExpressionParser: Helper to parse expression holding multiple
// registry specifications
class ExpressionParser
{
public:
ExpressionParser(cm::string_view expression)
: Expression(expression)
, Separator(";"_s)
, RegistryFormat{
"\\[({.+})?(HKCU|HKEY_CURRENT_USER|HKLM|HKEY_LOCAL_MACHINE|HKCR|HKEY_"
"CLASSES_"
"ROOT|HKCC|HKEY_CURRENT_CONFIG|HKU|HKEY_USERS)[/\\]?([^]]*)\\]"
}
{
}
bool Find()
{
// reset result members
this->RootKey = cm::string_view{};
this->SubKey = cm::string_view{};
this->ValueName = cm::string_view{};
auto result = this->RegistryFormat.find(this->Expression);
if (result) {
auto separator = cm::string_view{
this->Expression.data() + this->RegistryFormat.start(1),
this->RegistryFormat.end(1) - this->RegistryFormat.start(1)
};
if (separator.empty()) {
separator = this->Separator;
} else {
separator = separator.substr(1, separator.length() - 2);
}
this->RootKey = cm::string_view{
this->Expression.data() + this->RegistryFormat.start(2),
this->RegistryFormat.end(2) - this->RegistryFormat.start(2)
};
this->SubKey = cm::string_view{
this->Expression.data() + this->RegistryFormat.start(3),
this->RegistryFormat.end(3) - this->RegistryFormat.start(3)
};
auto pos = this->SubKey.find(separator);
if (pos != cm::string_view::npos) {
// split in ValueName and SubKey
this->ValueName = this->SubKey.substr(pos + separator.size());
if (Strucmp(this->ValueName, "(default)") == 0) {
// handle magic name for default value
this->ValueName = ""_s;
}
this->SubKey = this->SubKey.substr(0, pos);
} else {
this->ValueName = ""_s;
}
}
return result;
}
#if defined(_WIN32) && !defined(__CYGWIN__)
void Replace(const std::string& value)
{
this->Expression.replace(
this->RegistryFormat.start(),
this->RegistryFormat.end() - this->RegistryFormat.start(), value);
}
cm::string_view GetRootKey() const { return this->RootKey; }
cm::string_view GetSubKey() const { return this->SubKey; }
cm::string_view GetValueName() const { return this->ValueName; }
const std::string& GetExpression() const { return this->Expression; }
#endif
private:
std::string Expression;
cm::string_view Separator;
cmsys::RegularExpression RegistryFormat;
cm::string_view RootKey;
cm::string_view SubKey;
cm::string_view ValueName;
};
}
// class cmWindowsRegistry
cmWindowsRegistry::cmWindowsRegistry(cmMakefile& makefile)
#if !defined(_WIN32) || defined(__CYGWIN__)
const cmWindowsRegistry::ValueTypeSet cmWindowsRegistry::SimpleTypes =
cmWindowsRegistry::ValueTypeSet{ cmWindowsRegistry::ValueType::Reg_SZ,
cmWindowsRegistry::ValueType::Reg_EXPAND_SZ,
cmWindowsRegistry::ValueType::Reg_DWORD,
cmWindowsRegistry::ValueType::Reg_QWORD };
const cmWindowsRegistry::ValueTypeSet cmWindowsRegistry::AllTypes =
cmWindowsRegistry::SimpleTypes + cmWindowsRegistry::ValueType::Reg_MULTI_SZ;
cmWindowsRegistry::cmWindowsRegistry(cmMakefile& makefile,
const ValueTypeSet& supportedTypes)
#if defined(_WIN32) && !defined(__CYGWIN__)
: SupportedTypes(supportedTypes)
#else
: LastError("No Registry on this platform.")
#endif
{
@@ -334,6 +498,7 @@ cmWindowsRegistry::cmWindowsRegistry(cmMakefile& makefile)
}
#else
(void)makefile;
(void)supportedTypes;
#endif
}
@@ -350,8 +515,22 @@ cm::optional<cmWindowsRegistry::View> cmWindowsRegistry::ToView(
auto it = ViewDefinitions.find(name);
return it == ViewDefinitions.end() ? cm::nullopt
: cm::optional{ it->second };
return it == ViewDefinitions.end()
? cm::nullopt
: cm::optional<cmWindowsRegistry::View>{ it->second };
}
// define hash structure required by std::unordered_map
namespace std {
template <>
struct hash<cmWindowsRegistry::View>
{
size_t operator()(cmWindowsRegistry::View const& v) const noexcept
{
return static_cast<
typename underlying_type<cmWindowsRegistry::View>::type>(v);
}
};
}
cm::string_view cmWindowsRegistry::FromView(View view)
@@ -434,7 +613,7 @@ cm::optional<std::string> cmWindowsRegistry::ReadValue(
// compute list of registry views
auto views = this->ComputeViews(view);
if (cmsys::SystemTools::Strucmp(name.data(), "(default)") == 0) {
if (Strucmp(name, "(default)") == 0) {
// handle magic name for default value
name = ""_s;
}
@@ -446,7 +625,7 @@ cm::optional<std::string> cmWindowsRegistry::ReadValue(
try {
this->LastError.clear();
auto handler = KeyHandler::OpenKey(key, v);
return handler.ReadValue(name, separator);
return handler.ReadValue(name, this->SupportedTypes, separator);
} catch (const registry_error& e) {
this->LastError = e.what();
continue;
@@ -539,3 +718,53 @@ cm::optional<std::vector<std::string>> cmWindowsRegistry::GetSubKeys(
#endif
return cm::nullopt;
}
cm::optional<std::vector<std::string>> cmWindowsRegistry::ExpandExpression(
cm::string_view expression, View view, cm::string_view separator)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
static std::string NOTFOUND{ "/REGISTRY-NOTFOUND" };
this->LastError.clear();
// compute list of registry views
auto views = this->ComputeViews(view);
std::vector<std::string> result;
for (auto v : views) {
ExpressionParser parser(expression);
while (parser.Find()) {
try {
auto handler =
KeyHandler::OpenKey(parser.GetRootKey(), parser.GetSubKey(), v);
auto data = handler.ReadValue(parser.GetValueName(),
this->SupportedTypes, separator);
parser.Replace(data);
} catch (const registry_error& e) {
this->LastError = e.what();
parser.Replace(NOTFOUND);
continue;
}
}
result.emplace_back(parser.GetExpression());
if (expression == parser.GetExpression()) {
// there no substitutions, so can ignore other views
break;
}
}
return result;
#else
(void)view;
(void)separator;
ExpressionParser parser(expression);
if (parser.Find()) {
// expression holds unsupported registry access
// so the expression cannot be used on this platform
return cm::nullopt;
}
return std::vector<std::string>{ std::string{ expression } };
#endif
}
+27 -2
View File
@@ -7,6 +7,7 @@
#include <cm/optional>
#include <cm/string_view>
#include <cmext/enum_set>
#include <cmext/string_view>
class cmMakefile;
@@ -14,8 +15,6 @@ class cmMakefile;
class cmWindowsRegistry
{
public:
cmWindowsRegistry(cmMakefile&);
enum class View
{
Both,
@@ -27,6 +26,25 @@ public:
Reg64
};
// Registry supported types
enum class ValueType : std::uint8_t
{
Reg_SZ,
Reg_EXPAND_SZ,
Reg_MULTI_SZ,
Reg_DWORD,
Reg_QWORD
};
using ValueTypeSet = cm::enum_set<ValueType>;
// All types as defined by enum ValueType
static const ValueTypeSet AllTypes;
// same as AllTYpes but without type REG_MULTI_SZ
static const ValueTypeSet SimpleTypes;
cmWindowsRegistry(cmMakefile&,
const ValueTypeSet& supportedTypes = AllTypes);
// Helper routine to convert string to enum value
static cm::optional<View> ToView(cm::string_view name);
// Helper routine to convert enum to string
@@ -48,6 +66,12 @@ public:
cm::optional<std::vector<std::string>> GetSubKeys(cm::string_view key,
View view = View::Both);
// Expand an expression which may contains multiple references
// to registry keys.
// Depending of the view specified, one or two expansions can be done.
cm::optional<std::vector<std::string>> ExpandExpression(
cm::string_view expression, View view, cm::string_view separator = "\0"_s);
cm::string_view GetLastError() const;
private:
@@ -55,6 +79,7 @@ private:
std::vector<View> ComputeViews(View view);
int TargetSize = 0;
ValueTypeSet SupportedTypes = AllTypes;
#endif
std::string LastError;
};
@@ -0,0 +1 @@
1
@@ -0,0 +1,4 @@
CMake Error at REGISTRY_VIEW-no-view.cmake:[0-9]+ \(find_file\):
find_file missing required argument for "REGISTRY_VIEW"
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
@@ -0,0 +1,2 @@
find_file(result NAMES input.txt REGISTRY_VIEW)
@@ -0,0 +1 @@
1
@@ -0,0 +1,4 @@
CMake Error at REGISTRY_VIEW-wrong-view.cmake:[0-9]+ \(find_file\):
find_file given invalid value for "REGISTRY_VIEW": WRONG_VIEW
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
@@ -0,0 +1,2 @@
find_file(result NAMES input.txt REGISTRY_VIEW WRONG_VIEW)
@@ -0,0 +1,218 @@
# helper function for test validation
function(CHECK query result expression)
cmake_language(EVAL CODE
"if (NOT (${expression}))
message(SEND_ERROR \"wrong value for query '${query}': '${result}'\")
endif()")
endfunction()
cmake_policy(SET CMP0134 NEW)
# HKCU/Software/Classes/CLSID/CMake-Tests/find_file: Query default value
set(FILE_DIR "[HKCU/Software/Classes/CLSID/CMake-Tests/find_file]")
set(FILE_DIR2 "[HKCU/Software/Classes/CLSID/CMake-Tests/find_file;(default)]")
unset(result)
find_file(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.${ARCH}/file.txt$\"")
# query value using special name should be identical to default value
unset(result)
find_file(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR2}" REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR2}" "${result}" "result MATCHES \"default.${ARCH}/file.txt$\"")
unset(result)
find_file(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW HOST REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.${ARCH}/file.txt$\"")
# VIEW TARGET should have same value as VIEW HOST
unset(result2)
find_file(result2 NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW TARGET REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result2}" "result2 STREQUAL result")
if (ARCH STREQUAL "64bit")
unset(result)
find_file(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.64bit/file.txt$\"")
unset(result)
find_file(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/file.txt$\"")
unset(result)
find_file(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.64bit/file.txt$\"")
unset(result)
find_file(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/file.txt$\"")
# check the second view is taken into account
unset(result)
find_file(result NAMES file32bit.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/file32bit.txt$\"")
unset(result)
find_file(result NAMES file64bit.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.64bit/file64bit.txt$\"")
# check the both views are taken into account
unset(result)
find_file(result NAMES file32bit.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/file32bit.txt$\"")
unset(result)
find_file(result NAMES file64bit.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.64bit/file64bit.txt$\"")
else() # 32bit
# no 64bit registry: file not found
unset(result)
find_file(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64 NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"result-NOTFOUND$\"")
unset(result)
find_file(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/file.txt$\"")
# views 64_32 and 32_64 give same result
unset(result)
find_file(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/file.txt$\"")
unset(result)
find_file(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/file.txt$\"")
# check the both views are usable on 32bit platforms
unset(result)
find_file(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/file.txt$\"")
endif()
# HKCU/Software/Classes/CLSID/CMake-Tests/find_file: Query specific value
set(FILE_DIR "[{|}HKCU/Software/Classes/CLSID/CMake-Tests/find_file|FILE_DIR]")
set(FILE_DIR2 "[HKCU\\Software\\Classes\\CLSID\\CMake-Tests\\find_file;FILE_DIR]")
unset(result)
find_file(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/${ARCH}/file.txt$\"")
# query value using special name should be identical to default value
unset(result)
find_file(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR2}" REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR2}" "${result}" "result MATCHES \"/${ARCH}/file.txt$\"")
unset(result)
find_file(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW HOST REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/${ARCH}/file.txt$\"")
# VIEW TARGET should have same value as VIEW HOST
unset(result2)
find_file(result2 NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW TARGET REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result2}" "result2 STREQUAL result")
if (ARCH STREQUAL "64bit")
unset(result)
find_file(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/64bit/file.txt$\"")
unset(result)
find_file(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/file.txt$\"")
unset(result)
find_file(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/64bit/file.txt$\"")
unset(result)
find_file(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/file.txt$\"")
# check the second view is taken into account
unset(result)
find_file(result NAMES file32bit.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/file32bit.txt$\"")
unset(result)
find_file(result NAMES file64bit.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/64bit/file64bit.txt$\"")
# check the both views are taken into account
unset(result)
find_file(result NAMES file32bit.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/file32bit.txt$\"")
unset(result)
find_file(result NAMES file64bit.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/64bit/file64bit.txt$\"")
else() # 32bit
# no 64bit registry: file not found
unset(result)
find_file(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64 NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"result-NOTFOUND$\"")
unset(result)
find_file(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/file.txt$\"")
unset(result)
find_file(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/file.txt$\"")
unset(result)
find_file(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/file.txt$\"")
# check the both views are taken into account
unset(result)
find_file(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/file.txt$\"")
endif()
if (ARCH STREQUAL "64bit")
# Check influence of variable CMAKE_SIZEOF_VOID_P
set(CMAKE_SIZEOF_VOID_P 8)
unset(result)
find_file(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW TARGET REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/64bit/file.txt$\"")
unset(result)
find_file(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW HOST REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/${ARCH}/file.txt$\"")
set(CMAKE_SIZEOF_VOID_P 4)
unset(result)
find_file(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW TARGET REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/file.txt$\"")
unset(result)
find_file(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW HOST REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/${ARCH}/file.txt$\"")
unset(CMAKE_SIZEOF_VOID_P)
# Check influence of CMP0134 policy with OLD value
cmake_policy(SET CMP0134 OLD)
# CMAKE_SIZEOF_VOID_P is not set, so search first 32bit registry
unset(result)
find_file(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/file.txt$\"")
cmake_policy(SET CMP0134 NEW)
# CMAKE_SIZEOF_VOID_P is not set, so search first the HOST architecture registry
unset(result)
find_file(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/${ARCH}/file.txt$\"")
endif()
@@ -5,5 +5,33 @@ run_cmake(FromPrefixPath)
run_cmake(PrefixInPATH)
run_cmake(Required)
run_cmake(NO_CACHE)
run_cmake(REGISTRY_VIEW-no-view)
run_cmake(REGISTRY_VIEW-wrong-view)
run_cmake_with_options(FromPATHEnvDebugVar --debug-find-var=PrefixInPATH_File)
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
# Tests using the Windows registry
find_program(REG NAMES "reg.exe" NO_CACHE)
if (REG)
## check host architecture
cmake_host_system_information(RESULT result QUERY WINDOWS_REGISTRY "HKCU" SUBKEYS VIEW 64 ERROR_VARIABLE status)
if (status STREQUAL "")
set(ARCH "64bit")
else()
set(ARCH "32bit")
endif()
# crete some entries in the registry
cmake_path(CONVERT "${RunCMake_SOURCE_DIR}/registry_host${ARCH}.reg" TO_NATIVE_PATH_LIST registry_data)
execute_process(COMMAND "${REG}" import "${registry_data}" OUTPUT_QUIET ERROR_QUIET)
run_cmake_with_options(Registry-query -DARCH=${ARCH})
# clean-up registry
execute_process(COMMAND "${REG}" delete "HKCU\\SOFTWARE\\Classes\\CLSID\\CMake-Tests\\find_file" /f OUTPUT_QUIET ERROR_QUIET)
if (ARCH STREQUAL "64bit")
execute_process(COMMAND "${REG}" delete "HKCU\\SOFTWARE\\Classes\\WOW6432Node\\CLSID\\CMake-Tests\\find_file" /f OUTPUT_QUIET ERROR_QUIET)
endif()
endif()
endif()
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
1
@@ -0,0 +1,4 @@
CMake Error at REGISTRY_VIEW-no-view.cmake:[0-9]+ \(find_library\):
find_library missing required argument for "REGISTRY_VIEW"
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
@@ -0,0 +1,2 @@
find_library(result NAMES input.txt REGISTRY_VIEW)
@@ -0,0 +1 @@
1
@@ -0,0 +1,4 @@
CMake Error at REGISTRY_VIEW-wrong-view.cmake:[0-9]+ \(find_library\):
find_library given invalid value for "REGISTRY_VIEW": WRONG_VIEW
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
@@ -0,0 +1,2 @@
find_library(result NAMES input.txt REGISTRY_VIEW WRONG_VIEW)
@@ -0,0 +1,218 @@
# helper function for test validation
function(CHECK query result expression)
cmake_language(EVAL CODE
"if (NOT (${expression}))
message(SEND_ERROR \"wrong value for query '${query}': '${result}'\")
endif()")
endfunction()
cmake_policy(SET CMP0134 NEW)
# HKCU/Software/Classes/CLSID/CMake-Tests/find_library: Query default value
set(FILE_DIR "[HKCU/Software/Classes/CLSID/CMake-Tests/find_library]")
set(FILE_DIR2 "[HKCU/Software/Classes/CLSID/CMake-Tests/find_library;(default)]")
unset(result)
find_library(result NAMES file.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.${ARCH}/file.lib$\"")
# query value using special name should be identical to default value
unset(result)
find_library(result NAMES file.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR2}" REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR2}" "${result}" "result MATCHES \"default.${ARCH}/file.lib$\"")
unset(result)
find_library(result NAMES file.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW HOST REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.${ARCH}/file.lib$\"")
# VIEW TARGET should have same value as VIEW HOST
unset(result2)
find_library(result2 NAMES file.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW TARGET REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result2}" "result2 STREQUAL result")
if (ARCH STREQUAL "64bit")
unset(result)
find_library(result NAMES file.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.64bit/file.lib$\"")
unset(result)
find_library(result NAMES file.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/file.lib$\"")
unset(result)
find_library(result NAMES file.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.64bit/file.lib$\"")
unset(result)
find_library(result NAMES file.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/file.lib$\"")
# check the second view is taken into account
unset(result)
find_library(result NAMES file32bit.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/file32bit.lib$\"")
unset(result)
find_library(result NAMES file64bit.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.64bit/file64bit.lib$\"")
unset(result)
# check the both views are taken into account
unset(result)
find_library(result NAMES file32bit.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/file32bit.lib$\"")
unset(result)
find_library(result NAMES file64bit.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.64bit/file64bit.lib$\"")
unset(result)
else() # 32bit
# no 64bit registry: file not found
unset(result)
find_library(result NAMES file.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64 NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"result-NOTFOUND$\"")
unset(result)
find_library(result NAMES file.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/file.lib$\"")
# views 64_32 and 32_64 give same result
unset(result)
find_library(result NAMES file.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/file.lib$\"")
unset(result)
find_library(result NAMES file.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/file.lib$\"")
# check the both views are usable on 32bit platforms
unset(result)
find_library(result NAMES file.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/file.lib$\"")
endif()
# HKCU/Software/Classes/CLSID/CMake-Tests/find_library: Query specific value
set(FILE_DIR "[{|}HKCU/Software/Classes/CLSID/CMake-Tests/find_library|FILE_DIR]")
set(FILE_DIR2 "[HKCU\\Software\\Classes\\CLSID\\CMake-Tests\\find_library;FILE_DIR]")
unset(result)
find_library(result NAMES file.lib HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/${ARCH}/file.lib$\"")
# query value using special name should be identical to default value
unset(result)
find_library(result NAMES file.lib HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR2}" REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR2}" "${result}" "result MATCHES \"/${ARCH}/file.lib$\"")
unset(result)
find_library(result NAMES file.lib HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW HOST REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/${ARCH}/file.lib$\"")
# VIEW TARGET should have same value as VIEW HOST
unset(result2)
find_library(result2 NAMES file.lib HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW TARGET REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result2}" "result2 STREQUAL result")
if (ARCH STREQUAL "64bit")
unset(result)
find_library(result NAMES file.lib HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/64bit/file.lib$\"")
unset(result)
find_library(result NAMES file.lib HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/file.lib$\"")
unset(result)
find_library(result NAMES file.lib HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/64bit/file.lib$\"")
unset(result)
find_library(result NAMES file.lib HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/file.lib$\"")
# check the second view is taken into account
unset(result)
find_library(result NAMES file32bit.lib HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/file32bit.lib$\"")
unset(result)
find_library(result NAMES file64bit.lib HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/64bit/file64bit.lib$\"")
# check the both views are taken into account
unset(result)
find_library(result NAMES file32bit.lib HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/file32bit.lib$\"")
unset(result)
find_library(result NAMES file64bit.lib HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/64bit/file64bit.lib$\"")
else() # 32bit
# no 64bit registry: file not found
unset(result)
find_library(result NAMES file.lib HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64 NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"result-NOTFOUND$\"")
unset(result)
find_library(result NAMES file.lib HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/file.lib$\"")
unset(result)
find_library(result NAMES file.lib HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/file.lib$\"")
unset(result)
find_library(result NAMES file.lib HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/file.lib$\"")
unset(result)
find_library(result NAMES file.lib HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/file.lib$\"")
endif()
if (ARCH STREQUAL "64bit")
# Check influence of variable CMAKE_SIZEOF_VOID_P
set(CMAKE_SIZEOF_VOID_P 8)
unset(result)
find_library(result NAMES file.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW TARGET REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/64bit/file.lib$\"")
unset(result)
find_library(result NAMES file.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW HOST REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/${ARCH}/file.lib$\"")
set(CMAKE_SIZEOF_VOID_P 4)
unset(result)
find_library(result NAMES file.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW TARGET REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/file.lib$\"")
unset(result)
find_library(result NAMES file.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW HOST REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/${ARCH}/file.lib$\"")
unset(CMAKE_SIZEOF_VOID_P)
# Check influence of CMP0134 policy with OLD value
cmake_policy(SET CMP0134 OLD)
# CMAKE_SIZEOF_VOID_P is not set, so search first 32bit registry
unset(result)
find_library(result NAMES file.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/file.lib$\"")
cmake_policy(SET CMP0134 NEW)
# CMAKE_SIZEOF_VOID_P is not set, so search first the HOST architecture registry
unset(result)
find_library(result NAMES file.lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/${ARCH}/file.lib$\"")
endif()
@@ -11,7 +11,35 @@ endif()
run_cmake(PrefixInPATH)
run_cmake(Required)
run_cmake(NO_CACHE)
run_cmake(REGISTRY_VIEW-no-view)
run_cmake(REGISTRY_VIEW-wrong-view)
run_cmake_script(FromScriptMode "-DTEMP_DIR=${RunCMake_BINARY_DIR}/FromScriptMode-temp")
run_cmake_with_options(FromPATHEnvDebugVar --debug-find-var=CREATED_LIBRARY)
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
# Tests using the Windows registry
find_program(REG NAMES "reg.exe" NO_CACHE)
if (REG)
## check host architecture
cmake_host_system_information(RESULT result QUERY WINDOWS_REGISTRY "HKCU" SUBKEYS VIEW 64 ERROR_VARIABLE status)
if (status STREQUAL "")
set(ARCH "64bit")
else()
set(ARCH "32bit")
endif()
# crete some entries in the registry
cmake_path(CONVERT "${RunCMake_SOURCE_DIR}/registry_host${ARCH}.reg" TO_NATIVE_PATH_LIST registry_data)
execute_process(COMMAND "${REG}" import "${registry_data}" OUTPUT_QUIET ERROR_QUIET)
run_cmake_with_options(Registry-query -DARCH=${ARCH})
# clean-up registry
execute_process(COMMAND "${REG}" delete "HKCU\\SOFTWARE\\Classes\\CLSID\\CMake-Tests\\find_library" /f OUTPUT_QUIET ERROR_QUIET)
if (ARCH STREQUAL "64bit")
execute_process(COMMAND "${REG}" delete "HKCU\\SOFTWARE\\Classes\\WOW6432Node\\CLSID\\CMake-Tests\\find_library" /f OUTPUT_QUIET ERROR_QUIET)
endif()
endif()
endif()
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,4 @@
if (NOT EXPECTED_LOCATION STREQUAL "32bit")
message (SEND_ERROR "RegistryViewConfig: location is '32bit' but expects '${EXPECTED_LOCATION}'")
endif()
@@ -0,0 +1,4 @@
if (NOT EXPECTED_LOCATION STREQUAL "32bit")
message (SEND_ERROR "RegistryViewConfig: location is '32bit' but expects '${EXPECTED_LOCATION}'")
endif()
@@ -0,0 +1,4 @@
if (NOT EXPECTED_LOCATION STREQUAL "64bit")
message (SEND_ERROR "RegistryViewConfig: location is '64bit' but expects '${EXPECTED_LOCATION}'")
endif()
@@ -0,0 +1,4 @@
if (NOT EXPECTED_LOCATION STREQUAL "64bit")
message (SEND_ERROR "RegistryViewConfig: location is '64bit' but expects '${EXPECTED_LOCATION}'")
endif()
@@ -0,0 +1,11 @@
if (EXPECTED_REGISTRY_VIEW STREQUAL "UNDEFINED")
if (DEFINED ${CMAKE_FIND_PACKAGE_NAME}_FIND_REGISTRY_VIEW)
message(SEND_ERROR "${CMAKE_FIND_PACKAGE_NAME}_FIND_REGISTRY_VIEW: unexpectedly defined as '${${CMAKE_FIND_PACKAGE_NAME}_FIND_REGISTRY_VIEW}' instead of '${EXPECTED_REGISTRY_VIEW}'")
endif()
return()
endif()
if (NOT ${CMAKE_FIND_PACKAGE_NAME}_FIND_REGISTRY_VIEW STREQUAL EXPECTED_REGISTRY_VIEW)
message(SEND_ERROR "${CMAKE_FIND_PACKAGE_NAME}_FIND_REGISTRY_VIEW: '${${CMAKE_FIND_PACKAGE_NAME}_FIND_REGISTRY_VIEW}' instead of '${EXPECTED_REGISTRY_VIEW}'")
endif()
@@ -0,0 +1 @@
1
@@ -0,0 +1,4 @@
CMake Error at REGISTRY_VIEW-no-view.cmake:[0-9]+ \(find_package\):
find_package missing required argument for "REGISTRY_VIEW"
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
@@ -0,0 +1,2 @@
find_package(result NAMES input.txt REGISTRY_VIEW)
@@ -0,0 +1,16 @@
set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
# when REGISTRY_VIEW is not specified, should not be defined in module
set (EXPECTED_REGISTRY_VIEW "UNDEFINED")
find_package(RegistryView)
# query package to check if variable is propagated correctly
set(EXPECTED_REGISTRY_VIEW "TARGET")
find_package(RegistryView REGISTRY_VIEW TARGET)
set(EXPECTED_REGISTRY_VIEW "64_32")
find_package(RegistryView REGISTRY_VIEW 64_32)
set(EXPECTED_REGISTRY_VIEW "32")
find_package(RegistryView REGISTRY_VIEW 32)
@@ -0,0 +1 @@
1
@@ -0,0 +1,4 @@
CMake Error at REGISTRY_VIEW-wrong-view.cmake:[0-9]+ \(find_package\):
find_package given invalid value for "REGISTRY_VIEW": WRONG_VIEW
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
@@ -0,0 +1,2 @@
find_package(result NAMES input.txt REGISTRY_VIEW WRONG_VIEW)
@@ -0,0 +1,216 @@
# helper macro for test clean-up
macro(CLEAN)
unset(RegistryView_DIR CACHE)
unset(RegistryView_FOUND)
unset(RegistryView64_DIR CACHE)
unset(RegistryView64_FOUND)
unset(RegistryView32_DIR CACHE)
unset(RegistryView32_FOUND)
endmacro()
cmake_policy(SET CMP0134 NEW)
# HKCU/Software/Classes/CLSID/CMake-Tests/find_package: Query default value
set(FILE_DIR "[HKCU/Software/Classes/CLSID/CMake-Tests/find_package]")
set(FILE_DIR2 "[HKCU/Software/Classes/CLSID/CMake-Tests/find_package;(default)]")
set(EXPECTED_LOCATION "default.${ARCH}")
find_package(RegistryView PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REQUIRED NO_DEFAULT_PATH)
clean()
# query value using special name should be identical to default value
find_package(RegistryView PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR2}" REQUIRED NO_DEFAULT_PATH)
clean()
find_package(RegistryView PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW HOST REQUIRED NO_DEFAULT_PATH)
clean()
# VIEW TARGET should have same value as VIEW HOST
find_package(RegistryView PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW TARGET REQUIRED NO_DEFAULT_PATH)
clean()
if (ARCH STREQUAL "64bit")
set(EXPECTED_LOCATION "default.64bit")
find_package(RegistryView PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64 REQUIRED NO_DEFAULT_PATH)
clean()
set(EXPECTED_LOCATION "default.32bit")
find_package(RegistryView PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32 REQUIRED NO_DEFAULT_PATH)
clean()
set(EXPECTED_LOCATION "default.64bit")
find_package(RegistryView PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_DEFAULT_PATH)
clean()
set(EXPECTED_LOCATION "default.32bit")
find_package(RegistryView PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_DEFAULT_PATH)
clean()
# check the second view is taken into account
set(EXPECTED_LOCATION "default.32bit")
find_package(RegistryView32 PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_DEFAULT_PATH)
clean()
set(EXPECTED_LOCATION "default.64bit")
find_package(RegistryView64 PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_DEFAULT_PATH)
clean()
# check the both views are taken into account
set(EXPECTED_LOCATION "default.32bit")
find_package(RegistryView32 PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_DEFAULT_PATH)
clean()
set(EXPECTED_LOCATION "default.64bit")
find_package(RegistryView64 PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_DEFAULT_PATH)
clean()
else() # 32bit
# no 64bit registry: file not found
find_package(RegistryView PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64 NO_DEFAULT_PATH)
if (RegistryView_FOUND)
message (SEND_ERROR "Unexpectedly found file '${RegistryView_DIR}/RegistryViewConfog.cmake'")
endif()
clean()
set(EXPECTED_LOCATION "default.32bit")
find_package(RegistryView PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32 REQUIRED NO_DEFAULT_PATH)
clean()
# views 64_32 and 32_64 give same result
find_package(RegistryView PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_DEFAULT_PATH)
clean()
find_package(RegistryView PATHS "${CMAKE_ CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_DEFAULT_PATH)
clean()
# check the both views are usable on 32bit platforms
find_package(RegistryView PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_DEFAULT_PATH)
clean()
endif()
# HKCU/Software/Classes/CLSID/CMake-Tests/find_package: Query specific value
set(FILE_DIR "[{|}HKCU/Software/Classes/CLSID/CMake-Tests/find_package|FILE_DIR]")
set(FILE_DIR2 "[HKCU\\Software\\Classes\\CLSID\\CMake-Tests\\find_package;FILE_DIR]")
set(EXPECTED_LOCATION "${ARCH}")
find_package(RegistryView HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REQUIRED NO_DEFAULT_PATH)
clean()
# query value using special name should be identical to default value
find_package(RegistryView HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR2}" REQUIRED NO_DEFAULT_PATH)
clean()
find_package(RegistryView HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW HOST REQUIRED NO_DEFAULT_PATH)
clean()
# VIEW TARGET should have same value as VIEW HOST
find_package(RegistryView HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW TARGET REQUIRED NO_DEFAULT_PATH)
clean()
if (ARCH STREQUAL "64bit")
set(EXPECTED_LOCATION "64bit")
find_package(RegistryView HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64 REQUIRED NO_DEFAULT_PATH)
clean()
set(EXPECTED_LOCATION "32bit")
find_package(RegistryView HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32 REQUIRED NO_DEFAULT_PATH)
clean()
set(EXPECTED_LOCATION "64bit")
find_package(RegistryView HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_DEFAULT_PATH)
clean()
set(EXPECTED_LOCATION "32bit")
find_package(RegistryView HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_DEFAULT_PATH)
clean()
# check the second view is taken into account
find_package(RegistryView32 HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_DEFAULT_PATH)
clean()
set(EXPECTED_LOCATION "64bit")
find_package(RegistryView64 HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_DEFAULT_PATH)
clean()
# check the both views are taken into account
set(EXPECTED_LOCATION "32bit")
find_package(RegistryView32 HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_DEFAULT_PATH)
clean()
set(EXPECTED_LOCATION "64bit")
find_package(RegistryView64 NAMES HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_DEFAULT_PATH)
clean()
else() # 32bit
# no 64bit registry: file not found
find_package(RegistryView HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64 NO_DEFAULT_PATH)
if (RegistryView_FOUND)
message (SEND_ERROR "Unexpectedly found file '${RegistryView_DIR}/RegistryViewConfog.cmake'")
endif()
clean()
set(EXPECTED_LOCATION "32bit")
find_package(RegistryView HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32 REQUIRED NO_DEFAULT_PATH)
clean()
find_package(RegistryView HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_DEFAULT_PATH)
clean()
find_package(RegistryView HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_DEFAULT_PATH)
clean()
# check the both views are taken into account
find_package(RegistryView HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_DEFAULT_PATH)
clean()
endif()
if (ARCH STREQUAL "64bit")
# Check influence of variable CMAKE_SIZEOF_VOID_P
set(CMAKE_SIZEOF_VOID_P 8)
set(EXPECTED_LOCATION "64bit")
find_package(RegistryView PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW TARGET)
clean()
find_package(RegistryView PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW HOST)
clean()
set(CMAKE_SIZEOF_VOID_P 4)
set(EXPECTED_LOCATION "32bit")
find_package(RegistryView PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW TARGET)
clean()
set(EXPECTED_LOCATION "64bit")
find_package(RegistryView PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW HOST)
clean()
unset(CMAKE_SIZEOF_VOID_P)
# Check influence of CMP0134 policy with OLD value
cmake_policy(SET CMP0134 OLD)
# CMAKE_SIZEOF_VOID_P is not set, so search first 32bit registry
set(EXPECTED_LOCATION "32bit")
find_package(RegistryView PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}")
clean()
cmake_policy(SET CMP0134 NEW)
# CMAKE_SIZEOF_VOID_P is not set, so search first the HOST architecture registry
set(EXPECTED_LOCATION "64bit")
find_package(RegistryView PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}")
clean()
endif()
@@ -51,8 +51,38 @@ run_cmake(VersionRangeConfigStd2)
run_cmake_with_options(IgnoreInstallPrefix "-DCMAKE_INSTALL_PREFIX=${RunCMake_SOURCE_DIR}/PackageRoot/foo/cmake_root")
run_cmake(IgnorePath)
run_cmake(IgnorePrefixPath)
run_cmake(REGISTRY_VIEW-no-view)
run_cmake(REGISTRY_VIEW-wrong-view)
run_cmake(REGISTRY_VIEW-propagated)
if(UNIX
AND NOT MSYS # FIXME: This works on CYGWIN but not on MSYS
)
run_cmake(SetFoundResolved)
endif()
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
# Tests using the Windows registry
find_program(REG NAMES "reg.exe" NO_CACHE)
if (REG)
## check host architecture
cmake_host_system_information(RESULT result QUERY WINDOWS_REGISTRY "HKCU" SUBKEYS VIEW 64 ERROR_VARIABLE status)
if (status STREQUAL "")
set(ARCH "64bit")
else()
set(ARCH "32bit")
endif()
# crete some entries in the registry
cmake_path(CONVERT "${RunCMake_SOURCE_DIR}/registry_host${ARCH}.reg" TO_NATIVE_PATH_LIST registry_data)
execute_process(COMMAND "${REG}" import "${registry_data}" OUTPUT_QUIET ERROR_QUIET)
run_cmake_with_options(Registry-query -DARCH=${ARCH})
# clean-up registry
execute_process(COMMAND "${REG}" delete "HKCU\\SOFTWARE\\Classes\\CLSID\\CMake-Tests\\find_package" /f OUTPUT_QUIET ERROR_QUIET)
if (ARCH STREQUAL "64bit")
execute_process(COMMAND "${REG}" delete "HKCU\\SOFTWARE\\Classes\\WOW6432Node\\CLSID\\CMake-Tests\\find_package" /f OUTPUT_QUIET ERROR_QUIET)
endif()
endif()
endif()
@@ -0,0 +1,4 @@
if (NOT EXPECTED_LOCATION STREQUAL "default.32bit")
message (SEND_ERROR "RegistryViewConfig: location is 'default.32bit' but expects '${EXPECTED_LOCATION}'")
endif()
@@ -0,0 +1,4 @@
if (NOT EXPECTED_LOCATION STREQUAL "default.32bit")
message (SEND_ERROR "RegistryViewConfig: location is 'default.32bit' but expects '${EXPECTED_LOCATION}'")
endif()
@@ -0,0 +1,4 @@
if (NOT EXPECTED_LOCATION STREQUAL "default.64bit")
message (SEND_ERROR "RegistryViewConfig: location is 'default.64bit' but expects '${EXPECTED_LOCATION}'")
endif()
@@ -0,0 +1,4 @@
if (NOT EXPECTED_LOCATION STREQUAL "default.64bit")
message (SEND_ERROR "RegistryViewConfig: location is 'default.64bit' but expects '${EXPECTED_LOCATION}'")
endif()
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
1
@@ -0,0 +1,4 @@
CMake Error at REGISTRY_VIEW-no-view.cmake:[0-9]+ \(find_path\):
find_path missing required argument for "REGISTRY_VIEW"
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
@@ -0,0 +1,2 @@
find_path(result NAMES input.txt REGISTRY_VIEW)
@@ -0,0 +1 @@
1
@@ -0,0 +1,4 @@
CMake Error at REGISTRY_VIEW-wrong-view.cmake:[0-9]+ \(find_path\):
find_path given invalid value for "REGISTRY_VIEW": WRONG_VIEW
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
@@ -0,0 +1,2 @@
find_path(result NAMES input.txt REGISTRY_VIEW WRONG_VIEW)
@@ -0,0 +1,218 @@
# helper function for test validation
function(CHECK query result expression)
cmake_language(EVAL CODE
"if (NOT (${expression}))
message(SEND_ERROR \"wrong value for query '${query}': '${result}'\")
endif()")
endfunction()
cmake_policy(SET CMP0134 NEW)
# HKCU/Software/Classes/CLSID/CMake-Tests/find_path: Query default value
set(FILE_DIR "[HKCU/Software/Classes/CLSID/CMake-Tests/find_path]")
set(FILE_DIR2 "[HKCU/Software/Classes/CLSID/CMake-Tests/find_path;(default)]")
unset(result)
find_path(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.${ARCH}/$\"")
# query value using special name should be identical to default value
unset(result)
find_path(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR2}" REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR2}" "${result}" "result MATCHES \"default.${ARCH}/$\"")
unset(result)
find_path(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW HOST REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.${ARCH}/$\"")
# VIEW TARGET should have same value as VIEW HOST
unset(result2)
find_path(result2 NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW TARGET REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result2}" "result2 STREQUAL result")
if (ARCH STREQUAL "64bit")
unset(result)
find_path(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.64bit/$\"")
unset(result)
find_path(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/$\"")
unset(result)
find_path(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.64bit/$\"")
unset(result)
find_path(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/$\"")
# check the second view is taken into account
unset(result)
find_path(result NAMES file32bit.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/$\"")
unset(result)
find_path(result NAMES file64bit.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.64bit/$\"")
# check the both views are taken into account
unset(result)
find_path(result NAMES file32bit.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/$\"")
unset(result)
find_path(result NAMES file64bit.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.64bit/$\"")
else() # 32bit
# no 64bit registry: file not found
unset(result)
find_path(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64 NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"result-NOTFOUND$\"")
unset(result)
find_path(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/$\"")
# views 64_32 and 32_64 give same result
unset(result)
find_path(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/$\"")
unset(result)
find_path(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/$\"")
# check the both views are usable on 32bit platforms
unset(result)
find_path(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"default.32bit/$\"")
endif()
# HKCU/Software/Classes/CLSID/CMake-Tests/find_path: Query specific value
set(FILE_DIR "[{|}HKCU/Software/Classes/CLSID/CMake-Tests/find_path|FILE_DIR]")
set(FILE_DIR2 "[HKCU\\Software\\Classes\\CLSID\\CMake-Tests\\find_path;FILE_DIR]")
unset(result)
find_path(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" NO_CACHE REQUIRED NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/${ARCH}/$\"")
# query value using special name should be identical to default value
unset(result)
find_path(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR2}" NO_CACHE REQUIRED NO_DEFAULT_PATH)
check("${FILE_DIR2}" "${result}" "result MATCHES \"/${ARCH}/$\"")
unset(result)
find_path(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW HOST REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/${ARCH}/$\"")
# VIEW TARGET should have same value as VIEW HOST
unset(result2)
find_path(result2 NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW TARGET REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result2}" "result2 STREQUAL result")
if (ARCH STREQUAL "64bit")
unset(result)
find_path(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/64bit/$\"")
unset(result)
find_path(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/$\"")
unset(result)
find_path(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/64bit/$\"")
unset(result)
find_path(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/$\"")
# check the second view is taken into account
unset(result)
find_path(result NAMES file32bit.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/$\"")
unset(result)
find_path(result NAMES file64bit.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/64bit/$\"")
# check the both views are taken into account
unset(result)
find_path(result NAMES file32bit.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/$\"")
unset(result)
find_path(result NAMES file64bit.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/64bit/$\"")
else() # 32bit
# no 64bit registry: file not found
unset(result)
find_path(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64 NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"result-NOTFOUND$\"")
unset(result)
find_path(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/$\"")
unset(result)
find_path(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 64_32 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/$\"")
unset(result)
find_path(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW 32_64 REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/$\"")
unset(result)
find_path(result NAMES file.txt HINTS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW BOTH REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/$\"")
endif()
if (ARCH STREQUAL "64bit")
# Check influence of variable CMAKE_SIZEOF_VOID_P
set(CMAKE_SIZEOF_VOID_P 8)
unset(result)
find_path(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW TARGET REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/64bit/$\"")
unset(result)
find_path(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW HOST REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/${ARCH}/$\"")
set(CMAKE_SIZEOF_VOID_P 4)
unset(result)
find_path(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW TARGET REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/$\"")
unset(result)
find_path(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" REGISTRY_VIEW HOST REQUIRED NO_CACHE NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/${ARCH}/$\"")
unset(CMAKE_SIZEOF_VOID_P)
# Check influence of CMP0134 policy with OLD value
cmake_policy(SET CMP0134 OLD)
# CMAKE_SIZEOF_VOID_P is not set, so search first 32bit registry
unset(result)
find_path(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" NO_CACHE REQUIRED NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/32bit/$\"")
cmake_policy(SET CMP0134 NEW)
# CMAKE_SIZEOF_VOID_P is not set, so search first the HOST architecture registry
unset(result)
find_path(result NAMES file.txt PATHS "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_DIR}" NO_CACHE REQUIRED NO_DEFAULT_PATH)
check("${FILE_DIR}" "${result}" "result MATCHES \"/${ARCH}/$\"")
endif()
@@ -5,9 +5,37 @@ run_cmake(FromPATHEnv)
run_cmake(PrefixInPATH)
run_cmake(Required)
run_cmake(NO_CACHE)
run_cmake(REGISTRY_VIEW-no-view)
run_cmake(REGISTRY_VIEW-wrong-view)
if(APPLE)
run_cmake(FrameworksWithSubdirs)
endif()
run_cmake_with_options(FromPATHEnvDebugVar --debug-find-var=PATH_IN_ENV_PATH)
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
# Tests using the Windows registry
find_program(REG NAMES "reg.exe" NO_CACHE)
if (REG)
## check host architecture
cmake_host_system_information(RESULT result QUERY WINDOWS_REGISTRY "HKCU" SUBKEYS VIEW 64 ERROR_VARIABLE status)
if (status STREQUAL "")
set(ARCH "64bit")
else()
set(ARCH "32bit")
endif()
# crete some entries in the registry
cmake_path(CONVERT "${RunCMake_SOURCE_DIR}/registry_host${ARCH}.reg" TO_NATIVE_PATH_LIST registry_data)
execute_process(COMMAND "${REG}" import "${registry_data}" OUTPUT_QUIET ERROR_QUIET)
run_cmake_with_options(Registry-query -DARCH=${ARCH})
# clean-up registry
execute_process(COMMAND "${REG}" delete "HKCU\\SOFTWARE\\Classes\\CLSID\\CMake-Tests\\find_path" /f OUTPUT_QUIET ERROR_QUIET)
if (ARCH STREQUAL "64bit")
execute_process(COMMAND "${REG}" delete "HKCU\\SOFTWARE\\Classes\\WOW6432Node\\CLSID\\CMake-Tests\\find_path" /f OUTPUT_QUIET ERROR_QUIET)
endif()
endif()
endif()
Binary file not shown.
Binary file not shown.
View File
View File
View File
View File

Some files were not shown because too many files have changed in this diff Show More