I want to achieve the equivalent of C #define foo "bar"
but I don't want the value "bar"
to be part of my code repository, and the value will depend on whether the build is Debug or Release.
How can I do this?
NB: I like the idea of using the following in CMakeLists.txt add_compile_definitions(foo="bar")
but I don't know how to supply "bar"
from the Qt Creator build settings.
Presumably I'd add a Key/Value pair but what would I put?
CodePudding user response:
I would suggest you to set the definition using target_compile_definitions
:
target_compile_definitions(myexe PUBLIC foo="bar")
To set it to different things depending if it's release or debug, using generator expressions would make those options portable when using a multi config generator:
target_compile_definitions(myexe PUBLIC
$<$<CONFIG:Debug>:foo="bar">
$<$<CONFIG:Release>:baz="bat">
)
If you really don't want the bar
option to be present in your repository including the CMake files, there are ways to define that too.
You can send it as part of a command line option. For thst you can define that command line option using the option
command, then send the command line argument using a preset:
option(MYPROJECT_MY_OPTION "Activate the definitions" OFF)
if(MYPROJECT_MY_OPTION)
target_compile_definitions(myexe PUBLIC
$<$<CONFIG:Debug>:foo=bar">
$<$<CONFIG:Release>:baz="bat">
)
endif()
Then create some profiles:
{
"version": 2,
"cmakeMinimumRequired": {
"major": 3,
"minor": 22,
"patch": 0
},
"configurePresets": [
{
"name": "cmake-pedantic",
"hidden": true,
"warnings": {
"dev": false,
"deprecated": true,
"uninitialized": true,
"unusedCli": true,
"systemVars": false
},
"errors": {
"dev": false,
"deprecated": true
}
},
{
"name": "generator-ninja",
"hidden": true,
"generator": "Ninja Multi-Config",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_DEBUG_POSTFIX": "d",
"CMAKE_MAKE_PROGRAM": "ninja"
}
},
{
"name": "dev",
"displayName": "Development",
"description": "Development preset",
"inherits": ["generator-ninja"]
},
{
"name": "dev-with-option",
"displayName": "Development",
"description": "Development preset",
"binaryDir": "${sourceDir}/build-with-option",
"inherits": ["generator-ninja"],
"cacheVariables": {
"MYPROJECT_MY_OPTION": true
}
}
],
"buildPresets": [
{
"name": "dev-debug",
"displayName": "Debug",
"description": "Build with debug informations",
"configuration": "Debug",
"configurePreset": "dev"
},
{
"name": "dev-relwithdebinfo",
"displayName": "RelWithDebInfo",
"description": "Build with debug informations and optimizations enabled",
"configuration": "RelWithDebInfo",
"configurePreset": "dev"
},
{
"name": "dev-release",
"displayName": "Release",
"description": "Build with optimizations enabled",
"configuration": "Release",
"configurePreset": "dev"
},
{
"name": "dev-with-option-debug",
"displayName": "Debug",
"description": "Build with debug informations",
"configuration": "Debug",
"configurePreset": "dev-with-option"
},
{
"name": "dev-with-option-relwithdebinfo",
"displayName": "RelWithDebInfo",
"description": "Build with debug informations and optimizations enabled",
"configuration": "RelWithDebInfo",
"configurePreset": "dev-with-option"
},
{
"name": "dev-with-option-release",
"displayName": "Release",
"description": "Build with optimizations enabled",
"configuration": "Release",
"configurePreset": "dev-with-option"
}
],
"testPresets": [
{
"name": "base-test",
"hidden": true,
"output": {
"outputOnFailure": true
},
"execution": {
"noTestsAction": "error",
"stopOnFailure": true
}
},
{
"name": "dev-debug",
"displayName": "Debug",
"configuration": "Debug",
"configurePreset": "dev",
"inherits": "base-test"
},
{
"name": "dev-relwithdebinfo",
"displayName": "RelWithDebInfo",
"configuration": "RelWithDebInfo",
"configurePreset": "dev",
"inherits": "base-test"
},
{
"name": "dev-release",
"displayName": "Release",
"configuration": "Release",
"configurePreset": "dev",
"inherits": "base-test"
},
{
"name": "dev-with-option-debug",
"displayName": "Debug",
"configuration": "Debug",
"configurePreset": "dev",
"inherits": "base-test"
},
{
"name": "dev-with-option-relwithdebinfo",
"displayName": "RelWithDebInfo",
"configuration": "RelWithDebInfo",
"configurePreset": "dev",
"inherits": "base-test"
},
{
"name": "dev-with-option-release",
"displayName": "Release",
"configuration": "Release",
"configurePreset": "dev",
"inherits": "base-test"
}
]
}
This will allow IDEs to select between dev
and dev-with-option
, and also allow the IDE to select debug or release configs.
CodePudding user response:
You need a 2 step process:
- Add a Qt Creator build setting to create a CMake cache variable.
- In CMakeLists.txt use the cache variable within a command.
For your example:
- In Qt Creator build settings,
- either click Add > String setting Key to
MYPROJECT_FOO
and Value tobar
- or click Batch Edit... and add
-DMYPROJECT_FOO:STRING=bar
- In CMakeLists,
target_compile_definitions(mytarget PUBLIC foo="${MYPROJECT_FOO}")
(As advised by Guillaume Racicot it's better to apply the definition to a single target, as opposed to the entire project, which would be add_compile_definitions(foo="${MYPROJECT_FOO}")
.)
See also Qt Creator documentation CMake Build Configuration: Modifying Variable Values.
Thanks to Guillaume Racicot for deeper explanation of how CMake cache variables can be used.