Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make cMake use Debug compilation mode for only a subset of directories in a project?

Tags:

cmake

Rephrased the question.

I have the following problem:

My project has several binaries and libraries that reside in distinct sub-directories under the main project folder. It is useful to be able to debug only a subset of them, without recompiling the whole project in Debug mode.

I want to be able to only change the compilation mode for this subset in a semi-automatic fashion.

How can I accomplish this using CMake?

like image 995
Marco Costa Avatar asked Sep 19 '25 06:09

Marco Costa


1 Answers

If you change the build type, the whole project will be recompiled from scratch. Usually you keep 2 separated build tree, one configured debug and one configured release.

Note that CMAKE_BUILD_TYPE can be set from command line or from cmake-gui, you shouldn't set it in the CMakeLists.txt file.


To compile only some part of your project in debug mode, you can proceed as follow. In your main CMakeLists.txt, before including any subdirectory, define the following macro:
macro (CHECK_IF_DEBUG)
  if (NOT (CMAKE_BUILD_TYPE MATCHES Debug))
    get_filename_component(THIS_DIR ${CMAKE_CURRENT_SOURCE_DIR} NAME)
    STRING(REGEX REPLACE " " "_" THIS_DIR ${THIS_DIR}) #Replace spaces with underscores
    if (DEFINED DEBUG_${THIS_DIR})
      message(STATUS "Note: Targets in directory ${THIS_DIR} will be built Debug") #A reminder
      set (CMAKE_BUILD_TYPE Debug)
    endif()
  endif()
endmacro()

Then, in each subdirectory add (at the beginning of the CMakelists.txt) the macro call

 CHECK_IF_DEBUG()

When you need to temporarily debug a part (subdirectory) of your project, open your project in cmake-gui, and define a variable ("Add Entry") with name DEBUG_<DirectoryName>. You can define multiple ones. If your directory name contains spaces, in the variable name replace them with underscores. Don't forget to click Configure and Generate from cmake-gui to make the change effective. The value assigned to the variable is not important, it can be left empty.

When you are finished debugging, go back to cmake-gui and remove the corresponding entries. Don't forget to Configure and Generate.

I have tested it in a small project and it seems to work properly.

Note: If you create more than one target (add_library or add_executable) in the same CMakeLists.txt (=in the same subdirectory), I haven't found a way to have one target built in one way and one target in another: the only thing that seems to count is the value of the CMAKE_BUILD_TYPE directory when CMake is finished parsing the file.


In answer to your comment, you can have a reminder printed at build time by adding in the block the following line:

add_custom_target(info_${THIS_DIR} ALL COMMAND echo Targets in directory ${THIS_DIR} are built Debug)

See add_custom_target.

like image 180
Antonio Avatar answered Sep 21 '25 13:09

Antonio