diff options
author | Brad King <brad.king@kitware.com> | 2021-08-24 14:04:03 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2021-08-24 14:04:15 (GMT) |
commit | cf90aa5595eac39029f7516e0bc5790fe398ea3d (patch) | |
tree | 1eeb86857a1a7adcf70618b21e773f90f062f846 | |
parent | 91d5bf68ae2bee13bc29ce89732844047c687334 (diff) | |
parent | b9698f89df275a33b01cfc7b4f88a510ad9d8bbe (diff) | |
download | CMake-cf90aa5595eac39029f7516e0bc5790fe398ea3d.zip CMake-cf90aa5595eac39029f7516e0bc5790fe398ea3d.tar.gz CMake-cf90aa5595eac39029f7516e0bc5790fe398ea3d.tar.bz2 |
Merge topic 'host-distro-info'
b9698f89df cmake_host_system_information: Make it available for all systems
5469c71a82 Refactor: Simplify `GetValue()` function calls
6c92f80f2e cmake_host_system_information: Also set `USED_FALLBACK_SCRIPT`
efe139d1b8 cmake_host_system_information: Can run fallback scripts
1e65e4a6e5 cmake_host_system_information: Can read `/etc/os-release` file
e808cbb1dd Testing: Convert `cmake_host_system_information` tests into `RunCMake`
9e831284e5 Documentation: Use definition list instead of tables
346f3de005 Refactor: Deduplicate code for `VS_nn_DIR` keys processing
...
Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: buildbot <buildbot@kitware.com>
Merge-request: !6410
42 files changed, 991 insertions, 218 deletions
diff --git a/Help/command/cmake_host_system_information.rst b/Help/command/cmake_host_system_information.rst index 2b902a9..998e146 100644 --- a/Help/command/cmake_host_system_information.rst +++ b/Help/command/cmake_host_system_information.rst @@ -13,46 +13,236 @@ queried. The list of queried values is stored in ``<variable>``. ``<key>`` can be one of the following values: -============================= ================================================ -Key Description -============================= ================================================ -``NUMBER_OF_LOGICAL_CORES`` Number of logical cores -``NUMBER_OF_PHYSICAL_CORES`` Number of physical cores -``HOSTNAME`` Hostname -``FQDN`` Fully qualified domain name -``TOTAL_VIRTUAL_MEMORY`` Total virtual memory in MiB [#mebibytes]_ -``AVAILABLE_VIRTUAL_MEMORY`` Available virtual memory in MiB [#mebibytes]_ -``TOTAL_PHYSICAL_MEMORY`` Total physical memory in MiB [#mebibytes]_ -``AVAILABLE_PHYSICAL_MEMORY`` Available physical memory in MiB [#mebibytes]_ -============================= ================================================ - -.. versionadded:: 3.10 - Additional ``<key>`` values are available: - -============================= ================================================ -Key Description -============================= ================================================ -``IS_64BIT`` One if processor is 64Bit -``HAS_FPU`` One if processor has floating point unit -``HAS_MMX`` One if processor supports MMX instructions -``HAS_MMX_PLUS`` One if processor supports Ext. MMX instructions -``HAS_SSE`` One if processor supports SSE instructions -``HAS_SSE2`` One if processor supports SSE2 instructions -``HAS_SSE_FP`` One if processor supports SSE FP instructions -``HAS_SSE_MMX`` One if processor supports SSE MMX instructions -``HAS_AMD_3DNOW`` One if processor supports 3DNow instructions -``HAS_AMD_3DNOW_PLUS`` One if processor supports 3DNow+ instructions -``HAS_IA64`` One if IA64 processor emulating x86 -``HAS_SERIAL_NUMBER`` One if processor has serial number -``PROCESSOR_SERIAL_NUMBER`` Processor serial number -``PROCESSOR_NAME`` Human readable processor name -``PROCESSOR_DESCRIPTION`` Human readable full processor description -``OS_NAME`` See :variable:`CMAKE_HOST_SYSTEM_NAME` -``OS_RELEASE`` The OS sub-type e.g. on Windows ``Professional`` -``OS_VERSION`` The OS build ID -``OS_PLATFORM`` See :variable:`CMAKE_HOST_SYSTEM_PROCESSOR` -============================= ================================================ +``NUMBER_OF_LOGICAL_CORES`` + Number of logical cores + +``NUMBER_OF_PHYSICAL_CORES`` + Number of physical cores + +``HOSTNAME`` + Hostname + +``FQDN`` + Fully qualified domain name + +``TOTAL_VIRTUAL_MEMORY`` + Total virtual memory in MiB [#mebibytes]_ + +``AVAILABLE_VIRTUAL_MEMORY`` + Available virtual memory in MiB [#mebibytes]_ + +``TOTAL_PHYSICAL_MEMORY`` + Total physical memory in MiB [#mebibytes]_ + +``AVAILABLE_PHYSICAL_MEMORY`` + Available physical memory in MiB [#mebibytes]_ + +``IS_64BIT`` + .. versionadded:: 3.10 + + One if processor is 64Bit + +``HAS_FPU`` + .. versionadded:: 3.10 + + One if processor has floating point unit + +``HAS_MMX`` + .. versionadded:: 3.10 + + One if processor supports MMX instructions + +``HAS_MMX_PLUS`` + .. versionadded:: 3.10 + + One if processor supports Ext. MMX instructions + +``HAS_SSE`` + .. versionadded:: 3.10 + + One if processor supports SSE instructions + +``HAS_SSE2`` + .. versionadded:: 3.10 + + One if processor supports SSE2 instructions + +``HAS_SSE_FP`` + .. versionadded:: 3.10 + + One if processor supports SSE FP instructions + +``HAS_SSE_MMX`` + .. versionadded:: 3.10 + + One if processor supports SSE MMX instructions + +``HAS_AMD_3DNOW`` + .. versionadded:: 3.10 + + One if processor supports 3DNow instructions + +``HAS_AMD_3DNOW_PLUS`` + .. versionadded:: 3.10 + + One if processor supports 3DNow+ instructions + +``HAS_IA64`` + .. versionadded:: 3.10 + + One if IA64 processor emulating x86 + +``HAS_SERIAL_NUMBER`` + .. versionadded:: 3.10 + + One if processor has serial number + +``PROCESSOR_SERIAL_NUMBER`` + .. versionadded:: 3.10 + + Processor serial number + +``PROCESSOR_NAME`` + .. versionadded:: 3.10 + + Human readable processor name + +``PROCESSOR_DESCRIPTION`` + .. versionadded:: 3.10 + + Human readable full processor description + +``OS_NAME`` + .. versionadded:: 3.10 + + See :variable:`CMAKE_HOST_SYSTEM_NAME` + +``OS_RELEASE`` + .. versionadded:: 3.10 + + The OS sub-type e.g. on Windows ``Professional`` + +``OS_VERSION`` + .. versionadded:: 3.10 + + The OS build ID + +``OS_PLATFORM`` + .. versionadded:: 3.10 + + See :variable:`CMAKE_HOST_SYSTEM_PROCESSOR` + +``DISTRIB_INFO`` + .. versionadded:: 3.22 + + Read :file:`/etc/os-release` file and define the given ``<variable>`` + into a list of read variables + +``DISTRIB_<name>`` + .. versionadded:: 3.22 + + Get the ``<name>`` variable (see `man 5 os-release`_) if it exists in the + :file:`/etc/os-release` file + + Example: + + .. code-block:: cmake + + cmake_host_system_information(RESULT PRETTY_NAME QUERY DISTRIB_PRETTY_NAME) + message(STATUS "${PRETTY_NAME}") + + cmake_host_system_information(RESULT DISTRO QUERY DISTRIB_INFO) + + foreach(VAR IN LISTS DISTRO) + message(STATUS "${VAR}=`${${VAR}}`") + endforeach() + + + Output:: + + -- Ubuntu 20.04.2 LTS + -- DISTRO_BUG_REPORT_URL=`https://bugs.launchpad.net/ubuntu/` + -- DISTRO_HOME_URL=`https://www.ubuntu.com/` + -- DISTRO_ID=`ubuntu` + -- DISTRO_ID_LIKE=`debian` + -- DISTRO_NAME=`Ubuntu` + -- DISTRO_PRETTY_NAME=`Ubuntu 20.04.2 LTS` + -- DISTRO_PRIVACY_POLICY_URL=`https://www.ubuntu.com/legal/terms-and-policies/privacy-policy` + -- DISTRO_SUPPORT_URL=`https://help.ubuntu.com/` + -- DISTRO_UBUNTU_CODENAME=`focal` + -- DISTRO_VERSION=`20.04.2 LTS (Focal Fossa)` + -- DISTRO_VERSION_CODENAME=`focal` + -- 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 .. [#mebibytes] One MiB (mebibyte) is equal to 1024x1024 bytes. + +.. _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 diff --git a/Help/release/dev/os-release.rst b/Help/release/dev/os-release.rst new file mode 100644 index 0000000..cce6aee --- /dev/null +++ b/Help/release/dev/os-release.rst @@ -0,0 +1,6 @@ +os-release +---------- + +* The :command:`cmake_host_system_information` command query operating system + identification `variables <https://www.freedesktop.org/software/systemd/man/os-release.html>`_ + from the :file:`/etc/os-release` file. diff --git a/Modules/Internal/OSRelease/010-TryOldCentOS.cmake b/Modules/Internal/OSRelease/010-TryOldCentOS.cmake new file mode 100644 index 0000000..ff35897 --- /dev/null +++ b/Modules/Internal/OSRelease/010-TryOldCentOS.cmake @@ -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) diff --git a/Modules/Internal/OSRelease/020-TryDebianVersion.cmake b/Modules/Internal/OSRelease/020-TryDebianVersion.cmake new file mode 100644 index 0000000..8ebe19a --- /dev/null +++ b/Modules/Internal/OSRelease/020-TryDebianVersion.cmake @@ -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) diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx index 0550568..74071ff 100644 --- a/Source/cmCMakeHostSystemInformationCommand.cxx +++ b/Source/cmCMakeHostSystemInformationCommand.cxx @@ -2,214 +2,510 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCMakeHostSystemInformationCommand.h" -#include <cstddef> +#include <algorithm> +#include <cassert> +#include <cctype> +#include <initializer_list> +#include <map> +#include <string> +#include <type_traits> +#include <utility> +#include <cm/optional> +#include <cm/string_view> +#include <cmext/string_view> + +#include "cmsys/FStream.hxx" +#include "cmsys/Glob.hxx" #include "cmsys/SystemInformation.hxx" #include "cmExecutionStatus.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" +#include "cmSystemTools.h" -#if defined(_WIN32) +#ifdef _WIN32 # include "cmAlgorithms.h" # include "cmGlobalGenerator.h" # include "cmGlobalVisualStudioVersionedGenerator.h" -# include "cmSystemTools.h" # include "cmVSSetupHelper.h" # define HAVE_VS_SETUP_HELPER #endif namespace { -bool GetValue(cmExecutionStatus& status, cmsys::SystemInformation& info, - std::string const& key, std::string& value); -std::string ValueToString(size_t value); -std::string ValueToString(const char* value); -std::string ValueToString(std::string const& value); -} +std::string const DELIM[2] = { {}, ";" }; -// cmCMakeHostSystemInformation -bool cmCMakeHostSystemInformationCommand(std::vector<std::string> const& args, - cmExecutionStatus& status) +// BEGIN Private functions +std::string ValueToString(std::size_t const value) { - size_t current_index = 0; - - if (args.size() < (current_index + 2) || args[current_index] != "RESULT") { - status.SetError("missing RESULT specification."); - return false; - } - - std::string const& variable = args[current_index + 1]; - current_index += 2; - - if (args.size() < (current_index + 2) || args[current_index] != "QUERY") { - status.SetError("missing QUERY specification"); - return false; - } - - cmsys::SystemInformation info; - info.RunCPUCheck(); - info.RunOSCheck(); - info.RunMemoryCheck(); - - std::string result_list; - for (size_t i = current_index + 1; i < args.size(); ++i) { - std::string const& key = args[i]; - if (i != current_index + 1) { - result_list += ";"; - } - std::string value; - if (!GetValue(status, info, key, value)) { - return false; - } - result_list += value; - } - - status.GetMakefile().AddDefinition(variable, result_list); + return std::to_string(value); +} - return true; +std::string ValueToString(const char* const value) +{ + return value ? value : std::string{}; } -namespace { +std::string ValueToString(std::string const& value) +{ + return value; +} -bool GetValue(cmExecutionStatus& status, cmsys::SystemInformation& info, - std::string const& key, std::string& value) +cm::optional<std::string> GetValue(cmsys::SystemInformation& info, + std::string const& key) { - if (key == "NUMBER_OF_LOGICAL_CORES") { - value = ValueToString(info.GetNumberOfLogicalCPU()); - } else if (key == "NUMBER_OF_PHYSICAL_CORES") { - value = ValueToString(info.GetNumberOfPhysicalCPU()); - } else if (key == "HOSTNAME") { - value = ValueToString(info.GetHostname()); - } else if (key == "FQDN") { - value = ValueToString(info.GetFullyQualifiedDomainName()); - } else if (key == "TOTAL_VIRTUAL_MEMORY") { - value = ValueToString(info.GetTotalVirtualMemory()); - } else if (key == "AVAILABLE_VIRTUAL_MEMORY") { - value = ValueToString(info.GetAvailableVirtualMemory()); - } else if (key == "TOTAL_PHYSICAL_MEMORY") { - value = ValueToString(info.GetTotalPhysicalMemory()); - } else if (key == "AVAILABLE_PHYSICAL_MEMORY") { - value = ValueToString(info.GetAvailablePhysicalMemory()); - } else if (key == "IS_64BIT") { - value = ValueToString(info.Is64Bits()); - } else if (key == "HAS_FPU") { - value = ValueToString( + if (key == "NUMBER_OF_LOGICAL_CORES"_s) { + return ValueToString(info.GetNumberOfLogicalCPU()); + } + if (key == "NUMBER_OF_PHYSICAL_CORES"_s) { + return ValueToString(info.GetNumberOfPhysicalCPU()); + } + if (key == "HOSTNAME"_s) { + return ValueToString(info.GetHostname()); + } + if (key == "FQDN"_s) { + return ValueToString(info.GetFullyQualifiedDomainName()); + } + if (key == "TOTAL_VIRTUAL_MEMORY"_s) { + return ValueToString(info.GetTotalVirtualMemory()); + } + if (key == "AVAILABLE_VIRTUAL_MEMORY"_s) { + return ValueToString(info.GetAvailableVirtualMemory()); + } + if (key == "TOTAL_PHYSICAL_MEMORY"_s) { + return ValueToString(info.GetTotalPhysicalMemory()); + } + if (key == "AVAILABLE_PHYSICAL_MEMORY"_s) { + return ValueToString(info.GetAvailablePhysicalMemory()); + } + if (key == "IS_64BIT"_s) { + return ValueToString(info.Is64Bits()); + } + if (key == "HAS_FPU"_s) { + return ValueToString( info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_FPU)); - } else if (key == "HAS_MMX") { - value = ValueToString( + } + if (key == "HAS_MMX"_s) { + return ValueToString( info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_MMX)); - } else if (key == "HAS_MMX_PLUS") { - value = ValueToString(info.DoesCPUSupportFeature( + } + if (key == "HAS_MMX_PLUS"_s) { + return ValueToString(info.DoesCPUSupportFeature( cmsys::SystemInformation::CPU_FEATURE_MMX_PLUS)); - } else if (key == "HAS_SSE") { - value = ValueToString( + } + if (key == "HAS_SSE"_s) { + return ValueToString( info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_SSE)); - } else if (key == "HAS_SSE2") { - value = ValueToString( + } + if (key == "HAS_SSE2"_s) { + return ValueToString( info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_SSE2)); - } else if (key == "HAS_SSE_FP") { - value = ValueToString(info.DoesCPUSupportFeature( + } + if (key == "HAS_SSE_FP"_s) { + return ValueToString(info.DoesCPUSupportFeature( cmsys::SystemInformation::CPU_FEATURE_SSE_FP)); - } else if (key == "HAS_SSE_MMX") { - value = ValueToString(info.DoesCPUSupportFeature( + } + if (key == "HAS_SSE_MMX"_s) { + return ValueToString(info.DoesCPUSupportFeature( cmsys::SystemInformation::CPU_FEATURE_SSE_MMX)); - } else if (key == "HAS_AMD_3DNOW") { - value = ValueToString(info.DoesCPUSupportFeature( + } + if (key == "HAS_AMD_3DNOW"_s) { + return ValueToString(info.DoesCPUSupportFeature( cmsys::SystemInformation::CPU_FEATURE_AMD_3DNOW)); - } else if (key == "HAS_AMD_3DNOW_PLUS") { - value = ValueToString(info.DoesCPUSupportFeature( + } + if (key == "HAS_AMD_3DNOW_PLUS"_s) { + return ValueToString(info.DoesCPUSupportFeature( cmsys::SystemInformation::CPU_FEATURE_AMD_3DNOW_PLUS)); - } else if (key == "HAS_IA64") { - value = ValueToString( + } + if (key == "HAS_IA64"_s) { + return ValueToString( info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_IA64)); - } else if (key == "HAS_SERIAL_NUMBER") { - value = ValueToString(info.DoesCPUSupportFeature( + } + if (key == "HAS_SERIAL_NUMBER"_s) { + return ValueToString(info.DoesCPUSupportFeature( cmsys::SystemInformation::CPU_FEATURE_SERIALNUMBER)); - } else if (key == "PROCESSOR_NAME") { - value = ValueToString(info.GetExtendedProcessorName()); - } else if (key == "PROCESSOR_DESCRIPTION") { - value = info.GetCPUDescription(); - } else if (key == "PROCESSOR_SERIAL_NUMBER") { - value = ValueToString(info.GetProcessorSerialNumber()); - } else if (key == "OS_NAME") { - value = ValueToString(info.GetOSName()); - } else if (key == "OS_RELEASE") { - value = ValueToString(info.GetOSRelease()); - } else if (key == "OS_VERSION") { - value = ValueToString(info.GetOSVersion()); - } else if (key == "OS_PLATFORM") { - value = ValueToString(info.GetOSPlatform()); -#ifdef HAVE_VS_SETUP_HELPER - } else if (key == "VS_15_DIR") { - // If generating for the VS 15 IDE, use the same instance. - cmGlobalGenerator* gg = status.GetMakefile().GetGlobalGenerator(); - if (cmHasLiteralPrefix(gg->GetName(), "Visual Studio 15 ")) { - cmGlobalVisualStudioVersionedGenerator* vs15gen = - static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg); - if (vs15gen->GetVSInstance(value)) { - return true; - } + } + if (key == "PROCESSOR_NAME"_s) { + return ValueToString(info.GetExtendedProcessorName()); + } + if (key == "PROCESSOR_DESCRIPTION"_s) { + return info.GetCPUDescription(); + } + if (key == "PROCESSOR_SERIAL_NUMBER"_s) { + return ValueToString(info.GetProcessorSerialNumber()); + } + if (key == "OS_NAME"_s) { + return ValueToString(info.GetOSName()); + } + if (key == "OS_RELEASE"_s) { + return ValueToString(info.GetOSRelease()); + } + if (key == "OS_VERSION"_s) { + return ValueToString(info.GetOSVersion()); + } + if (key == "OS_PLATFORM"_s) { + return ValueToString(info.GetOSPlatform()); + } + return {}; +} + +cm::optional<std::pair<std::string, std::string>> ParseOSReleaseLine( + std::string const& line) +{ + std::string key; + std::string value; + + char prev = 0; + enum ParserState + { + PARSE_KEY_1ST, + PARSE_KEY, + FOUND_EQ, + PARSE_SINGLE_QUOTE_VALUE, + PARSE_DBL_QUOTE_VALUE, + PARSE_VALUE, + IGNORE_REST + } state = PARSE_KEY_1ST; + + for (auto ch : line) { + switch (state) { + case PARSE_KEY_1ST: + if (std::isalpha(ch) || ch == '_') { + key += ch; + state = PARSE_KEY; + } else if (!std::isspace(ch)) { + state = IGNORE_REST; + } + break; + + case PARSE_KEY: + if (ch == '=') { + state = FOUND_EQ; + } else if (std::isalnum(ch) || ch == '_') { + key += ch; + } else { + state = IGNORE_REST; + } + break; + + case FOUND_EQ: + switch (ch) { + case '\'': + state = PARSE_SINGLE_QUOTE_VALUE; + break; + case '"': + state = PARSE_DBL_QUOTE_VALUE; + break; + case '#': + case '\\': + state = IGNORE_REST; + break; + default: + value += ch; + state = PARSE_VALUE; + } + break; + + case PARSE_SINGLE_QUOTE_VALUE: + if (ch == '\'') { + if (prev != '\\') { + state = IGNORE_REST; + } else { + assert(!value.empty()); + value[value.size() - 1] = ch; + } + } else { + value += ch; + } + break; + + case PARSE_DBL_QUOTE_VALUE: + if (ch == '"') { + if (prev != '\\') { + state = IGNORE_REST; + } else { + assert(!value.empty()); + value[value.size() - 1] = ch; + } + } else { + value += ch; + } + break; + + case PARSE_VALUE: + if (ch == '#' || std::isspace(ch)) { + state = IGNORE_REST; + } else { + value += ch; + } + break; + + default: + // Unexpected os-release parser state! + state = IGNORE_REST; + break; } - // Otherwise, find a VS 15 instance ourselves. - cmVSSetupAPIHelper vsSetupAPIHelper(15); - if (vsSetupAPIHelper.GetVSInstanceInfo(value)) { - cmSystemTools::ConvertToUnixSlashes(value); + if (state == IGNORE_REST) { + break; } - } else if (key == "VS_16_DIR") { - // If generating for the VS 16 IDE, use the same instance. - cmGlobalGenerator* gg = status.GetMakefile().GetGlobalGenerator(); - if (cmHasLiteralPrefix(gg->GetName(), "Visual Studio 16 ")) { - cmGlobalVisualStudioVersionedGenerator* vs16gen = - static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg); - if (vs16gen->GetVSInstance(value)) { - return true; + prev = ch; + } + if (!(key.empty() || value.empty())) { + return std::make_pair(key, value); + } + return {}; +} + +std::map<std::string, std::string> GetOSReleaseVariables( + cmExecutionStatus& status) +{ + auto& makefile = status.GetMakefile(); + const auto& sysroot = makefile.GetSafeDefinition("CMAKE_SYSROOT"); + + std::map<std::string, std::string> data; + // Based on + // https://www.freedesktop.org/software/systemd/man/os-release.html + for (auto name : { "/etc/os-release"_s, "/usr/lib/os-release"_s }) { + const auto& filename = cmStrCat(sysroot, name); + if (cmSystemTools::FileExists(filename)) { + cmsys::ifstream fin(filename.c_str()); + for (std::string line; !std::getline(fin, line).fail();) { + auto kv = ParseOSReleaseLine(line); + if (kv.has_value()) { + data.emplace(kv.value()); + } } + break; } + } + // Got smth? + if (!data.empty()) { + return data; + } + + // Ugh, it could be some pre-os-release distro. + // Lets try some fallback getters. + // See also: + // - http://linuxmafia.com/faq/Admin/release-files.html + + // 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()); - // Otherwise, find a VS 16 instance ourselves. - cmVSSetupAPIHelper vsSetupAPIHelper(16); - if (vsSetupAPIHelper.GetVSInstanceInfo(value)) { - cmSystemTools::ConvertToUnixSlashes(value); + // 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; } - } else if (key == "VS_17_DIR") { - // If generating for the VS 17 IDE, use the same instance. - cmGlobalGenerator* gg = status.GetMakefile().GetGlobalGenerator(); - if (cmHasLiteralPrefix(gg->GetName(), "Visual Studio 17 ")) { - cmGlobalVisualStudioVersionedGenerator* vs17gen = - static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg); - if (vs17gen->GetVSInstance(value)) { - return true; + + 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)); } - // Otherwise, find a VS 17 instance ourselves. - cmVSSetupAPIHelper vsSetupAPIHelper(17); - if (vsSetupAPIHelper.GetVSInstanceInfo(value)) { - cmSystemTools::ConvertToUnixSlashes(value); + // Try 'till some script can get anything + if (!data.empty()) { + data.emplace("USED_FALLBACK_SCRIPT", script); + break; } -#endif - } else { - std::string e = "does not recognize <key> " + key; - status.SetError(e); - return false; } - return true; + makefile.RemoveDefinition(result_variable.data()); + + return data; } -std::string ValueToString(size_t value) +cm::optional<std::string> GetValue(cmExecutionStatus& status, + std::string const& key, + std::string const& variable) { - return std::to_string(value); + const auto prefix = "DISTRIB_"_s; + if (!cmHasPrefix(key, prefix)) { + return {}; + } + + static const std::map<std::string, std::string> s_os_release = + GetOSReleaseVariables(status); + + auto& makefile = status.GetMakefile(); + + const std::string subkey = + key.substr(prefix.size(), key.size() - prefix.size()); + if (subkey == "INFO"_s) { + std::string vars; + for (const auto& kv : s_os_release) { + auto cmake_var_name = cmStrCat(variable, '_', kv.first); + vars += DELIM[!vars.empty()] + cmake_var_name; + makefile.AddDefinition(cmake_var_name, kv.second); + } + return cm::optional<std::string>(std::move(vars)); + } + + // Query individual variable + const auto it = s_os_release.find(subkey); + if (it != s_os_release.cend()) { + return it->second; + } + + // NOTE Empty string means requested variable not set + return std::string{}; +} + +#ifdef HAVE_VS_SETUP_HELPER +cm::optional<std::string> GetValue(cmExecutionStatus& status, + std::string const& key) +{ + auto* const gg = status.GetMakefile().GetGlobalGenerator(); + for (auto vs : { 15, 16, 17 }) { + if (key == cmStrCat("VS_"_s, vs, "_DIR"_s)) { + std::string value; + // If generating for the VS nn IDE, use the same instance. + + if (cmHasPrefix(gg->GetName(), cmStrCat("Visual Studio "_s, vs, ' '))) { + cmGlobalVisualStudioVersionedGenerator* vsNNgen = + static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg); + if (vsNNgen->GetVSInstance(value)) { + return value; + } + } + + // Otherwise, find a VS nn instance ourselves. + cmVSSetupAPIHelper vsSetupAPIHelper(vs); + if (vsSetupAPIHelper.GetVSInstanceInfo(value)) { + cmSystemTools::ConvertToUnixSlashes(value); + } + return value; + } + } + + return {}; } +#endif -std::string ValueToString(const char* value) +cm::optional<std::string> GetValueChained() { - std::string safe_string = value ? value : ""; - return safe_string; + return {}; } -std::string ValueToString(std::string const& value) +template <typename GetterFn, typename... Next> +cm::optional<std::string> GetValueChained(GetterFn current, Next... chain) { - return value; + auto value = current(); + if (value.has_value()) { + return value; + } + return GetValueChained(chain...); } +// END Private functions +} // anonymous namespace + +// cmCMakeHostSystemInformation +bool cmCMakeHostSystemInformationCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + std::size_t current_index = 0; + + if (args.size() < (current_index + 2) || args[current_index] != "RESULT"_s) { + status.SetError("missing RESULT specification."); + return false; + } + + auto const& variable = args[current_index + 1]; + current_index += 2; + + if (args.size() < (current_index + 2) || args[current_index] != "QUERY"_s) { + status.SetError("missing QUERY specification"); + return false; + } + + static cmsys::SystemInformation info; + static auto initialized = false; + if (!initialized) { + info.RunCPUCheck(); + info.RunOSCheck(); + info.RunMemoryCheck(); + initialized = true; + } + + std::string result_list; + for (auto i = current_index + 1; i < args.size(); ++i) { + result_list += DELIM[!result_list.empty()]; + + auto const& key = args[i]; + // clang-format off + auto value = + GetValueChained( + [&]() { return GetValue(info, key); } + , [&]() { return GetValue(status, key, variable); } +#ifdef HAVE_VS_SETUP_HELPER + , [&]() { return GetValue(status, key); } +#endif + ); + // clang-format on + if (!value) { + status.SetError("does not recognize <key> " + key); + return false; + } + result_list += value.value(); + } + + status.GetMakefile().AddDefinition(variable, result_list); + + return true; } diff --git a/Tests/CMakeTests/CMakeLists.txt b/Tests/CMakeTests/CMakeLists.txt index 52959e6..9e0b891 100644 --- a/Tests/CMakeTests/CMakeLists.txt +++ b/Tests/CMakeTests/CMakeLists.txt @@ -31,7 +31,6 @@ AddCMakeTest(CompilerIdVendor "") AddCMakeTest(ProcessorCount "-DKWSYS_TEST_EXE=$<TARGET_FILE:cmsysTestsCxx>") AddCMakeTest(PushCheckState "") AddCMakeTest(While "") -AddCMakeTest(CMakeHostSystemInformation "") AddCMakeTest(FileDownload "") set_tests_properties(CMake.FileDownload PROPERTIES diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index ef797f7..eb2c2d9 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -349,6 +349,7 @@ if(NOT CMake_TEST_EXTERNAL_CMAKE) endif() add_RunCMake_test(execute_process) add_RunCMake_test(export) +add_RunCMake_test(cmake_host_system_information) add_RunCMake_test(cmake_language) add_RunCMake_test(cmake_minimum_required) add_RunCMake_test(cmake_parse_arguments) diff --git a/Tests/RunCMake/cmake_host_system_information/000-FirstFallbackScript.cmake b/Tests/RunCMake/cmake_host_system_information/000-FirstFallbackScript.cmake new file mode 100644 index 0000000..ad873eb --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/000-FirstFallbackScript.cmake @@ -0,0 +1 @@ +message(WARNING "The warning text to match just to make sure the script get executed") diff --git a/Tests/RunCMake/cmake_host_system_information/999-LastFallbackScript.cmake b/Tests/RunCMake/cmake_host_system_information/999-LastFallbackScript.cmake new file mode 100644 index 0000000..08d8da8 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/999-LastFallbackScript.cmake @@ -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 + ) diff --git a/Tests/RunCMake/cmake_host_system_information/BadArg1-result.txt b/Tests/RunCMake/cmake_host_system_information/BadArg1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/BadArg1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/cmake_host_system_information/BadArg1-stderr.txt b/Tests/RunCMake/cmake_host_system_information/BadArg1-stderr.txt new file mode 100644 index 0000000..ed995e6 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/BadArg1-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at BadArg1\.cmake:1 \(cmake_host_system_information\): + cmake_host_system_information missing RESULT specification. +Call Stack \(most recent call first\): + CMakeLists\.txt:7 \(include\) diff --git a/Tests/CMakeTests/CMakeHostSystemInformation-BadArg1.cmake b/Tests/RunCMake/cmake_host_system_information/BadArg1.cmake index 1655eb4..1655eb4 100644 --- a/Tests/CMakeTests/CMakeHostSystemInformation-BadArg1.cmake +++ b/Tests/RunCMake/cmake_host_system_information/BadArg1.cmake diff --git a/Tests/RunCMake/cmake_host_system_information/BadArg2-result.txt b/Tests/RunCMake/cmake_host_system_information/BadArg2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/BadArg2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/cmake_host_system_information/BadArg2-stderr.txt b/Tests/RunCMake/cmake_host_system_information/BadArg2-stderr.txt new file mode 100644 index 0000000..b78c927 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/BadArg2-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at BadArg2\.cmake:1 \(cmake_host_system_information\): + cmake_host_system_information missing QUERY specification +Call Stack \(most recent call first\): + CMakeLists\.txt:7 \(include\) diff --git a/Tests/CMakeTests/CMakeHostSystemInformation-BadArg2.cmake b/Tests/RunCMake/cmake_host_system_information/BadArg2.cmake index 1f056d5..1f056d5 100644 --- a/Tests/CMakeTests/CMakeHostSystemInformation-BadArg2.cmake +++ b/Tests/RunCMake/cmake_host_system_information/BadArg2.cmake diff --git a/Tests/RunCMake/cmake_host_system_information/BadArg3-result.txt b/Tests/RunCMake/cmake_host_system_information/BadArg3-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/BadArg3-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/cmake_host_system_information/BadArg3-stderr.txt b/Tests/RunCMake/cmake_host_system_information/BadArg3-stderr.txt new file mode 100644 index 0000000..c3f1314 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/BadArg3-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at BadArg3\.cmake:1 \(cmake_host_system_information\): + cmake_host_system_information does not recognize <key> FOOBAR +Call Stack \(most recent call first\): + CMakeLists\.txt:7 \(include\) diff --git a/Tests/CMakeTests/CMakeHostSystemInformation-BadArg3.cmake b/Tests/RunCMake/cmake_host_system_information/BadArg3.cmake index 9c5a558..9c5a558 100644 --- a/Tests/CMakeTests/CMakeHostSystemInformation-BadArg3.cmake +++ b/Tests/RunCMake/cmake_host_system_information/BadArg3.cmake diff --git a/Tests/RunCMake/cmake_host_system_information/CMakeLists.txt b/Tests/RunCMake/cmake_host_system_information/CMakeLists.txt new file mode 100644 index 0000000..0198f9b --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.21) + +project(${RunCMake_TEST} NONE) + +set(CMAKE_SYSROOT ${PROJECT_SOURCE_DIR}/${RunCMake_TEST}) + +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/cmake_host_system_information/CentOS6-stdout.txt b/Tests/RunCMake/cmake_host_system_information/CentOS6-stdout.txt new file mode 100644 index 0000000..50dbb08 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/CentOS6-stdout.txt @@ -0,0 +1,7 @@ +-- CENTOS6_ID=`centos` +-- CENTOS6_ID_LIKE=`rhel` +-- CENTOS6_NAME=`CentOS` +-- CENTOS6_PRETTY_NAME=`CentOS release 6\.10 \(Final\)` +-- CENTOS6_USED_FALLBACK_SCRIPT=`.*/Modules/Internal/OSRelease/010-TryOldCentOS.cmake` +-- CENTOS6_VERSION=`6\.10` +-- CENTOS6_VERSION_ID=`6\.10` diff --git a/Tests/RunCMake/cmake_host_system_information/CentOS6.cmake b/Tests/RunCMake/cmake_host_system_information/CentOS6.cmake new file mode 100644 index 0000000..3bc632b --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/CentOS6.cmake @@ -0,0 +1,5 @@ +cmake_host_system_information(RESULT CENTOS6 QUERY DISTRIB_INFO) + +foreach(VAR IN LISTS CENTOS6) + message(STATUS "${VAR}=`${${VAR}}`") +endforeach() diff --git a/Tests/RunCMake/cmake_host_system_information/CentOS6/etc/centos-release b/Tests/RunCMake/cmake_host_system_information/CentOS6/etc/centos-release new file mode 100644 index 0000000..294ccc9 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/CentOS6/etc/centos-release @@ -0,0 +1 @@ +CentOS release 6.10 (Final) diff --git a/Tests/RunCMake/cmake_host_system_information/Debian6-stdout.txt b/Tests/RunCMake/cmake_host_system_information/Debian6-stdout.txt new file mode 100644 index 0000000..4193d6f --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/Debian6-stdout.txt @@ -0,0 +1,5 @@ +-- DEBIAN6_ID=`debian` +-- DEBIAN6_NAME=`Debian` +-- DEBIAN6_USED_FALLBACK_SCRIPT=`.*/Modules/Internal/OSRelease/020-TryDebianVersion.cmake` +-- DEBIAN6_VERSION=`6\.0\.10` +-- DEBIAN6_VERSION_ID=`6\.0\.10` diff --git a/Tests/RunCMake/cmake_host_system_information/Debian6.cmake b/Tests/RunCMake/cmake_host_system_information/Debian6.cmake new file mode 100644 index 0000000..cbf83a9 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/Debian6.cmake @@ -0,0 +1,5 @@ +cmake_host_system_information(RESULT DEBIAN6 QUERY DISTRIB_INFO) + +foreach(VAR IN LISTS DEBIAN6) + message(STATUS "${VAR}=`${${VAR}}`") +endforeach() diff --git a/Tests/RunCMake/cmake_host_system_information/Debian6/etc/debian_version b/Tests/RunCMake/cmake_host_system_information/Debian6/etc/debian_version new file mode 100644 index 0000000..c7d48f0 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/Debian6/etc/debian_version @@ -0,0 +1 @@ +6.0.10 diff --git a/Tests/RunCMake/cmake_host_system_information/Exherbo-stdout.txt b/Tests/RunCMake/cmake_host_system_information/Exherbo-stdout.txt new file mode 100644 index 0000000..11ae71f --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/Exherbo-stdout.txt @@ -0,0 +1,9 @@ +-- TEST1_ANSI_COLOR=`0;32` +-- TEST1_BUG_REPORT_URL=`https://bugs.exherbo.org/` +-- TEST1_HOME_URL=`https://www.exherbo.org/` +-- TEST1_ID=`exherbo` +-- TEST1_NAME=`Exherbo` +-- TEST1_PRETTY_NAME=`Exherbo Linux` +-- TEST1_SUPPORT_URL=`irc://irc.freenode.net/#exherbo` +-- TEST2_ID=`exherbo` +-- TEST2_VERSION=`` diff --git a/Tests/RunCMake/cmake_host_system_information/Exherbo.cmake b/Tests/RunCMake/cmake_host_system_information/Exherbo.cmake new file mode 100644 index 0000000..7fc26d8 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/Exherbo.cmake @@ -0,0 +1,11 @@ +cmake_host_system_information(RESULT TEST1 QUERY DISTRIB_INFO) + +foreach(VAR IN LISTS TEST1) + message(STATUS "${VAR}=`${${VAR}}`") +endforeach() + +# Query individual variables +cmake_host_system_information(RESULT TEST2 QUERY DISTRIB_ID DISTRIB_VERSION) +list(POP_FRONT TEST2 TEST2_ID TEST2_VERSION) +message(STATUS "TEST2_ID=`${TEST2_ID}`") +message(STATUS "TEST2_VERSION=`${TEST2_VERSION}`") diff --git a/Tests/RunCMake/cmake_host_system_information/Exherbo/etc/os-release b/Tests/RunCMake/cmake_host_system_information/Exherbo/etc/os-release new file mode 100644 index 0000000..944c9b4 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/Exherbo/etc/os-release @@ -0,0 +1,7 @@ +NAME="Exherbo" +PRETTY_NAME="Exherbo Linux" +ID="exherbo" +ANSI_COLOR="0;32" +HOME_URL="https://www.exherbo.org/" +SUPPORT_URL="irc://irc.freenode.net/#exherbo" +BUG_REPORT_URL="https://bugs.exherbo.org/" diff --git a/Tests/RunCMake/cmake_host_system_information/QueryKeys-stdout.txt b/Tests/RunCMake/cmake_host_system_information/QueryKeys-stdout.txt new file mode 100644 index 0000000..f583deb --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/QueryKeys-stdout.txt @@ -0,0 +1,27 @@ +-- NUMBER_OF_LOGICAL_CORES=`[0-9]+` +-- NUMBER_OF_PHYSICAL_CORES=`[0-9]+` +-- HOSTNAME=`.*` +-- FQDN=`.*` +-- TOTAL_VIRTUAL_MEMORY=`[0-9]+` +-- AVAILABLE_VIRTUAL_MEMORY=`[0-9]+` +-- TOTAL_PHYSICAL_MEMORY=`[0-9]+` +-- AVAILABLE_PHYSICAL_MEMORY=`[0-9]+` +-- IS_64BIT=`[01]` +-- HAS_FPU=`[01]` +-- HAS_MMX=`[01]` +-- HAS_MMX_PLUS=`[01]` +-- HAS_SSE=`[01]` +-- HAS_SSE2=`[01]` +-- HAS_SSE_FP=`[01]` +-- HAS_SSE_MMX=`[01]` +-- HAS_AMD_3DNOW=`[01]` +-- HAS_AMD_3DNOW_PLUS=`[01]` +-- HAS_IA64=`[01]` +-- HAS_SERIAL_NUMBER=`[01]` +-- PROCESSOR_SERIAL_NUMBER=`.*` +-- PROCESSOR_NAME=`.*` +-- PROCESSOR_DESCRIPTION=`.*` +-- OS_NAME=`.*` +-- OS_RELEASE=`.*` +-- OS_VERSION=`.*` +-- OS_PLATFORM=`.*` diff --git a/Tests/CMakeTests/CMakeHostSystemInformationTest.cmake.in b/Tests/RunCMake/cmake_host_system_information/QueryKeys.cmake index a3c2b05..f22a0ae 100644 --- a/Tests/CMakeTests/CMakeHostSystemInformationTest.cmake.in +++ b/Tests/RunCMake/cmake_host_system_information/QueryKeys.cmake @@ -1,19 +1,8 @@ -set(BadArg1-RESULT 1) -set(BadArg1-STDERR "missing RESULT specification") -set(BadArg2-RESULT 1) -set(BadArg2-STDERR "missing QUERY specification") -set(BadArg3-RESULT 1) -set(BadArg3-STDERR "does not recognize <key> FOOBAR") -set(QueryList-RESULT 0) -set(QueryList-STDERR "\\[[0-9]+;[0-9]+\\]") - function(try_and_print key) - cmake_host_system_information(RESULT RESULT QUERY ${key}) - message(STATUS "[${key}] [${RESULT}]") + cmake_host_system_information(RESULT RESULT QUERY ${key}) + message(STATUS "${key}=`${RESULT}`") endfunction() -message("CTEST_FULL_OUTPUT (Avoid ctest truncation of output)") - try_and_print(NUMBER_OF_LOGICAL_CORES) try_and_print(NUMBER_OF_PHYSICAL_CORES) try_and_print(HOSTNAME) @@ -41,12 +30,3 @@ try_and_print(OS_NAME) try_and_print(OS_RELEASE) try_and_print(OS_VERSION) try_and_print(OS_PLATFORM) - -include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake") - -check_cmake_test(CMakeHostSystemInformation - BadArg1 - BadArg2 - BadArg3 - QueryList -) diff --git a/Tests/RunCMake/cmake_host_system_information/QueryList-stdout.txt b/Tests/RunCMake/cmake_host_system_information/QueryList-stdout.txt new file mode 100644 index 0000000..eebe0d4 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/QueryList-stdout.txt @@ -0,0 +1 @@ +-- \[[0-9]+;[0-9]+\] diff --git a/Tests/CMakeTests/CMakeHostSystemInformation-QueryList.cmake b/Tests/RunCMake/cmake_host_system_information/QueryList.cmake index 1c3156d..f24aa2b 100644 --- a/Tests/CMakeTests/CMakeHostSystemInformation-QueryList.cmake +++ b/Tests/RunCMake/cmake_host_system_information/QueryList.cmake @@ -2,4 +2,4 @@ cmake_host_system_information(RESULT RESULT QUERY NUMBER_OF_LOGICAL_CORES NUMBER_OF_PHYSICAL_CORES ) -message("[${RESULT}]") +message(STATUS "[${RESULT}]") diff --git a/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake b/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake new file mode 100644 index 0000000..189013f --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake @@ -0,0 +1,17 @@ +include(RunCMake) + +run_cmake(BadArg1) +run_cmake(BadArg2) +run_cmake(BadArg3) + +run_cmake(QueryList) +run_cmake(QueryKeys) + +run_cmake(UnitTest) +run_cmake(Exherbo) +run_cmake(Ubuntu) + +run_cmake(CentOS6) +run_cmake(Debian6) + +run_cmake(UserFallbackScript) diff --git a/Tests/RunCMake/cmake_host_system_information/Ubuntu-stdout.txt b/Tests/RunCMake/cmake_host_system_information/Ubuntu-stdout.txt new file mode 100644 index 0000000..d1a18da --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/Ubuntu-stdout.txt @@ -0,0 +1,14 @@ +-- TEST1_BUG_REPORT_URL=`https://bugs\.launchpad\.net/ubuntu/` +-- TEST1_HOME_URL=`https://www\.ubuntu\.com/` +-- TEST1_ID=`ubuntu` +-- TEST1_ID_LIKE=`debian` +-- TEST1_NAME=`Ubuntu` +-- TEST1_PRETTY_NAME=`Ubuntu 20\.04\.2 LTS` +-- TEST1_PRIVACY_POLICY_URL=`https://www\.ubuntu\.com/legal/terms-and-policies/privacy-policy` +-- TEST1_SUPPORT_URL=`https://help\.ubuntu\.com/` +-- TEST1_UBUNTU_CODENAME=`focal` +-- TEST1_VERSION=`20\.04\.2 LTS \(Focal Fossa\)` +-- TEST1_VERSION_CODENAME=`focal` +-- TEST1_VERSION_ID=`20\.04` +-- TEST2_ID=`ubuntu` +-- TEST2_VERSION=`20\.04\.2 LTS \(Focal Fossa\)` diff --git a/Tests/RunCMake/cmake_host_system_information/Ubuntu.cmake b/Tests/RunCMake/cmake_host_system_information/Ubuntu.cmake new file mode 100644 index 0000000..7fc26d8 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/Ubuntu.cmake @@ -0,0 +1,11 @@ +cmake_host_system_information(RESULT TEST1 QUERY DISTRIB_INFO) + +foreach(VAR IN LISTS TEST1) + message(STATUS "${VAR}=`${${VAR}}`") +endforeach() + +# Query individual variables +cmake_host_system_information(RESULT TEST2 QUERY DISTRIB_ID DISTRIB_VERSION) +list(POP_FRONT TEST2 TEST2_ID TEST2_VERSION) +message(STATUS "TEST2_ID=`${TEST2_ID}`") +message(STATUS "TEST2_VERSION=`${TEST2_VERSION}`") diff --git a/Tests/RunCMake/cmake_host_system_information/Ubuntu/etc/os-release b/Tests/RunCMake/cmake_host_system_information/Ubuntu/etc/os-release new file mode 100644 index 0000000..f228f22 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/Ubuntu/etc/os-release @@ -0,0 +1,12 @@ +NAME="Ubuntu" +VERSION="20.04.2 LTS (Focal Fossa)" +ID=ubuntu +ID_LIKE=debian +PRETTY_NAME="Ubuntu 20.04.2 LTS" +VERSION_ID="20.04" +HOME_URL="https://www.ubuntu.com/" +SUPPORT_URL="https://help.ubuntu.com/" +BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" +PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" +VERSION_CODENAME=focal +UBUNTU_CODENAME=focal diff --git a/Tests/RunCMake/cmake_host_system_information/UnitTest-stdout.txt b/Tests/RunCMake/cmake_host_system_information/UnitTest-stdout.txt new file mode 100644 index 0000000..db6f487 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/UnitTest-stdout.txt @@ -0,0 +1,7 @@ +-- UNIT_TEST_A_LIST_LIKE_VARIABLE=`satu;dua;tiga` +-- UNIT_TEST_DBL_QUOTED_VALUE=`"The" value in double "quotes"` +-- UNIT_TEST_DBL_QUOTED_VALUE_STIPPED_COMMENT=`Blah blah blah` +-- UNIT_TEST_NON_SPACE_VALUE=`Blah-blah-blah` +-- UNIT_TEST_QUOTED_VALUE=`'The' value in single 'quotes'` +-- UNIT_TEST_QUOTED_VALUE_STIPPED_COMMENT=`The value in single quotes` +-- UNIT_TEST_THE_URL_WITH_ANCHOR_TEST=`https://blah.blah/resource#anchor` diff --git a/Tests/RunCMake/cmake_host_system_information/UnitTest.cmake b/Tests/RunCMake/cmake_host_system_information/UnitTest.cmake new file mode 100644 index 0000000..d9a0aca --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/UnitTest.cmake @@ -0,0 +1,5 @@ +cmake_host_system_information(RESULT UNIT_TEST QUERY DISTRIB_INFO) + +foreach(VAR IN LISTS UNIT_TEST) + message(STATUS "${VAR}=`${${VAR}}`") +endforeach() diff --git a/Tests/RunCMake/cmake_host_system_information/UnitTest/etc/os-release b/Tests/RunCMake/cmake_host_system_information/UnitTest/etc/os-release new file mode 100644 index 0000000..66c33b5 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/UnitTest/etc/os-release @@ -0,0 +1,9 @@ +# Comment string gonna be ignored +NON_SPACE_VALUE=Blah-blah-blah +QUOTED_VALUE='\'The\' value in single \'quotes\'' +QUOTED_VALUE_STIPPED_COMMENT='The value in single quotes'# The comment right after `'` +DBL_QUOTED_VALUE="\"The\" value in double \"quotes\"" +DBL_QUOTED_VALUE_STIPPED_COMMENT="Blah blah blah"# The comment right after `'` +THE_URL_WITH_ANCHOR_TEST="https://blah.blah/resource#anchor" # And a comment after +A_LIST_LIKE_VARIABLE='satu;dua;tiga' +INCORRECT_ESCAPE_IGNORED=\'This line gonna be ignored' diff --git a/Tests/RunCMake/cmake_host_system_information/UserFallbackScript-stderr.txt b/Tests/RunCMake/cmake_host_system_information/UserFallbackScript-stderr.txt new file mode 100644 index 0000000..78acea2 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/UserFallbackScript-stderr.txt @@ -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\) diff --git a/Tests/RunCMake/cmake_host_system_information/UserFallbackScript-stdout.txt b/Tests/RunCMake/cmake_host_system_information/UserFallbackScript-stdout.txt new file mode 100644 index 0000000..acaf47e --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/UserFallbackScript-stdout.txt @@ -0,0 +1,7 @@ +-- UFS_ID=`unittest` +-- UFS_ID_LIKE=`nothing` +-- UFS_NAME=`UnitTest` +-- UFS_PRETTY_NAME=`Just a Unit Test` +-- UFS_USED_FALLBACK_SCRIPT=`.*/999-LastFallbackScript\.cmake` +-- UFS_VERSION=`0\.0\.1` +-- UFS_VERSION_ID=`0\.0\.1` diff --git a/Tests/RunCMake/cmake_host_system_information/UserFallbackScript.cmake b/Tests/RunCMake/cmake_host_system_information/UserFallbackScript.cmake new file mode 100644 index 0000000..660aa1c --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/UserFallbackScript.cmake @@ -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() |