From 4df119773c18280c0bb16fc87312c8144fc1c3f8 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 13 Apr 2011 10:36:45 -0400 Subject: [PATCH 1/7] find_package: Rename implementation of user package registry Rename {Registry => UserRegistry} in names associated specifically with the user package registry and not registry access in general. --- Source/cmFindPackageCommand.cxx | 10 +++++----- Source/cmFindPackageCommand.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index d3c4bc7e4..aaf95fb3e 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -54,7 +54,7 @@ cmFindPackageCommand::cmFindPackageCommand() this->CMakePathName = "PACKAGE"; this->Quiet = false; this->Required = false; - this->NoRegistry = false; + this->NoUserRegistry = false; this->NoBuilds = false; this->NoModule = false; this->DebugMode = false; @@ -444,7 +444,7 @@ bool cmFindPackageCommand } else if(args[i] == "NO_CMAKE_PACKAGE_REGISTRY") { - this->NoRegistry = true; + this->NoUserRegistry = true; this->NoModule = true; this->Compatibility_1_6 = false; doing = DoingNone; @@ -1181,7 +1181,7 @@ void cmFindPackageCommand::ComputePrefixes() this->AddPrefixesCMakeEnvironment(); this->AddPrefixesUserHints(); this->AddPrefixesSystemEnvironment(); - this->AddPrefixesRegistry(); + this->AddPrefixesUserRegistry(); this->AddPrefixesBuilds(); this->AddPrefixesCMakeSystemVariable(); this->AddPrefixesUserGuess(); @@ -1249,9 +1249,9 @@ void cmFindPackageCommand::AddPrefixesSystemEnvironment() } //---------------------------------------------------------------------------- -void cmFindPackageCommand::AddPrefixesRegistry() +void cmFindPackageCommand::AddPrefixesUserRegistry() { - if(this->NoRegistry || this->NoDefaultPath) + if(this->NoUserRegistry || this->NoDefaultPath) { return; } diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h index 19d2b1099..a76b25c25 100644 --- a/Source/cmFindPackageCommand.h +++ b/Source/cmFindPackageCommand.h @@ -87,7 +87,7 @@ private: void AddPrefixesCMakeEnvironment(); void AddPrefixesCMakeVariable(); void AddPrefixesSystemEnvironment(); - void AddPrefixesRegistry(); + void AddPrefixesUserRegistry(); void AddPrefixesBuilds(); void AddPrefixesCMakeSystemVariable(); void AddPrefixesUserGuess(); @@ -132,7 +132,7 @@ private: bool Required; bool Compatibility_1_6; bool NoModule; - bool NoRegistry; + bool NoUserRegistry; bool NoBuilds; bool DebugMode; bool UseLib64Paths; From c9563dbe1aaee196b6e69926ae66234dd2d6fa22 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 13 Apr 2011 11:00:06 -0400 Subject: [PATCH 2/7] find_package: Cleanup user package registry less aggressively Delete only REG_SZ entries that are specifically detected to point to invalid paths. This will allow future versions to add other value types for different purposes. --- Source/cmFindPackageCommand.cxx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index aaf95fb3e..d2d395652 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -1308,13 +1308,12 @@ void cmFindPackageCommand::LoadPackageRegistryWin() { data[dataSize] = 0; cmsys_ios::stringstream ss(&data[0]); - if(this->CheckPackageRegistryEntry(ss)) + if(!this->CheckPackageRegistryEntry(ss)) { - // The entry is okay. - continue; + // The entry is invalid. + bad.insert(name); } } - bad.insert(name); break; case ERROR_MORE_DATA: data.resize(dataSize+1); From 549458f280b19189e78f3d9dcae2be22854b1178 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 13 Apr 2011 13:10:08 -0400 Subject: [PATCH 3/7] find_package: Document user package registry locations Specify the Windows registry key under HKEY_CURRENT_USER and directory on UNIX platforms in which the package registry is stored. --- Source/cmFindPackageCommand.cxx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index d2d395652..5cc5683ab 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -299,9 +299,16 @@ void cmFindPackageCommand::GenerateDocumentation() "dependent projects one after another.\n" "6. Search paths stored in the CMake user package registry. " "This can be skipped if NO_CMAKE_PACKAGE_REGISTRY is passed. " - "Paths are stored in the registry when CMake configures a project " - "that invokes export(PACKAGE ). " - "See the export(PACKAGE) command documentation for more details." + "On Windows a may appear under registry key\n" + " HKEY_CURRENT_USER\\Software\\Kitware\\CMake\\Packages\\\n" + "as a REG_SZ value, with arbitrary name, that specifies the directory " + "containing the package configuration file. " + "On UNIX platforms a may appear under the directory\n" + " ~/.cmake/packages/\n" + "as a file, with arbitrary name, whose content specifies the directory " + "containing the package configuration file. " + "See the export(PACKAGE) command to create user package registry entries " + "for project build trees." "\n" "7. Search cmake variables defined in the Platform files " "for the current system. This can be skipped if NO_CMAKE_SYSTEM_PATH " From a0d76c10a72fb1cdb551f729bd8c74493543a6c7 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 13 Apr 2011 13:14:41 -0400 Subject: [PATCH 4/7] find_package: Search a "system package registry" Generalize the "user package registry" created by commit ed0650f6 (Teach find_package to search a "package registry", 2009-09-01). Define a corresponding "system" registry key under HKEY_LOCAL_MACHINE. This gives package installers a place to create a registry value that points at the right location for find_package() to locate the package. --- Source/cmFindPackageCommand.cxx | 49 ++++++++++++++++++++++++--------- Source/cmFindPackageCommand.h | 4 ++- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 5cc5683ab..daf71d4cd 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -55,6 +55,7 @@ cmFindPackageCommand::cmFindPackageCommand() this->Quiet = false; this->Required = false; this->NoUserRegistry = false; + this->NoSystemRegistry = false; this->NoBuilds = false; this->NoModule = false; this->DebugMode = false; @@ -140,6 +141,7 @@ void cmFindPackageCommand::GenerateDocumentation() " [NO_CMAKE_PACKAGE_REGISTRY]\n" " [NO_CMAKE_BUILDS_PATH]\n" " [NO_CMAKE_SYSTEM_PATH]\n" + " [NO_CMAKE_SYSTEM_PACKAGE_REGISTRY]\n" " [CMAKE_FIND_ROOT_PATH_BOTH |\n" " ONLY_CMAKE_FIND_ROOT_PATH |\n" " NO_CMAKE_FIND_ROOT_PATH])\n" @@ -316,7 +318,15 @@ void cmFindPackageCommand::GenerateDocumentation() " CMAKE_SYSTEM_PREFIX_PATH\n" " CMAKE_SYSTEM_FRAMEWORK_PATH\n" " CMAKE_SYSTEM_APPBUNDLE_PATH\n" - "8. Search paths specified by the PATHS option. " + "8. Search paths stored in the CMake system package registry. " + "This can be skipped if NO_CMAKE_SYSTEM_PACKAGE_REGISTRY is passed. " + "On Windows a may appear under registry key\n" + " HKEY_LOCAL_MACHINE\\Software\\Kitware\\CMake\\Packages\\\n" + "as a REG_SZ value, with arbitrary name, that specifies the directory " + "containing the package configuration file. " + "There is no system package registry on non-Windows platforms." + "\n" + "9. Search paths specified by the PATHS option. " "These are typically hard-coded guesses.\n" ; this->CommandDocumentation += this->GenericDocumentationMacPolicy; @@ -456,6 +466,13 @@ bool cmFindPackageCommand this->Compatibility_1_6 = false; doing = DoingNone; } + else if(args[i] == "NO_CMAKE_SYSTEM_PACKAGE_REGISTRY") + { + this->NoSystemRegistry = true; + this->NoModule = true; + this->Compatibility_1_6 = false; + doing = DoingNone; + } else if(args[i] == "NO_CMAKE_BUILDS_PATH") { this->NoBuilds = true; @@ -1191,6 +1208,7 @@ void cmFindPackageCommand::ComputePrefixes() this->AddPrefixesUserRegistry(); this->AddPrefixesBuilds(); this->AddPrefixesCMakeSystemVariable(); + this->AddPrefixesSystemRegistry(); this->AddPrefixesUserGuess(); this->ComputeFinalPrefixes(); } @@ -1264,7 +1282,7 @@ void cmFindPackageCommand::AddPrefixesUserRegistry() } #if defined(_WIN32) && !defined(__CYGWIN__) - this->LoadPackageRegistryWin(); + this->LoadPackageRegistryWin(true); #elif defined(__HAIKU__) BPath dir; if (find_directory(B_USER_SETTINGS_DIRECTORY, &dir) == B_OK) @@ -1284,17 +1302,30 @@ void cmFindPackageCommand::AddPrefixesUserRegistry() #endif } +//---------------------------------------------------------------------------- +void cmFindPackageCommand::AddPrefixesSystemRegistry() +{ + if(this->NoSystemRegistry || this->NoDefaultPath) + { + return; + } + +#if defined(_WIN32) && !defined(__CYGWIN__) + this->LoadPackageRegistryWin(false); +#endif +} + #if defined(_WIN32) && !defined(__CYGWIN__) # include # undef GetCurrentDirectory //---------------------------------------------------------------------------- -void cmFindPackageCommand::LoadPackageRegistryWin() +void cmFindPackageCommand::LoadPackageRegistryWin(bool user) { std::string key = "Software\\Kitware\\CMake\\Packages\\"; key += this->Name; std::set bad; HKEY hKey; - if(RegOpenKeyEx(HKEY_CURRENT_USER, key.c_str(), + if(RegOpenKeyEx(user? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, key.c_str(), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) { DWORD valueType = REG_NONE; @@ -1332,7 +1363,7 @@ void cmFindPackageCommand::LoadPackageRegistryWin() } // Remove bad values if possible. - if(!bad.empty() && + if(user && !bad.empty() && RegOpenKeyEx(HKEY_CURRENT_USER, key.c_str(), 0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS) { @@ -2292,11 +2323,3 @@ bool cmFindPackageCommand::SearchAppBundlePrefix(std::string const& prefix_in) } // TODO: Debug cmsys::Glob double slash problem. - -// TODO: Add registry entries after cmake system search path? -// Currently the user must specify them with the PATHS option. -// -// [HKEY_CURRENT_USER\Software\*\Foo*;InstallDir] -// [HKEY_CURRENT_USER\Software\*\*\Foo*;InstallDir] -// [HKEY_LOCAL_MACHINE\Software\*\Foo*;InstallDir] -// [HKEY_LOCAL_MACHINE\Software\*\*\Foo*;InstallDir] diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h index a76b25c25..fa3fd4f25 100644 --- a/Source/cmFindPackageCommand.h +++ b/Source/cmFindPackageCommand.h @@ -88,13 +88,14 @@ private: void AddPrefixesCMakeVariable(); void AddPrefixesSystemEnvironment(); void AddPrefixesUserRegistry(); + void AddPrefixesSystemRegistry(); void AddPrefixesBuilds(); void AddPrefixesCMakeSystemVariable(); void AddPrefixesUserGuess(); void AddPrefixesUserHints(); void ComputeFinalPrefixes(); void LoadPackageRegistryDir(std::string const& dir); - void LoadPackageRegistryWin(); + void LoadPackageRegistryWin(bool user); bool CheckPackageRegistryEntry(std::istream& is); bool SearchDirectory(std::string const& dir); bool CheckDirectory(std::string const& dir); @@ -133,6 +134,7 @@ private: bool Compatibility_1_6; bool NoModule; bool NoUserRegistry; + bool NoSystemRegistry; bool NoBuilds; bool DebugMode; bool UseLib64Paths; From b95f3cac91488f754bfef183e391c1dae03ba406 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 13 Apr 2011 13:17:42 -0400 Subject: [PATCH 5/7] find_package: Check both 32-bit and 64-bit registry views The system package registry is under HKEY_LOCAL_MACHINE\SOFTWARE which has separate views for 32-bit and 64-bit applications. Look in both views, but prefer the architecture matching the build target platform. --- Source/cmFindPackageCommand.cxx | 42 +++++++++++++++++++++++++++++---- Source/cmFindPackageCommand.h | 4 +++- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index daf71d4cd..b77273c3a 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -1282,7 +1282,7 @@ void cmFindPackageCommand::AddPrefixesUserRegistry() } #if defined(_WIN32) && !defined(__CYGWIN__) - this->LoadPackageRegistryWin(true); + this->LoadPackageRegistryWinUser(); #elif defined(__HAIKU__) BPath dir; if (find_directory(B_USER_SETTINGS_DIRECTORY, &dir) == B_OK) @@ -1311,22 +1311,54 @@ void cmFindPackageCommand::AddPrefixesSystemRegistry() } #if defined(_WIN32) && !defined(__CYGWIN__) - this->LoadPackageRegistryWin(false); + this->LoadPackageRegistryWinSystem(); #endif } #if defined(_WIN32) && !defined(__CYGWIN__) # include # undef GetCurrentDirectory + // http://msdn.microsoft.com/en-us/library/aa384253%28v=vs.85%29.aspx +# if !defined(KEY_WOW64_32KEY) +# define KEY_WOW64_32KEY 0x0200 +# endif +# if !defined(KEY_WOW64_64KEY) +# define KEY_WOW64_64KEY 0x0100 +# endif //---------------------------------------------------------------------------- -void cmFindPackageCommand::LoadPackageRegistryWin(bool user) +void cmFindPackageCommand::LoadPackageRegistryWinUser() +{ + // HKEY_CURRENT_USER\\Software shares 32-bit and 64-bit views. + this->LoadPackageRegistryWin(true, 0); +} + +//---------------------------------------------------------------------------- +void cmFindPackageCommand::LoadPackageRegistryWinSystem() +{ + // HKEY_LOCAL_MACHINE\\SOFTWARE has separate 32-bit and 64-bit views. + // Prefer the target platform view first. + if(this->Makefile->PlatformIs64Bit()) + { + this->LoadPackageRegistryWin(false, KEY_WOW64_64KEY); + this->LoadPackageRegistryWin(false, KEY_WOW64_32KEY); + } + else + { + this->LoadPackageRegistryWin(false, KEY_WOW64_32KEY); + this->LoadPackageRegistryWin(false, KEY_WOW64_64KEY); + } +} + +//---------------------------------------------------------------------------- +void cmFindPackageCommand::LoadPackageRegistryWin(bool user, + unsigned int view) { std::string key = "Software\\Kitware\\CMake\\Packages\\"; key += this->Name; std::set bad; HKEY hKey; if(RegOpenKeyEx(user? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, key.c_str(), - 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) + 0, KEY_QUERY_VALUE|view, &hKey) == ERROR_SUCCESS) { DWORD valueType = REG_NONE; char name[16384]; @@ -1365,7 +1397,7 @@ void cmFindPackageCommand::LoadPackageRegistryWin(bool user) // Remove bad values if possible. if(user && !bad.empty() && RegOpenKeyEx(HKEY_CURRENT_USER, key.c_str(), - 0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS) + 0, KEY_SET_VALUE|view, &hKey) == ERROR_SUCCESS) { for(std::set::const_iterator vi = bad.begin(); vi != bad.end(); ++vi) diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h index fa3fd4f25..4229d375d 100644 --- a/Source/cmFindPackageCommand.h +++ b/Source/cmFindPackageCommand.h @@ -95,7 +95,9 @@ private: void AddPrefixesUserHints(); void ComputeFinalPrefixes(); void LoadPackageRegistryDir(std::string const& dir); - void LoadPackageRegistryWin(bool user); + void LoadPackageRegistryWinUser(); + void LoadPackageRegistryWinSystem(); + void LoadPackageRegistryWin(bool user, unsigned int view); bool CheckPackageRegistryEntry(std::istream& is); bool SearchDirectory(std::string const& dir); bool CheckDirectory(std::string const& dir); From 93021adb732106776458caac8be99fa2c8609566 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 13 Apr 2011 14:28:00 -0400 Subject: [PATCH 6/7] find_package: Test system package registry when possible Teach the FindPackagTest to try creating the appropriate HKLM system package registry value. If it works then add a test to verify that find_package() reads it as expected. Then delete the value to cleanup. --- Tests/FindPackageTest/CMakeLists.txt | 41 +++++++++++++++++++ .../CMakeTestSystemPackageConfig.cmake | 1 + 2 files changed, 42 insertions(+) create mode 100644 Tests/FindPackageTest/SystemPackage/CMakeTestSystemPackageConfig.cmake diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt index d4984d7aa..9ac9eee0d 100644 --- a/Tests/FindPackageTest/CMakeLists.txt +++ b/Tests/FindPackageTest/CMakeLists.txt @@ -37,6 +37,38 @@ FIND_PACKAGE(VersionTestB 1.2) FIND_PACKAGE(VersionTestC 1.2.3) FIND_PACKAGE(VersionTestD 1.2.3.4) +#----------------------------------------------------------------------------- +# Test system package registry if possible. +SET(CMakeTestSystemPackage "") +IF(WIN32 AND NOT CYGWIN) + # Try writing a value to the system package registry. + FILE(TO_NATIVE_PATH "${FindPackageTest_SOURCE_DIR}/SystemPackage" _data) + SET(_key "HKLM\\Software\\Kitware\\CMake\\Packages\\CMakeTestSystemPackage") + SET(_file "${FindPackageTest_BINARY_DIR}/CMakeTestSystemPackage.data") + FILE(WRITE ${_file} "${_data}\n") + EXECUTE_PROCESS( + COMMAND ${CMAKE_COMMAND} -E md5sum ${_file} + OUTPUT_VARIABLE _output ERROR_VARIABLE _error RESULT_VARIABLE _failed + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + STRING(REGEX REPLACE " .*" "" _value "${_output}") + IF(NOT _failed AND _value) + EXECUTE_PROCESS( + COMMAND reg add "${_key}" /v "${_value}" /t REG_SZ /d "${_data}" /f + OUTPUT_VARIABLE _output ERROR_VARIABLE _output RESULT_VARIABLE _failed + ) + ENDIF() + # If the above worked, add the rest of the test and a rule to + # cleanup the value. + IF(NOT _failed) + MESSAGE(STATUS "HKLM is writable: enabling CMakeTestSystemPackage") + SET(CMakeTestSystemPackage_CLEANUP reg delete "${_key}" /v "${_value}" /f) + SET(CMakeTestSystemPackage CMakeTestSystemPackage) + ELSE() + MESSAGE(STATUS "HKLM is readonly: disabling CMakeTestSystemPackage") + ENDIF() +ENDIF() + #----------------------------------------------------------------------------- #SET(CMAKE_FIND_DEBUG_MODE 1) @@ -49,6 +81,7 @@ SET(PACKAGES wibbleA wibbleB RecursiveA RecursiveB RecursiveC EnvA EnvB + ${CMakeTestSystemPackage} ) FOREACH(p ${PACKAGES}) SET(${p}_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE) @@ -116,6 +149,13 @@ SET(ENV{EnvA_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/lib/zot-3.1") FIND_PACKAGE(EnvA 3.1 EXACT QUIET NAMES zot) # Should Work FIND_PACKAGE(EnvB 3.1 EXACT QUIET NAMES zot) # Should Fail +# Test system package registry if available. +IF(CMakeTestSystemPackage) + FIND_PACKAGE(CMakeTestSystemPackage) + EXECUTE_PROCESS(COMMAND ${CMakeTestSystemPackage_CLEANUP} + OUTPUT_VARIABLE _output ERROR_VARIABLE _error) +ENDIF() + # Expected locations at which packages should be found. SET(foo_EXPECTED "lib/foo-1.2/foo-config.cmake") SET(Foo_EXPECTED "lib/foo-1.2/CMake/FooConfig.cmake") @@ -145,6 +185,7 @@ SET(RecursiveB_EXPECTED "lib/zot-2.0/zot-config.cmake") SET(RecursiveC_EXPECTED "lib/zot-3.1/zot-config.cmake") SET(EnvA_EXPECTED "lib/zot-3.1/zot-config.cmake") SET(EnvB_MISSING "EnvB_DIR-NOTFOUND") +SET(CMakeTestSystemPackage_EXPECTED "SystemPackage/CMakeTestSystemPackageConfig.cmake") # Check the results. FOREACH(p ${PACKAGES}) diff --git a/Tests/FindPackageTest/SystemPackage/CMakeTestSystemPackageConfig.cmake b/Tests/FindPackageTest/SystemPackage/CMakeTestSystemPackageConfig.cmake new file mode 100644 index 000000000..deffa5729 --- /dev/null +++ b/Tests/FindPackageTest/SystemPackage/CMakeTestSystemPackageConfig.cmake @@ -0,0 +1 @@ +# Test config file. From 08b93977cffacc53f2c5b405f781efd035240175 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 14 Apr 2011 09:35:21 -0400 Subject: [PATCH 7/7] find_package: Fix system package registry test path conversion Do not use file(TO_NATIVE_PATH) to compute the value to store in the registry. It is meant for constructing values to be put in shells. Since find_package() can use the value with CMake-normalized slashes do not bother with any conversion. --- Tests/FindPackageTest/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt index 9ac9eee0d..89383a0eb 100644 --- a/Tests/FindPackageTest/CMakeLists.txt +++ b/Tests/FindPackageTest/CMakeLists.txt @@ -42,7 +42,7 @@ FIND_PACKAGE(VersionTestD 1.2.3.4) SET(CMakeTestSystemPackage "") IF(WIN32 AND NOT CYGWIN) # Try writing a value to the system package registry. - FILE(TO_NATIVE_PATH "${FindPackageTest_SOURCE_DIR}/SystemPackage" _data) + SET(_data "${FindPackageTest_SOURCE_DIR}/SystemPackage") SET(_key "HKLM\\Software\\Kitware\\CMake\\Packages\\CMakeTestSystemPackage") SET(_file "${FindPackageTest_BINARY_DIR}/CMakeTestSystemPackage.data") FILE(WRITE ${_file} "${_data}\n")