Home > Net >  Configure CMake with a Custom flag
Configure CMake with a Custom flag

Time:06-23

I have a CMake Project with a macro inside my CPP file to enable some debugging code, as shown below:

main.cpp

#ifdef MY_FLAG_DEBUG
  // added for debugging only
  cv::imwrite("segmentation.png", img);
#endif

I defined MY_FLAG_DEBUG inside CMakeLists.txt. Please see below:

CMakeLists.txt

option(MY_FLAG "Use MY_FLAG" OFF) # OFF by default
if(MY_FLAG)
  add_definitions(-DMY_FLAG_DEBUG)
endif()

# if(MY_FLAG)
#   target_compile_definitions(${PROJECT_NAME}
#     PRIVATE "${PROJECT_NAME}_BUILDING_DLL"
#     PRIVATE MY_FLAG_DEBUG
#   )
# else()
#   target_compile_definitions(${PROJECT_NAME}
#     PRIVATE "${PROJECT_NAME}_BUILDING_DLL"
#   )
# endif(MY_FLAG)

target_compile_definitions(${PROJECT_NAME}
  PRIVATE "${PROJECT_NAME}_BUILDING_DLL"
)

It works BUT shows the following error when no command-line argument is given (MY_FLAG is unset):

CMake Warning:
  Manually-specified variables were not used by the project:

    MY_FLAG

The above approach declares two variables inside CMakeLists.txt to enable a macro. Moreover, it turned out that the above is an old practice, and target_compile_definitions should be preferred. I tried, but it could not work. Please see the commented lines in the CMakeLists.txt file. In addition, I found the following posts 1 and 2. Unfortunately, they did not discuss unused variables.

My goal is to enable the macro only when specified as a command-line argument.

Questions

  1. How to use a newer command, i.e., target_compile_definitions in this case?
  2. How to modify the existing approach so that CMake does not display a warning?

CodePudding user response:

Probably the issue is the wrong target name in the target_compile_definitions command; you are using ${PROJECT_NAME} instead of the named target.
The quote from cmake manual:
"The named target must have been created by a command such as add_executable() or add_library()"

CMakeList.txt

cmake_minimum_required(VERSION 3.22)
project(my_flag_proj)
option(MY_FLAG "Use MY_FLAG" OFF) # OFF by default

add_executable(my_flag_test)
target_sources(my_flag_test PRIVATE main.cpp)
if(MY_FLAG)
   target_compile_definitions(my_flag_test
     PRIVATE "${PROJECT_NAME}_BUILDING_DLL"
     PRIVATE MY_FLAG_DEBUG
   )
 else()
   target_compile_definitions(my_flag_test
     PRIVATE "${PROJECT_NAME}_BUILDING_DLL"
   )
endif(MY_FLAG)

main.cpp

#include <iostream>

int main() {
#ifdef MY_FLAG_DEBUG
    std::cout << "MY_FLAG_DEBUG is defined" << std::endl;
#else
    std::cout << "MY_FLAG_DEBUG is undefined" << std::endl;
#endif
    return 0;
}

Output

$cmake -S . -B flagOn -DMY_FLAG=ON 
$cmake -S . -B flagOff
$cmake --build flagOn
$cmake --build flagOff
$./flagOff/my_flag_test && ./flagOn/my_flag_test 
MY_FLAG_DEBUG is defined
MY_FLAG_DEBUG is undefined

CodePudding user response:

If you want to use custom CMake flags, call cmake as such:

~/proj/build $ cmake .. -DMY_TARGET_THING=1

Make sure you prefix it with -D and give it a value, otherwise CMake won't parse the option

  • Related