Reputation: 1273
How can I get CMake options used for building from within a program?
E.g. I would like to use this:
int main()
{
std::cout << "Build options: " << BUILD_OPTIONS << std::endl;
}
BUILD_OPTIONS
would contain a string with all options passed to cmake
, like:
cmake -DOPT1 -DOPT3
with CMakeLists.txt
defined as follows:
option(OPT1 "option 1" OFF)
option(OPT2 "option 2" OFF)
option(OPT3 "option 3" OFF)
The desired output of such program:
Build options: OPT1=ON OPT3=ON
(OPT2
skipped, as it is not defined explicitly and equal to default value)
Upvotes: 1
Views: 1393
Reputation: 1273
It is possible to pass a list of all defines to a program in a single string using generator expressions:
target_compile_options(target PRIVATE "-DENABLED_FEATURES=\"$<JOIN:$<TARGET_PROPERTY:COMPILE_DEFINITIONS>,$<COMMA>>\"")
Using target_compile_options
instead of target_compile_definitions
, as the latter would cause infinite recursion.
In CMake 3.15 and newer it is possible to use REMOVE_DUPLICATES
generator, if a single define may appear several times on a command line.
Upvotes: 0
Reputation: 1273
Finally I'm using the following approach, maybe someone fill find that useful. Instead of option()
function I'm using custom feature_option()
:
include(cmake/options.cmake)
feature_option(OPT1 "option 1" OFF)
feature_option(OPT2 "option 2" OFF)
feature_option(OPT3 "option 3" OFF)
which defines the option and also stores it on a list. Then it can be passed to the compiler via ENABLED_FEATURES
define:
get_feature_list(feature_list)
message(STATUS "Enabled features: ${feature_list}")
target_compile_definitions(target PUBLIC "-DENABLED_FEATURES=\"${feature_list}\"")
Those functions are defined in separate options.cmake
file, so they can be used in project consiting of multiple modules:
function(feature_option option_variable help_string) # optional argument: default_value
option(${option_variable} ${help_string} ${ARGN})
get_property(FEATURE_VARIABLE_LIST GLOBAL PROPERTY FEATURE_VARIABLE_LIST)
set_property(GLOBAL PROPERTY FEATURE_VARIABLE_LIST ${FEATURE_VARIABLE_LIST} ${option_variable})
endfunction()
function(get_feature_list output_variable)
get_property(FEATURE_VARIABLE_LIST GLOBAL PROPERTY FEATURE_VARIABLE_LIST)
foreach(option_variable ${FEATURE_VARIABLE_LIST})
set(option_value "${${option_variable}}")
if(${option_value})
if(feature_list)
set(feature_list "${feature_list},${option_variable}")
else()
set(feature_list "${option_variable}")
endif()
endif()
endforeach()
set(${output_variable} ${feature_list} PARENT_SCOPE)
endfunction()
Upvotes: 0
Reputation: 326
Well, if the program itself was compiled using the CMakeLists.txt file, you could write something along these lines:
option (OPT1 “option 1” OFF)
option (OPT2 “option 2” OFF)
if (OPT1)
add_definitions (-DOPT1_ENABLED)
endif(OPT1)
if (OPT2)
add_definitions (-DOPT2_ENABLED)
endif(OPT2)
Then in your program:
int main(void)
{
std::cout << “Build options: “;
#ifdef OPT1_ENABLED
std::cout << “OPT1=ON ”;
#else
std::cout << “OPT1=OFF ”;
#endif /* OPT1 */
#ifdef OPT2_ENABLED
std::cout << “OPT2=ON ”;
#else
std::cout << “OPT2=OFF ”;
#endif /* OPT2 */
std::cout << endl;
return 0;
}
Upvotes: 0
Reputation: 407
It is possible to use configure_file command with 'cmakedefine' feaure. This is capable to generate something very similar what autotools do i.e. config.h with all enabled/disabled features. The final string may be concatenated from particular sub-string depending if CMake option defined.
Upvotes: 0
Reputation: 9855
I don't know if it is possible to find out if an option has been specified explicitly or not.
The proposed solution will show all option values as specified in a CMake string variable. It consists of 3 steps:
CMakeLists.txt
In CMakeLists.txt
add e.g.
set(BUILD_OPTIONS "OPT1=${OPT1} OPT2=${OPT2} OPT3=${OPT3}")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/build_options.c.in ${CMAKE_CURRENT_BINARY_DIR}/build_options.c @ONLY)
Manually created files:
build_options.c.in
#include "build_options.h"
const char *BUILD_OPTIONS = "@BUILD_OPTIONS@";
build_options.h
#ifndef BUILD_OPTIONS_H_
#define BUILD_OPTIONS_H_
extern const char *BUILD_OPTIONS;
#endif /* BUILD_OPTIONS_H_ */
CMake
will generate build_options.c
#include "build_options.h"
const char *BUILD_OPTIONS = "OPT1=ON OPT2=OFF OPT3=ON";
Upvotes: 1