How do you create a second debug config with CMake?

In my plugin I want Debug and Debug_Editor. This was easy to do with Projucer, any idea how to do in CMake? I’m trying:

set(CMAKE_CONFIGURATION_TYPES Debug Release Debug_Editor Release_Editor)
set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING "Reset the configurations to what we need" FORCE)

set (CMAKE_C_FLAGS_DEBUG_EDITOR ${CMAKE_C_FLAGS_DEBUG})
set (CMAKE_CXX_FLAGS_DEBUG_EDITOR ${CMAKE_CXX_FLAGS_DEBUG})

However, in Xcode and Visual Studio, NDEBUG and _NDEBUG are still defined for Debug_Editor.

The issue is here in JUCEModuleSupport.cmake line 75. You can’t just assume that the debug config is always just named DEBUG.

function(_juce_add_standard_defs juce_target)
    target_compile_definitions(${juce_target} INTERFACE
        JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1
        $<IF:$<CONFIG:DEBUG>,DEBUG=1 _DEBUG=1,NDEBUG=1 _NDEBUG=1>
        $<$<PLATFORM_ID:Android>:JUCE_ANDROID=1>)
endfunction()

Could you make a change like this: Don't assume the Debug config is named Debug · reFX/JUCE@4ff5fd3 · GitHub

And then I can add set (JUCE_DEBUG_CONFIGS "Debug,Debug_Editor") to my CMakeLists.txt?

You’re right that it’s an error for JUCE to assume the debug config is always just Debug, but CMake already has a property for this built in, I advise against adding a JUCE-specific property/variable for this.

IMHO the correct way to handle this is:

  • JUCE should check the value of the DEBUG_CONFIGURATIONS global property
  • You should set that property in your CMakeLists.txt before adding JUCE

@benvining Does this look better:

function(_juce_add_standard_defs juce_target)
    get_property (CFGS GLOBAL PROPERTY DEBUG_CONFIGURATIONS)

    if (NOT CFGS)
        target_compile_definitions(${juce_target} INTERFACE
            JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1
            $<IF:$<CONFIG:DEBUG>,DEBUG=1 _DEBUG=1,NDEBUG=1 _NDEBUG=1>
            $<$<PLATFORM_ID:Android>:JUCE_ANDROID=1>)
    else ()
        string(TOUPPER "${CFGS}" CFGS)
        string(REPLACE ";" "," CFGS "${CFGS}")

        target_compile_definitions(${juce_target} INTERFACE
            JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1
            $<IF:$<CONFIG:${CFGS}>,DEBUG=1 _DEBUG=1,NDEBUG=1 _NDEBUG=1>
            $<$<PLATFORM_ID:Android>:JUCE_ANDROID=1>)
    endif ()
endfunction()
1 Like

I would write it like this:

function(_juce_add_standard_defs juce_target)

  get_cmake_property (debug_configs DEBUG_CONFIGURATIONS)

  if(NOT debug_configs)
    set (debug_configs Debug)
  endif()

  list (JOIN debug_configs "," debug_configs)

  target_compile_definitions ("${juce_target}" INTERFACE
    JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1
    $<IF:$<CONFIG:${debug_configs}>,DEBUG=1 _DEBUG=1,NDEBUG=1 _NDEBUG=1>
    $<$<PLATFORM_ID:Android>:JUCE_ANDROID=1>)

endfunction()

The following in JUCEHelperTargets.cmake also needs to be updated to support multiple configs.

# ==================================================================================================

add_library(juce_recommended_config_flags INTERFACE)
add_library(juce::juce_recommended_config_flags ALIAS juce_recommended_config_flags)

if((CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC"))
    target_compile_options(juce_recommended_config_flags INTERFACE
        $<IF:$<CONFIG:Debug>,/Od /Zi,/Ox> $<$<STREQUAL:"${CMAKE_CXX_COMPILER_ID}","MSVC">:/MP> /EHsc)
elseif((CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
       OR (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
       OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"))
    target_compile_options(juce_recommended_config_flags INTERFACE
        $<$<CONFIG:Debug>:-g -O0>
        $<$<CONFIG:Release>:-O3>)
endif()

# ==================================================================================================

add_library(juce_recommended_lto_flags INTERFACE)
add_library(juce::juce_recommended_lto_flags ALIAS juce_recommended_lto_flags)

if((CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC"))
    target_compile_options(juce_recommended_lto_flags INTERFACE
        $<$<CONFIG:Release>:$<IF:$<STREQUAL:"${CMAKE_CXX_COMPILER_ID}","MSVC">,-GL,-flto>>)
    target_link_libraries(juce_recommended_lto_flags INTERFACE
        $<$<CONFIG:Release>:$<$<STREQUAL:"${CMAKE_CXX_COMPILER_ID}","MSVC">:-LTCG>>)
elseif((NOT MINGW) AND ((CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
                     OR (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
                     OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")))
    target_compile_options(juce_recommended_lto_flags INTERFACE $<$<CONFIG:Release>:-flto>)
    target_link_libraries(juce_recommended_lto_flags INTERFACE $<$<CONFIG:Release>:-flto>)
endif()

Yeah you’re right. The same generator expression pattern I showed above can be used here.

1 Like

I think I have it all working now, I’ve squashed it all into one commit.

1 Like

The multi-argument form of $<CONFIG> isn’t supported in JUCE’s minimum-required CMake (3.15). I’ve got a patch on the way that should work for all of the CMake versions we support.

2 Likes

Is there a reason for this low requirement? Is there a block preventing people from installing a later version of CMake?