mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-11 16:32:14 -06:00
cmake: Preserve symlinks in references to itself when possible
CMake's tools search relative to their own locations to find their
resources. Previously they always started at their own `realpath()`.
The intention was to support invocation through symbolic links to the
binaries where the resources can only be found under the real prefix:
/logical/prefix/bin/cmake -> /real/prefix/bin/cmake
/real/prefix/share/cmake
The generated build system refers to CMake's own tools and resources
through the `/real/prefix`. This is not desirable in the case that the
`/logical/prefix` is meant as the canonical location and uses symbolic
links for both tools and resources as an implementation detail:
/logical/prefix/bin/cmake -> /real/prefix/bin/cmake
/logical/prefix/share/cmake -> /real/prefix/share/cmake
In this case, the generated build system should refer to CMake's own
tools and resources through the `/logical/prefix`. This way the
`/real/prefix` can be changed, and the symbolic links updated,
without breaking already-generated build systems.
Fixes: #19849
Fixes: #21059
Inspired-by: Carlo Cabrera <github@carlo.cab>
Inspired-by: Rodger Combs <rodger.combs@gmail.com>
This commit is contained in:
@@ -2695,7 +2695,6 @@ std::string FindOwnExecutable(const char* argv0)
|
||||
wchar_t modulepath[_MAX_PATH];
|
||||
::GetModuleFileNameW(nullptr, modulepath, sizeof(modulepath));
|
||||
std::string exe = cmsys::Encoding::ToNarrow(modulepath);
|
||||
exe = cmSystemTools::GetRealPath(exe);
|
||||
#elif defined(__APPLE__)
|
||||
static_cast<void>(argv0);
|
||||
# define CM_EXE_PATH_LOCAL_SIZE 16384
|
||||
@@ -2715,7 +2714,6 @@ std::string FindOwnExecutable(const char* argv0)
|
||||
if (exe_path != exe_path_local) {
|
||||
free(exe_path);
|
||||
}
|
||||
exe = cmSystemTools::GetRealPath(exe);
|
||||
if (IsCMakeAppBundleExe(exe)) {
|
||||
// The executable is inside an application bundle.
|
||||
// The install tree has "..<CMAKE_BIN_DIR>/cmake-gui".
|
||||
@@ -2735,12 +2733,34 @@ std::string FindOwnExecutable(const char* argv0)
|
||||
if (!cmSystemTools::FindProgramPath(argv0, exe, errorMsg)) {
|
||||
// ???
|
||||
}
|
||||
exe = cmSystemTools::GetRealPath(exe);
|
||||
#endif
|
||||
exe = cmSystemTools::ToNormalizedPathOnDisk(std::move(exe));
|
||||
return exe;
|
||||
}
|
||||
|
||||
#ifndef CMAKE_BOOTSTRAP
|
||||
bool ResolveSymlinkToOwnExecutable(std::string& exe, std::string& exe_dir)
|
||||
{
|
||||
std::string linked_exe;
|
||||
if (!cmSystemTools::ReadSymlink(exe, linked_exe)) {
|
||||
return false;
|
||||
}
|
||||
# if defined(__APPLE__)
|
||||
// Ignore "cmake-gui -> ../MacOS/CMake".
|
||||
if (IsCMakeAppBundleExe(linked_exe)) {
|
||||
return false;
|
||||
}
|
||||
# endif
|
||||
if (cmSystemTools::FileIsFullPath(linked_exe)) {
|
||||
exe = std::move(linked_exe);
|
||||
} else {
|
||||
exe = cmStrCat(exe_dir, '/', std::move(linked_exe));
|
||||
}
|
||||
exe = cmSystemTools::ToNormalizedPathOnDisk(std::move(exe));
|
||||
exe_dir = cmSystemTools::GetFilenamePath(exe);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FindCMakeResourcesInInstallTree(std::string const& exe_dir)
|
||||
{
|
||||
// Install tree has
|
||||
@@ -2808,7 +2828,11 @@ void cmSystemTools::FindCMakeResources(const char* argv0)
|
||||
#else
|
||||
// Find resources relative to our own executable.
|
||||
std::string exe_dir = cmSystemTools::GetFilenamePath(exe);
|
||||
if (!FindCMakeResourcesInInstallTree(exe_dir)) {
|
||||
bool found = false;
|
||||
do {
|
||||
found = FindCMakeResourcesInInstallTree(exe_dir);
|
||||
} while (!found && ResolveSymlinkToOwnExecutable(exe, exe_dir));
|
||||
if (!found) {
|
||||
FindCMakeResourcesInBuildTree(exe_dir);
|
||||
}
|
||||
cmSystemToolsCMakeCommand =
|
||||
|
||||
Reference in New Issue
Block a user