【问题标题】:CMake visual studio debug/release configCMake Visual Studio 调试/发布配置
【发布时间】:2012-01-10 06:04:13
【问题描述】:

我正在设置我的 Visual Studio 项目以使用 CMake,但我遇到了两个尚未解决的问题。

1 如何为 Release 设置一个预处理器定义,为 Debug 设置另一个定义?

2 我有一个带有 opengl 和 directx 的项目,因此对于 DebugOpenGL 和 ReleaseOpenGL,我想从 buld 中排除所有 directx cpp/h 文件。使用 DebugDirectX 和 ReleaseDirectx 排除 opengl 文件。我该如何设置?

编辑:

这是我得到的 1. 到目前为止:

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)

【问题讨论】:

    标签: c++ visual-studio configuration cmake


    【解决方案1】:
    1. 如何为 Release 设置一个预处理器定义,为 Debug 设置另一个定义?

    正确的方法是使用生成器表达式在正确的范围内设置 COMPILE_DEFINITIONS 属性。

    如果您想为所有目标添加定义,例如add_definitions(),请使用:

      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>
      )
    

    您还可以为 target 或特定的 source file 设置 COMPILE_DEFINITIONS。见set_property

    为了设置其他编译标志,您可以像上面一样在目录、目标或源文件上设置COMPILE_OPTIONS 属性。但是您也可以使用add_compile_options() 命令,因为与add_definitions() 不同,它支持生成器表达式。您也可以为目标设置COMPILE_OPTIONS,或使用target_compile_options()。对于源文件,从 CMake 3.3 开始,您仍然需要设置 COMPILE_FLAGS 属性。

      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}>"
      )
    

    请注意,将选项列表放入这些生成器表达式中需要 add_compile_options() 中的引号。

    1. 我有一个带有 opengl 和 directx 的项目,因此对于 DebugOpenGL 和 ReleaseOpenGL,我想从 buld 中排除所有 directx cpp/h 文件。使用 DebugDirectX 和 ReleaseDirectx 排除 opengl 文件。如何设置?

    这可能是个问题。尽管可以使用生成器表达式有条件地将源文件添加到目标,但我不知道有任何 IDE 支持按配置源文件。 Visual Studio 和 CMake 的 Visual Studio 生成器不支持它。 Xcode 和 Xcode 生成器也不支持这个。因此,如果您想使用 Visual Studio 或其他 IDE 进行构建,则不能这样做。

    一次使用单一配置的生成器,例如 makefile 或 ninja 生成器应该支持这一点。

    除了让源文件在配置之间有所不同之外,还有其他几个选项。这是一对。

    您可以有多个目标,并且它们之间的来源不同:

    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})
    

    请注意,这意味着您可以重新使用调试和发布配置,这也将简化您的其余配置。

    或者,您可以通过在源代码中使用一些间接来保留单独的 OpenGL 和 DirectX 配置。有一些“虚拟”cpp 文件和头文件在 #includeing 您的 opengl 文件或基于预处理器定义的 directx 文件之间切换:

    // 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
    

    然后在 CMake 中简单地引用这些虚拟文件:

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

    现在构建不同的配置最终会引入不同的代码。此外,如果您继续将文件重命名为以 .inc 结尾,您甚至可以在 add_executable() 中引用它们,以便它们显示在 VS 中,但 VS 不会尝试直接构建它们。

    【讨论】:

    • “虽然可以使用生成器表达式有条件地将源文件添加到目标,但我不知道有任何 IDE 支持按配置源文件。” Visual Studio 允许这样做,方法是在 标记上放置条件,或在项目条目本身下放置 元素(带有条件)。
    【解决方案2】:
    if(CMAKE_BUILD_TYPE STREQUAL "Debug")
      add_definitions(/DYOURDEFINITION)
    endif()
    

    在 MSVS 多配置解决方案上下文中不起作用。为此,您需要

    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>
        )
    

    【讨论】:

      【解决方案3】:

      1:

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

      2: 如果我理解正确,您需要创建一个选项变量

      option(USE_OPENGL "Use OpenGL or DirectX")
      

      然后在添加新目标时检查它:

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

      当然,你应该在 OpenGL/ 和 DirectX/ 目录中创建 CMakeLists.txt。

      【讨论】:

      • 虽然我没有不同子文件夹中的文件.. 我想要项目中的文件,但是对于 opengl 配置,我想排除 directx cpp/h 文件.. 和 directx 配置我想排除 opengl 文件。在 Visual Studio 中,您可以右键单击文件并从构建中选择排除 .. 1. 回答第一个问题,谢谢 :)
      • 没问题,只需将我的答案中的 add_subdirectory() 调用替换为 set(SOURCES Opengl1.cpp Opengl2.cpp etc)。在 else 分支做set(SOURCES DirectX1.cpp DirectX2.cpp etc)。最后,在 if 子句之外,通过将 ${SRCS} 传递给它来创建构建目标。
      • 很好的答案 arrowdodger... 只是一点点补充:如果您在 CMake 中将 set( SOURCES ) 与一些 if-else 子句一起使用,则“取消选择”的源文件将不会显示在 Visual Studio 中。
      • 另外一个补充:从命令行运行 cmake 时,CMAKE_BUILD_TYPE 未定义,因此检查 1) 可能会失败。也许更好的方法是使用 COMPILE_DEFINITIONS 属性,您可以在其中区分配置......虽然我必须承认它不是最优雅的解决方案
      • 我正在尝试使用 1. 现在.. 我正在使用 Windows 的 gui 版本构建.. 配置已设置,但配置没有预处理器定义集.. 我已经用我得到的东西编辑了最初的帖子
      猜你喜欢
      • 2016-12-14
      • 2017-01-09
      • 1970-01-01
      • 2014-03-21
      • 1970-01-01
      • 1970-01-01
      • 2011-03-09
      • 2011-06-04
      • 1970-01-01
      相关资源
      最近更新 更多