Issue
I use cmake 3.22. I try to get root directory of the my project in the install[CODE] section in the my top level CMakeLists.txt file:
cmake_minimum_required(VERSION 3.22)
...
project(myProject CXX)
...
install(CODE [[
message(STATUS "PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}")
message(STATUS "CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR}")
message(STATUS "CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}")
]])
I get the following outputs during installation ${PROJECT_SOURCE_DIR}
:
-- PROJECT_SOURCE_DIR:
-- CMAKE_BINARY_DIR: /project_root/build/config_type_dir
-- CMAKE_SOURCE_DIR: /project_root/build/config_type_dir
But I need to get my /project_root
path.
Doc says about ${PROJECT_SOURCE_DIR}
variable:
This is the source directory of the last call to the project() command made in the current directory scope or one of its parents.
https://cmake.org/cmake/help/latest/variable/PROJECT_SOURCE_DIR.html
Is it a bug? Or I do something wrong?
Solution
Is it a bug? Or I do something wrong?
No, it's just that not all variables are available in install(CODE)
segments. Here's a simple demo of detecting all the variables available there:
cmake_minimum_required(VERSION 3.24)
project(example)
install(CODE [[
get_property(vars DIRECTORY PROPERTY VARIABLES)
foreach (var IN LISTS vars)
message(STATUS "${var} = ${${var}}")
endforeach ()
]])
See in the terminal:
$ cmake -S . -B build
-- Install configuration: ""
-- CMAKE_ARGC = 4
-- CMAKE_ARGV0 = /home/reinking/.local/lib/python3.9/site-packages/cmake/data/bin/cmake
-- CMAKE_ARGV1 = -DCMAKE_INSTALL_PREFIX=foo
-- CMAKE_ARGV2 = -P
-- CMAKE_ARGV3 = /path/to/build/cmake_install.cmake
-- CMAKE_BINARY_DIR = /path/to
-- CMAKE_COMMAND = /home/reinking/.local/lib/python3.9/site-packages/cmake/data/bin/cmake
-- CMAKE_CPACK_COMMAND = /home/reinking/.local/lib/python3.9/site-packages/cmake/data/bin/cpack
-- CMAKE_CROSSCOMPILING = FALSE
-- CMAKE_CTEST_COMMAND = /home/reinking/.local/lib/python3.9/site-packages/cmake/data/bin/ctest
-- CMAKE_CURRENT_BINARY_DIR = /path/to
-- CMAKE_CURRENT_LIST_DIR = /path/to/build
-- CMAKE_CURRENT_LIST_FILE = /path/to/build/cmake_install.cmake
-- CMAKE_CURRENT_SOURCE_DIR = /path/to
-- CMAKE_FILES_DIRECTORY = /CMakeFiles
-- CMAKE_HOST_SYSTEM_NAME = Linux
-- CMAKE_HOST_UNIX = 1
-- CMAKE_INSTALL_CONFIG_NAME =
-- CMAKE_INSTALL_PREFIX = foo
-- CMAKE_INSTALL_PREFIX = foo
-- CMAKE_INSTALL_SO_NO_EXE = 1
-- CMAKE_MAJOR_VERSION = 3
-- CMAKE_MINOR_VERSION = 24
-- CMAKE_OBJDUMP = /usr/bin/objdump
-- CMAKE_PATCH_VERSION = 1
-- CMAKE_ROOT = /home/reinking/.local/lib/python3.9/site-packages/cmake/data/share/cmake-3.24
-- CMAKE_SCRIPT_MODE_FILE = /path/to/build/cmake_install.cmake
-- CMAKE_SOURCE_DIR = /path/to
-- CMAKE_TWEAK_VERSION = 0
-- CMAKE_VERSION = 3.24.1
-- UNIX = 1
So if you want to bake a variable into your install script, you'll have to generate the file. Here's one technique:
string(CONFIGURE [[
set(PROJECT_SOURCE_DIR "@PROJECT_SOURCE_DIR@")
message(STATUS "PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}")
message(STATUS "CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR}")
message(STATUS "CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}")
]] install_script @ONLY)
install(CODE "${install_script}")
Answered By - Alex Reinking Answer Checked By - Willingham (WPSolving Volunteer)