Is it possible to rename cmake's build directory?

Viewed 36

cmake uses ./build as a standard place to generate build system and to place all intermediate files. Is this a hard requirement or is it possible to use a different name such as ./work? or maybe ./work/build?

To put in context this question. This is an initial idea so I can keep the same top level workflow for different project languages and toolchains.

2 Answers

Yes. The notion that CMake has a "standard" binary directory is incorrect. There is no default. Using build is common, but it is truly just a convention. In general, you can run:

$ cmake -G Ninja -S /path/to/source-dir -B /path/to/binary-dir -DCMAKE_BUILD_TYPE=RelWithDebInfo [...more options...]

Where /path/to/source-dir is the path to the folder containing the top-level CMakeLists.txt. People commonly run CMake from this folder, so this is often just -S .. Similarly, the binary directory, /path/to/binary-dir, is commonly stored beneath the source directory in a folder called build. So in these cases you will see -B ./build.

The values of both flags may be arbitrary, however.

For instance, when building LLVM, I often write:

$ cmake ... -S llvm -B build ... 

because LLVM's "top-level" CMakeLists.txt is actually in the llvm/ subfolder of their monorepo structure. But I still keep the build directory at the top level. I could just as easily have written:

$ cmake ... -S llvm -B $HOME/.binary-trees/llvm ...

Which is a little odd, but perfectly valid.

cmake uses ./build as a standard place to generate build system [...]

This is incorrect. If you're using cmake for configuring without providing a preset and without specifying the source/build directory using the -S ... -B ... options, the current working directory is used as build directory.

A convenient way of providing multiple configurations that also benefits from integration with some IDEs are cmake presets.

Put something like the following in a CMakePresets.json file next to your toplevel CMakeLists.txt file.

{
  "version": 3,
  "cmakeMinimumRequired": {
    "major": 3,
    "minor": 21,
    "patch": 0
  },
  "configurePresets": [
    {
      "name": "linux-x86",
      "displayName": "linux-x86",
      "description": "Linux build release build targeting the x86 architecture",
      "generator": "Unix Makefiles",
      "toolchainFile": "${sourceDir}/toolchains/linux-x86.cmake"
      "binaryDir": "${sourceDir}/build/linux-x86",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": {
          "type": "STRING",
          "value": "Release"
        }
      }
    },
    {
      "name": "linux-x86-debug",
      "displayName": "linux-x86-debug",
      "description": "Linux build debug build targeting the x86 architecture",
      "inherits": "linux-x86",
      "binaryDir": "${sourceDir}/build/linux-x86-debug",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": {
          "type": "STRING",
          "value": "Debug"
        }
      }
    },
    {
      "name": "linux-aarch64",
      "displayName": "linux-aarch64",
      "description": "Linux build release build targeting the aarch64 architecture",
      "inherits": "linux-x86",
      "binaryDir": "${sourceDir}/build/linux-aarch64",
      "toolchainFile": "${sourceDir}/toolchains/linux-aarch64.cmake"
    },
    {
      "name": "linux-aarch64-debug",
      "displayName": "linux-aarch64-debug",
      "description": "Linux build debug build targeting the aarch64 architecture",
      "inherits": "linux-x86-debug",
      "binaryDir": "${sourceDir}/build/linux-aarch64-debug",
      "toolchainFile": "${sourceDir}/toolchains/linux-aarch64.cmake"
    }
    , ...
  ]
}

This does require a minimum cmake version of 3.19 though, 3.21 for this specific json file.

This allows you to use commands like

cmake --preset linux-aarch64-debug .
cmake --preset linux-x86 .

To set up the aarch64 debug build and the linux-x86 release build in build/linux-aarch64-debug and build/linux-x86 respectively.

Related