CMake default install prefix in subprojects

CMake FetchContent is useful to incorporate subprojects at configure time. FetchContent subproject cache variables can override the top-level project cache, which can be confusing.

Projects may wish to use a default install prefix when cmake –install-prefix is not specified. Environment variable CMAKE_INSTALL_PREFIX can set a default install prefix across projects.

Some projects force a default install prefix if not specified by the top level project:

if(PROJECT_IS_TOP_LEVEL AND CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
  set_property(CACHE CMAKE_INSTALL_PREFIX PROPERTY VALUE ${CMAKE_BINARY_DIR}/local)
endif()

However, it is more a canonical approach to check the install prefix write permissions.

message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
file(MAKE_DIRECTORY ${CMAKE_INSTALL_PREFIX})
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.29)
  if(NOT IS_WRITABLE ${CMAKE_INSTALL_PREFIX})
    message(FATAL_ERROR "CMAKE_INSTALL_PREFIX is not writable: ${CMAKE_INSTALL_PREFIX}")
  endif()
else()
  file(TOUCH ${CMAKE_INSTALL_PREFIX}/.cmake_writable "")
endif()

CMake Presets install prefix

CMakePresets.json can set a default install prefix:

{
  "version": 3,

"configurePresets": [
{
  "name": "default",
  "binaryDir": "${sourceDir}/build",
  "installDir": "${sourceDir}/build/local"
}
]
}