GNUInstallDirs: Fix double separator in /opt special-case absolute paths

Since commit 7566a477f7 (GNUInstallDirs: Factor out helper for special
absolute path logic, 2025-03-27, v4.1.0), when CMAKE_INSTALL_PREFIX is
under /opt/ (excluding /opt/homebrew), the special case FHS directories
include an extra path separator, resulting in values like /etc//opt/foo.
This is observed in CMAKE_INSTALL_FULL_SYSCONFDIR,
CMAKE_INSTALL_FULL_LOCALSTATEDIR, and CMAKE_INSTALL_FULL_RUNSTATEDIR
whenever their corresponding CMAKE_INSTALL_<dir> may be relative, as is
the case under policy CMP0192 OLD or if set explicitly while under
CMP0192 NEW (e.g. -DCMAKE_INSTALL_SYSCONFDIR=etc). Restore the previous
path calculation, which relies on the prefix starting with `/`.

Fixes: #28186
This commit is contained in:
Mike Matthews authored and Brad King committed 2026-10-20 14:12:09 -04:00
1 parent 69c0c40459
commit 0f585d056c
6 files changed
+27 -1

No files matched your search

+1 -1
View File
@@ -360,7 +360,7 @@ function(_GNUInstallDirs_special_absolute out_var original_path install_prefix)
if(install_prefix MATCHES "^/usr/?$")
set(${out_var} "/${original_path}")
elseif(install_prefix MATCHES "^/opt/" AND NOT install_prefix MATCHES "^/opt/homebrew/")
set(${out_var} "/${original_path}/${install_prefix}")
set(${out_var} "/${original_path}${install_prefix}")
endif()
return(PROPAGATE ${out_var})
@@ -0,0 +1,3 @@
^CMAKE_INSTALL_FULL_LOCALSTATEDIR='/var/opt/Opt-CMP0192-OLD'
CMAKE_INSTALL_FULL_RUNSTATEDIR='/var/run/opt/Opt-CMP0192-OLD'
CMAKE_INSTALL_FULL_SYSCONFDIR='/etc/opt/Opt-CMP0192-OLD'$
@@ -0,0 +1,7 @@
enable_language(C)
cmake_policy(SET CMP0192 OLD)
set(CMAKE_INSTALL_PREFIX "/opt/${PROJECT_NAME}")
include(GNUInstallDirs)
foreach(dir IN ITEMS LOCALSTATEDIR RUNSTATEDIR SYSCONFDIR)
message("CMAKE_INSTALL_FULL_${dir}='${CMAKE_INSTALL_FULL_${dir}}'")
endforeach()
@@ -0,0 +1,3 @@
^CMAKE_INSTALL_FULL_LOCALSTATEDIR='/var/opt/Opt-RelativeSpecialDirs'
CMAKE_INSTALL_FULL_RUNSTATEDIR='/var/run/opt/Opt-RelativeSpecialDirs'
CMAKE_INSTALL_FULL_SYSCONFDIR='/etc/opt/Opt-RelativeSpecialDirs'$
@@ -0,0 +1,7 @@
enable_language(C)
cmake_policy(SET CMP0192 NEW)
set(CMAKE_INSTALL_PREFIX "/opt/${PROJECT_NAME}")
include(GNUInstallDirs)
foreach(dir IN ITEMS LOCALSTATEDIR RUNSTATEDIR SYSCONFDIR)
message("CMAKE_INSTALL_FULL_${dir}='${CMAKE_INSTALL_FULL_${dir}}'")
endforeach()
@@ -39,6 +39,12 @@ endblock()
run_cmake(GetAbs)
run_cmake(NoSystem)
run_cmake(Opt-CMP0192-OLD)
run_cmake_with_options(Opt-RelativeSpecialDirs
-DCMAKE_INSTALL_LOCALSTATEDIR=var
-DCMAKE_INSTALL_RUNSTATEDIR=var/run
-DCMAKE_INSTALL_SYSCONFDIR=etc
)
foreach(case
Opt