mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-23 00:48:55 +08:00
cmake_host_system_information: Can run fallback scripts
This commit is contained in:
@@ -176,8 +176,75 @@ system identification as described in the `man 5 os-release`_.
|
|||||||
-- DISTRO_VERSION_CODENAME=`focal`
|
-- DISTRO_VERSION_CODENAME=`focal`
|
||||||
-- DISTRO_VERSION_ID=`20.04`
|
-- DISTRO_VERSION_ID=`20.04`
|
||||||
|
|
||||||
|
If :file:`/etc/os-release` file is not found, the command tries to gather OS
|
||||||
|
identification via fallback scripts. The fallback script can use `various
|
||||||
|
distribution-specific files`_ to collect OS identification data and map it
|
||||||
|
into `man 5 os-release`_ variables.
|
||||||
|
|
||||||
|
Fallback Interface Variables
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. variable:: CMAKE_GET_OS_RELEASE_FALLBACK_SCRIPTS
|
||||||
|
|
||||||
|
In addition to the scripts shipped with CMake, a user may append full
|
||||||
|
paths to his script(s) to the this list. The script filename has the
|
||||||
|
following format: ``NNN-<name>.cmake``, where ``NNN`` is three digits
|
||||||
|
used to apply collected scripts in a specific order.
|
||||||
|
|
||||||
|
.. variable:: CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_<varname>
|
||||||
|
|
||||||
|
Variables collected by the user provided fallback script
|
||||||
|
ought to be assigned to CMake variables using this naming
|
||||||
|
convention. Example, the ``ID`` variable from the manual becomes
|
||||||
|
``CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID``.
|
||||||
|
|
||||||
|
.. variable:: CMAKE_GET_OS_RELEASE_FALLBACK_RESULT
|
||||||
|
|
||||||
|
The fallback script ought to store names of all assigned
|
||||||
|
``CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_<varname>`` variables in this list.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
# Try to detect some old distribution
|
||||||
|
# See also
|
||||||
|
# - http://linuxmafia.com/faq/Admin/release-files.html
|
||||||
|
#
|
||||||
|
if(NOT EXISTS "${CMAKE_SYSROOT}/etc/foobar-release")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
# Get the first string only
|
||||||
|
file(
|
||||||
|
STRINGS "${CMAKE_SYSROOT}/etc/foobar-release" CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT
|
||||||
|
LIMIT_COUNT 1
|
||||||
|
)
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
#
|
||||||
|
# Foobar distribution release 1.2.3 (server)
|
||||||
|
#
|
||||||
|
if(CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT MATCHES "Foobar distribution release ([0-9\.]+) .*")
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_NAME Foobar)
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_PRETTY_NAME "${CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT}")
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID foobar)
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION ${CMAKE_MATCH_1})
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION_ID ${CMAKE_MATCH_1})
|
||||||
|
list(
|
||||||
|
APPEND CMAKE_GET_OS_RELEASE_FALLBACK_RESULT
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_NAME
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_PRETTY_NAME
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION_ID
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
unset(CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT)
|
||||||
|
|
||||||
|
|
||||||
.. rubric:: Footnotes
|
.. rubric:: Footnotes
|
||||||
|
|
||||||
.. [#mebibytes] One MiB (mebibyte) is equal to 1024x1024 bytes.
|
.. [#mebibytes] One MiB (mebibyte) is equal to 1024x1024 bytes.
|
||||||
|
|
||||||
.. _man 5 os-release: https://www.freedesktop.org/software/systemd/man/os-release.html
|
.. _man 5 os-release: https://www.freedesktop.org/software/systemd/man/os-release.html
|
||||||
|
.. _various distribution-specific files: http://linuxmafia.com/faq/Admin/release-files.html
|
||||||
|
41
Modules/Internal/OSRelease/010-TryOldCentOS.cmake
Normal file
41
Modules/Internal/OSRelease/010-TryOldCentOS.cmake
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||||
|
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||||
|
|
||||||
|
# Author: Alex Turbov
|
||||||
|
|
||||||
|
if(NOT EXISTS "${CMAKE_SYSROOT}/etc/centos-release")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Get the first string only
|
||||||
|
file(
|
||||||
|
STRINGS "${CMAKE_SYSROOT}/etc/centos-release" CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT
|
||||||
|
LIMIT_COUNT 1
|
||||||
|
)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# CentOS release 6.10 (Final)
|
||||||
|
#
|
||||||
|
if(CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT MATCHES "CentOS release ([0-9\.]+) .*")
|
||||||
|
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_NAME CentOS)
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_PRETTY_NAME "${CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT}")
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID centos)
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID_LIKE rhel)
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION ${CMAKE_MATCH_1})
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION_ID ${CMAKE_MATCH_1})
|
||||||
|
|
||||||
|
list(
|
||||||
|
APPEND CMAKE_GET_OS_RELEASE_FALLBACK_RESULT
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_NAME
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_PRETTY_NAME
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID_LIKE
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION_ID
|
||||||
|
)
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
|
unset(CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT)
|
38
Modules/Internal/OSRelease/020-TryDebianVersion.cmake
Normal file
38
Modules/Internal/OSRelease/020-TryDebianVersion.cmake
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||||
|
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||||
|
|
||||||
|
# Author: Alex Turbov
|
||||||
|
|
||||||
|
if(NOT EXISTS "${CMAKE_SYSROOT}/etc/debian_version")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Get the first string only
|
||||||
|
file(
|
||||||
|
STRINGS "${CMAKE_SYSROOT}/etc/debian_version" CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT
|
||||||
|
LIMIT_COUNT 1
|
||||||
|
)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# 6.0.10 # Old debian
|
||||||
|
# wheezy/sid # Ubuntu
|
||||||
|
#
|
||||||
|
if(CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT MATCHES "[0-9]+(\.[0-9]+)*")
|
||||||
|
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_NAME Debian)
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID debian)
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION ${CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT})
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION_ID ${CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT})
|
||||||
|
|
||||||
|
list(
|
||||||
|
APPEND CMAKE_GET_OS_RELEASE_FALLBACK_RESULT
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_NAME
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION_ID
|
||||||
|
)
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
|
unset(CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT)
|
@@ -2,6 +2,7 @@
|
|||||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||||
#include "cmCMakeHostSystemInformationCommand.h"
|
#include "cmCMakeHostSystemInformationCommand.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
#include <cmext/string_view>
|
#include <cmext/string_view>
|
||||||
|
|
||||||
#include "cmsys/FStream.hxx"
|
#include "cmsys/FStream.hxx"
|
||||||
|
#include "cmsys/Glob.hxx"
|
||||||
#include "cmsys/SystemInformation.hxx"
|
#include "cmsys/SystemInformation.hxx"
|
||||||
|
|
||||||
#include "cmExecutionStatus.h"
|
#include "cmExecutionStatus.h"
|
||||||
@@ -259,8 +261,8 @@ cm::optional<std::pair<std::string, std::string>> ParseOSReleaseLine(
|
|||||||
std::map<std::string, std::string> GetOSReleaseVariables(
|
std::map<std::string, std::string> GetOSReleaseVariables(
|
||||||
cmExecutionStatus& status)
|
cmExecutionStatus& status)
|
||||||
{
|
{
|
||||||
const auto& sysroot =
|
auto& makefile = status.GetMakefile();
|
||||||
status.GetMakefile().GetSafeDefinition("CMAKE_SYSROOT");
|
const auto& sysroot = makefile.GetSafeDefinition("CMAKE_SYSROOT");
|
||||||
|
|
||||||
std::map<std::string, std::string> data;
|
std::map<std::string, std::string> data;
|
||||||
// Based on
|
// Based on
|
||||||
@@ -278,6 +280,92 @@ std::map<std::string, std::string> GetOSReleaseVariables(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Got smth?
|
||||||
|
if (!data.empty()) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ugh, it could be some pre-os-release distro.
|
||||||
|
// Lets try some fallback getters.
|
||||||
|
|
||||||
|
// 1. CMake provided
|
||||||
|
cmsys::Glob gl;
|
||||||
|
std::vector<std::string> scripts;
|
||||||
|
auto const findExpr = cmStrCat(cmSystemTools::GetCMakeRoot(),
|
||||||
|
"/Modules/Internal/OSRelease/*.cmake");
|
||||||
|
if (gl.FindFiles(findExpr)) {
|
||||||
|
scripts = gl.GetFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. User provided (append to the CMake prvided)
|
||||||
|
makefile.GetDefExpandList("CMAKE_GET_OS_RELEASE_FALLBACK_SCRIPTS", scripts);
|
||||||
|
|
||||||
|
// Filter out files that are not in format `NNN-name.cmake`
|
||||||
|
auto checkName = [](std::string const& filepath) -> bool {
|
||||||
|
auto const& filename = cmSystemTools::GetFilenameName(filepath);
|
||||||
|
// NOTE Minimum filename length expected:
|
||||||
|
// NNN-<at-least-one-char-name>.cmake --> 11
|
||||||
|
return (filename.size() < 11) || !std::isdigit(filename[0]) ||
|
||||||
|
!std::isdigit(filename[1]) || !std::isdigit(filename[2]) ||
|
||||||
|
filename[3] != '-';
|
||||||
|
};
|
||||||
|
scripts.erase(std::remove_if(scripts.begin(), scripts.end(), checkName),
|
||||||
|
scripts.end());
|
||||||
|
|
||||||
|
// Make sure scripts are running in desired order
|
||||||
|
std::sort(scripts.begin(), scripts.end(),
|
||||||
|
[](std::string const& lhs, std::string const& rhs) -> bool {
|
||||||
|
long lhs_order;
|
||||||
|
cmStrToLong(cmSystemTools::GetFilenameName(lhs).substr(0u, 3u),
|
||||||
|
&lhs_order);
|
||||||
|
long rhs_order;
|
||||||
|
cmStrToLong(cmSystemTools::GetFilenameName(rhs).substr(0u, 3u),
|
||||||
|
&rhs_order);
|
||||||
|
return lhs_order < rhs_order;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Name of the variable to put the results
|
||||||
|
auto const result_variable = "CMAKE_GET_OS_RELEASE_FALLBACK_RESULT"_s;
|
||||||
|
|
||||||
|
for (auto const& script : scripts) {
|
||||||
|
// Unset the result variable
|
||||||
|
makefile.RemoveDefinition(result_variable.data());
|
||||||
|
|
||||||
|
// include FATAL_ERROR and ERROR in the return status
|
||||||
|
if (!makefile.ReadListFile(script) ||
|
||||||
|
cmSystemTools::GetErrorOccuredFlag()) {
|
||||||
|
// Ok, no worries... go try the next script.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> variables;
|
||||||
|
if (!makefile.GetDefExpandList(result_variable.data(), variables)) {
|
||||||
|
// Heh, this script didn't found anything... go try the next one.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const& variable : variables) {
|
||||||
|
auto value = makefile.GetSafeDefinition(variable);
|
||||||
|
makefile.RemoveDefinition(variable);
|
||||||
|
|
||||||
|
if (!cmHasPrefix(variable, cmStrCat(result_variable, '_'))) {
|
||||||
|
// Ignore unknown variable set by the script
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto key = variable.substr(result_variable.size() + 1,
|
||||||
|
variable.size() - result_variable.size() - 1);
|
||||||
|
data.emplace(std::move(key), std::move(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.empty()) {
|
||||||
|
// Try 'till some script can get anything
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
makefile.RemoveDefinition(result_variable.data());
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1 @@
|
|||||||
|
message(WARNING "The warning text to match just to make sure the script get executed")
|
@@ -0,0 +1,21 @@
|
|||||||
|
if(DEFINED CMAKE_GET_OS_RELEASE_FALLBACK_RESULT)
|
||||||
|
message(FATAL_ERROR "The `CMAKE_GET_OS_RELEASE_FALLBACK_RESULT` expected to be unset at this moment")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_NAME UnitTest)
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_PRETTY_NAME "Just a Unit Test")
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID unittest)
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID_LIKE nothing)
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION 0.0.1)
|
||||||
|
set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION_ID 0.0.1)
|
||||||
|
|
||||||
|
list(
|
||||||
|
APPEND CMAKE_GET_OS_RELEASE_FALLBACK_RESULT
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_NAME
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_PRETTY_NAME
|
||||||
|
IGNORED_VARIABLE_NAME_WHICH_IS_NOT_STARTED_WITH_EXPECTED_PREFIX
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID_LIKE
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION
|
||||||
|
CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION_ID
|
||||||
|
)
|
@@ -0,0 +1,6 @@
|
|||||||
|
-- CENTOS6_ID=`centos`
|
||||||
|
-- CENTOS6_ID_LIKE=`rhel`
|
||||||
|
-- CENTOS6_NAME=`CentOS`
|
||||||
|
-- CENTOS6_PRETTY_NAME=`CentOS release 6\.10 \(Final\)`
|
||||||
|
-- CENTOS6_VERSION=`6\.10`
|
||||||
|
-- CENTOS6_VERSION_ID=`6\.10`
|
@@ -0,0 +1,5 @@
|
|||||||
|
cmake_host_system_information(RESULT CENTOS6 QUERY DISTRIB_INFO)
|
||||||
|
|
||||||
|
foreach(VAR IN LISTS CENTOS6)
|
||||||
|
message(STATUS "${VAR}=`${${VAR}}`")
|
||||||
|
endforeach()
|
@@ -0,0 +1 @@
|
|||||||
|
CentOS release 6.10 (Final)
|
@@ -0,0 +1,4 @@
|
|||||||
|
-- DEBIAN6_ID=`debian`
|
||||||
|
-- DEBIAN6_NAME=`Debian`
|
||||||
|
-- DEBIAN6_VERSION=`6\.0\.10`
|
||||||
|
-- DEBIAN6_VERSION_ID=`6\.0\.10`
|
@@ -0,0 +1,5 @@
|
|||||||
|
cmake_host_system_information(RESULT DEBIAN6 QUERY DISTRIB_INFO)
|
||||||
|
|
||||||
|
foreach(VAR IN LISTS DEBIAN6)
|
||||||
|
message(STATUS "${VAR}=`${${VAR}}`")
|
||||||
|
endforeach()
|
@@ -0,0 +1 @@
|
|||||||
|
6.0.10
|
@@ -13,4 +13,9 @@ if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
|||||||
run_cmake_with_options(Exherbo)
|
run_cmake_with_options(Exherbo)
|
||||||
run_cmake_with_options(Ubuntu)
|
run_cmake_with_options(Ubuntu)
|
||||||
|
|
||||||
|
run_cmake_with_options(CentOS6)
|
||||||
|
run_cmake_with_options(Debian6)
|
||||||
|
|
||||||
|
run_cmake_with_options(UserFallbackScript)
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
@@ -0,0 +1,5 @@
|
|||||||
|
CMake Warning at 000-FirstFallbackScript\.cmake:[0-9]+ \(message\):
|
||||||
|
The warning text to match just to make sure the script get executed
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
UserFallbackScript\.cmake:[0-9]+ \(cmake_host_system_information\)
|
||||||
|
CMakeLists\.txt:[0-9]+ \(include\)
|
@@ -0,0 +1,6 @@
|
|||||||
|
-- UFS_ID=`unittest`
|
||||||
|
-- UFS_ID_LIKE=`nothing`
|
||||||
|
-- UFS_NAME=`UnitTest`
|
||||||
|
-- UFS_PRETTY_NAME=`Just a Unit Test`
|
||||||
|
-- UFS_VERSION=`0\.0\.1`
|
||||||
|
-- UFS_VERSION_ID=`0\.0\.1`
|
@@ -0,0 +1,12 @@
|
|||||||
|
list(
|
||||||
|
APPEND CMAKE_GET_OS_RELEASE_FALLBACK_SCRIPTS
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/000-FirstFallbackScript.cmake
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/Ignored-Script.cmake
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/999-LastFallbackScript.cmake
|
||||||
|
)
|
||||||
|
|
||||||
|
cmake_host_system_information(RESULT UFS QUERY DISTRIB_INFO)
|
||||||
|
|
||||||
|
foreach(VAR IN LISTS UFS)
|
||||||
|
message(STATUS "${VAR}=`${${VAR}}`")
|
||||||
|
endforeach()
|
Reference in New Issue
Block a user