CMake visual studio debug/release config

I'm setting up my visual studio project to use CMake, but I got two issues I haven't been able to solve yet.

1 How can I set a preprocessor define for Release and another for Debug?

2 I have a project with opengl and directx so for DebugOpenGL and ReleaseOpenGL i want to exclude all directx cpp/h files from the buld. With DebugDirectX and ReleaseDirectx exclude the opengl files. How do I set this up?

EDIT:

Heres what I got for 1. so far:

cmake_minimum_required(VERSION 2.8)

project(TEngine)

if(CMAKE_CONFIGURATION_TYPES AND MSVC)
#DebugOpenGL flags
set(CMAKE_CXX_FLAGS_DEBUGOPENGL "/D_DEBUG /MDd /Zi /Ob0 /Od /RTC1" CACHE STRING "Flags used by the C++ compiler during maintainer builds." FORCE)
set(CMAKE_C_FLAGS_DEBUGOPENGL "/D_DEBUG /MDd /Zi  /Ob0 /Od /RTC1" CACHE STRING "Flags used by the C compiler during maintainer builds." FORCE)
set(CMAKE_EXE_LINKER_FLAGS_DEBUGOPENGL "/debug /INCREMENTAL" CACHE STRING "Flags used for linking binaries during maintainer builds." FORCE )
set(CMAKE_SHARED_LINKER_FLAGS_DEBUGOPENGL "/debug /INCREMENTAL" CACHE STRING "Flags used by the shared libraries linker during maintainer builds." FORCE )

#ReleaseOpenGL flags
set(CMAKE_CXX_FLAGS_RELEASEOPENGL "/MD /O2 /Ob2 /D NDEBUG" CACHE STRING "Flags used by the C++ compiler during maintainer builds." FORCE)
set(CMAKE_C_FLAGS_RELEASEOPENGL "/MD /O2 /Ob2 /D NDEBUG" CACHE STRING "Flags used by the C compiler during maintainer builds." FORCE)
set(CMAKE_EXE_LINKER_FLAGS_RELEASEOPENGL "/INCREMENTAL:NO" CACHE STRING "Flags used for linking binaries during maintainer builds." FORCE )
set(CMAKE_SHARED_LINKER_FLAGS_RELEASEOPENGL "/INCREMENTAL:NO" CACHE STRING "Flags used by the shared libraries linker during maintainer builds." FORCE )

#DebugDirectX flags
set(CMAKE_CXX_FLAGS_DEBUGDIRECTX "/D_DEBUG /MDd /Zi /Ob0 /Od /RTC1" CACHE STRING "Flags used by the C++ compiler during maintainer builds." FORCE)
set(CMAKE_C_FLAGS_DEBUGDIRECTX "/D_DEBUG /MDd /Zi  /Ob0 /Od /RTC1" CACHE STRING "Flags used by the C compiler during maintainer builds." FORCE)
set(CMAKE_EXE_LINKER_FLAGS_DEBUGDIRECTX "/debug /INCREMENTAL" CACHE STRING "Flags used for linking binaries during maintainer builds." FORCE )
set(CMAKE_SHARED_LINKER_FLAGS_DEBUGDIRECTX "/debug /INCREMENTAL" CACHE STRING "Flags used by the shared libraries linker during maintainer builds." FORCE )

#ReleaseDirectx flags
set(CMAKE_CXX_FLAGS_RELEASEDIRECTX "/MD /O2 /Ob2 /D NDEBUG" CACHE STRING "Flags used by the C++ compiler during maintainer builds." FORCE)
set(CMAKE_C_FLAGS_RELEASEDIRECTX "/MD /O2 /Ob2 /D NDEBUG" CACHE STRING "Flags used by the C compiler during maintainer builds." FORCE)
set(CMAKE_EXE_LINKER_FLAGS_RELEASEDIRECTX "/INCREMENTAL:NO" CACHE STRING "Flags used for linking binaries during maintainer builds." FORCE )
set(CMAKE_SHARED_LINKER_FLAGS_RELEASEDIRECTX "/INCREMENTAL:NO" CACHE STRING "Flags used by the shared libraries linker during maintainer builds." FORCE )

set(CMAKE_CONFIGURATION_TYPES "DebugOpenGL;ReleaseOpenGL;DebugDirectX;ReleaseDirectX")
set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING
"Reset the configurations to what we need"
FORCE)

if(CMAKE_BUILD_TYPE STREQUAL "DebugOpenGL")
    add_definitions(/DTE_USE_OPENGL)
endif()
if(CMAKE_BUILD_TYPE STREQUAL "ReleaseOpenGL")
    add_definitions(/DTE_USE_OPENGL)
endif()
if(CMAKE_BUILD_TYPE STREQUAL "DebugDirectX")
    add_definitions(/DTE_USE_OPENGL)
endif()
if(CMAKE_BUILD_TYPE STREQUAL "ReleaseDirectX")
    add_definitions(/DTE_USE_OPENGL)
endif()
endif()

set(Boost_ADDITIONAL_VERSIONS "1.47" "1.47.0")
set(BOOST_ROOT "${TEngine_SOURCE_DIR}/Externals/boost_1_47_0")

if(WIN32)
    add_definitions(-DTEWINDOWS)
elseif(LINUX)
    add_definitions(-DTELINUX -DTE_USE_OPENGL)
endif()

subdirs(TEEngineTest TECore TEGraphics TEPhysics TEngine)

Answers


1:

if(CMAKE_BUILD_TYPE STREQUAL "Debug")
  add_definitions(/DYOURDEFINITION)
endif()

2: If i understood you right, you need to create an option variable

option(USE_OPENGL "Use OpenGL or DirectX")

And then check for it when you are adding new target:

if(USE_OPENGL)
add_subdirectory(OpenGL)
else()
add_subdirectory(DirectX)
endif()

Of course, you should create CMakeLists.txt in OpenGL/ and DirectX/ dirs.


  1. How can I set a preprocessor define for Release and another for Debug?

The proper way to do this is to set the COMPILE_DEFINITIONS property at the correct scope using generator expressions.

If you want to add definitions to all targets like add_definitions() does then use:

  set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS
    $<$<CONFIG:DebugOpenGL>:_DEBUG>
    $<$<CONFIG:ReleaseOpenGL>:NDEBUG>
    $<$<CONFIG:DebugDirectX>:_DEBUG>
    $<$<CONFIG:ReleaseDirectX>:NDEBUG>
  )

  set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS
    $<$<CONFIG:DebugOpenGL>:TE_USE_OPENGL>
    $<$<CONFIG:ReleaseOpenGL>:TE_USE_OPENGL>
    $<$<CONFIG:DebugDirectX>:TE_USE_DIRECTX>
    $<$<CONFIG:ReleaseDirectX>:TE_USE_DIRECTX>
  )

You can also set COMPILE_DEFINITIONS for just a target or a specific source file. See set_property.

In order to set other compile flags you can set the COMPILE_OPTIONS property on a directory, target, or source file just like above. However you can also use the add_compile_options() command because unlike add_definitions() it supports generator expressions. You can set COMPILE_OPTIONS for targets as well, or use target_compile_options(). For source files, as of CMake 3.3, you still have to set the COMPILE_FLAGS property.

  set(MY_DEBUG_OPTIONS /MDd /Zi /Ob0 /Od /RTC1)
  set(MY_RELEASE_OPTIONS /MD /Ob2 /O2)

  add_compile_options(
    "$<$<CONFIG:DebugOpenGL>:${MY_DEBUG_OPTIONS}>"
    "$<$<CONFIG:ReleaseOpenGL>:${MY_RELEASE_OPTIONS}>"
    "$<$<CONFIG:DebugDirectX>:${MY_DEBUG_OPTIONS}>"
    "$<$<CONFIG:ReleaseDirectX>:${MY_RELEASE_OPTIONS}>"
  )

Note that putting lists of options inside these generator expressions requires the quotes in add_compile_options().

  1. I have a project with opengl and directx so for DebugOpenGL and ReleaseOpenGL i want to exclude all directx cpp/h files from the buld. With DebugDirectX and ReleaseDirectx exclude the opengl files. How do I set this up?

This may be a problem. Although it's possible to use generator expressions to add source files to a target conditionally, I don't know of any IDEs that support per-configuration source files. Visual Studio and CMake's Visual Studio generator does not support it. Xcode and the Xcode generator also does not support this. So if you want to build with Visual Studio or another IDE you can't do this.

Generators that use a single configuration at a time such as the makefile or ninja generators should support this just fine.

Instead of having the source files differ between configurations there are several other options. Here are a couple.

You can have multiple targets and have the source differ between them:

set(OPENGL_SOURCES src/opengl/func1.cpp src/opengl/func2.cpp)
set(DIRECTX_SOURCES src/opengl/func1.cpp src/opengl/func2.cpp)

add_executable(opengl_foo ${COMMON_SOURCES} ${OPENGL_SOURCES})
add_executable(directx_foo ${COMMON_SOURCES} ${DIRECTX_SOURCES})

Note that this means you can go back to just having Debug and Release configs which will simplify the rest of your configuration as well.

Alternatively, you can keep your seperate OpenGL and DirectX configs by using some indirection in your source code. Have some 'dummy' cpp files and header files that switch between #includeing your opengl files or directx files based on a preprocessor define:

// src/func1.h
#ifdef TE_USE_OPENGL
#  include "opengl/func1.h.inc"
#elif defined(TC_USE_DIRECTX)
#  include "directx/func1.h.inc"
#endif

// src/func1.cpp
#ifdef TE_USE_OPENGL
#  include "opengl/func1.cpp.inc"
#elif defined(TC_USE_DIRECTX)
#  include "directx/func1.cpp.inc"
#endif

And then simply reference these dummy files in CMake:

add_executable(foo src/func1.h src/func1.cpp)

Now building different configs will end up pulling in different code. Also if you go ahead and rename the files to end in .inc you can even reference them in add_executable() so that they show up in VS but VS won't try to build them directly.


if(CMAKE_BUILD_TYPE STREQUAL "Debug")
  add_definitions(/DYOURDEFINITION)
endif()

won't work within an MSVS multi-config solution context. For that you need

set(MY_DEFINITION 
    $<$<CONFIG:Debug>:definition_for_debug>
    $<$<CONFIG:RelWithDebInfo>:definition_for_rel_with_debug>
    $<$<CONFIG:Release>:definition_for_release> 
    $<$<CONFIG:MinSizeRel>:definition_for_tight_release>
    )

Need Your Help

Play framework - unit testing controllers with dependencies

java unit-testing playframework mocking playframework-2.1

I am in a process of writing web application that uses Play framework (2.1.1 version).

set onClickListener for spinner item?

android spinner listener

I have spinner which populates from database:

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.