Tuesday, February 6, 2024

[SOLVED] Is the system processor available in CMakePreset.json?

Issue

Visual Studio generated the following CMakePresets.json for me when I click on "Manage Configurations..." in a CMake project:

{
  "version": 3,
  "configurePresets": [
    {
      "name": "windows-base",
      "description": "Target Windows with the Visual Studio development environment.",
      "hidden": true,
      "generator": "Ninja",
      "binaryDir": "${sourceDir}/out/build/${presetName}",
      "installDir": "${sourceDir}/out/install/${presetName}",
      "cacheVariables": {
        "CMAKE_C_COMPILER": "cl.exe",
        "CMAKE_CXX_COMPILER": "cl.exe"
      },
      "condition": {
        "type": "equals",
        "lhs": "${hostSystemName}",
        "rhs": "Windows"
      }
    },
    {
      "name": "x64-debug",
      "displayName": "x64 Debug",
      "description": "Target Windows (64-bit) with the Visual Studio development environment. (Debug)",
      "inherits": "windows-base",
      "architecture": {
        "value": "x64",
        "strategy": "external"
      },
      "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" }
    },
    {
      "name": "x64-release",
      "displayName": "x64 Release",
      "description": "Target Windows (64-bit) with the Visual Studio development environment. (RelWithDebInfo)",
      "inherits": "x64-debug",
      "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" }
    },
    {
      "name": "x86-debug",
      "displayName": "x86 Debug",
      "description": "Target Windows (32-bit) with the Visual Studio development environment. (Debug)",
      "inherits": "windows-base",
      "architecture": {
        "value": "x86",
        "strategy": "external"
      },
      "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" }
    },
    {
      "name": "x86-release",
      "displayName": "x86 Release",
      "description": "Target Windows (32-bit) with the Visual Studio development environment. (RelWithDebInfo)",
      "inherits": "x86-debug",
      "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" }
    }
  ]
}

I'm interested in the cmake install prefix, which is set with the installDir field. It is nice because the resulting directory will indirectly include the processor name "x64" since the preset name includes the processor.

But the processor name is hardcoded, i.e. it is part of the string literal, e.g. "x64-debug", in the various preset names. Is it possible to reference the processor as a variable (or macro expansion) in CMakePresets.json? I.e. something similar to the CMAKE_SYSTEM_PROCESSOR cache variable that is available in CMakeLists.txt?


Solution

No it is not. The full list of available macros can be found here.

It is currently limited to

  • ${sourceDir}: Path to the project source directory (i.e. the same as CMAKE_SOURCE_DIR).
  • ${sourceParentDir}: Path to the project source directory's parent directory.
  • ${sourceDirName}: The last filename component of ${sourceDir}. For example, if ${sourceDir} is /path/to/source, this would be source.
  • ${presetName}: Name specified in the preset's name field.
  • ${generator}: Generator specified in the preset's generator field. For build and test presets, this will evaluate to the generator specified by configurePreset.
  • ${hostSystemName}:The name of the host operating system. Contains the same value as CMAKE_HOST_SYSTEM_NAME. This is allowed in preset files specifying version 3 or above.
  • ${fileDir}: Path to the directory containing the preset file which contains the macro. This is allowed in preset files specifying version 4 or above.
  • ${dollar}: A literal dollar sign ($).
  • ${pathListSep}: Native character for separating lists of paths, such as : or ;. For example, by setting PATH to /path/to/ninja/bin${pathListSep}$env{PATH}, ${pathListSep} will expand to the underlying operating system's character used for concatenation in PATH. This is allowed in preset files specifying version 5 or above.
  • $env{<variable-name>}: Environment variable with name <variable-name>. The variable name may not be an empty string. If the variable is defined in the environment field, that value is used instead of the value from the parent environment. If the environment variable is not defined, this evaluates as an empty string. Note that while Windows environment variable names are case-insensitive, variable names within a preset are still case-sensitive. This may lead to unexpected results when using inconsistent casing. For best results, keep the casing of environment variable names consistent.
  • $penv{<variable-name>}: Similar to $env{<variable-name>}, except that the value only comes from the parent environment, and never from the environment field. This allows you to prepend or append values to existing environment variables. For example, setting PATH to /path/to/ninja/bin:$penv{PATH} will prepend /path/to/ninja/bin to the PATH environment variable. This is needed because $env{<variable-name>} does not allow circular references.
  • $vendor{<macro-name>}: An extension point for vendors to insert their own macros. CMake will not be able to use presets which have a $vendor{<macro-name>} macro, and effectively ignores such presets. However, it will still be able to use other presets from the same file. CMake does not make any attempt to interpret $vendor{<macro-name>} macros. However, to avoid name collisions, IDE vendors should prefix <macro-name> with a very short (preferably <= 4 characters) vendor identifier prefix, followed by a ., followed by the macro name. For example, the Example IDE could have $vendor{xide.ideInstallDir}.


Answered By - Corristo
Answer Checked By - Gilberto Lyons (WPSolving Admin)