DirectX CMake 包括中断 Windows.h

DirectX CMake includes break Windows.h

当我尝试使用 CMake 将 DirectX SDK 目录包含到我的项目中时,windows.h 中的 header 文件在我尝试 #include 时抛出错误(否directx header 包含在前面)。

我用来 generate/compile 的命令:

cmake -S . -B build -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=Debug
cd build
nmake

CMakeLists.txt

cmake_minimum_required(VERSION 3.0)

project( NisPaper )

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
IF( EXISTS "${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json" )
   EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E copy_if_different
   ${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json
   ${CMAKE_CURRENT_SOURCE_DIR}/compile_commands.json
)
ENDIF()

ADD_LIBRARY(NisPaperLibs
    gdimanager.cpp
    gdirenderer.cpp
    d3dmanager.cpp
    winmanager.cpp
    d3drenderer.cpp
)

add_executable( NisPaper main.cpp )
target_link_libraries(NisPaper NisPaperLibs)

target_link_libraries(NisPaper gdiplus.lib)
target_link_libraries(NisPaper gdi32.lib)
target_link_libraries(NisPaper user32.lib)
target_link_libraries(NisPaper Dwmapi.lib)

find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
target_link_libraries( NisPaper ${OpenCV_LIBS} )

#This line causes the errors
include_directories("C:/Program Files (x86)/Microsoft DirectX SDK (March 2008)/Include")

错误:

C:\Program Files (x86)\Windows Kits\include.0.19041.0\um\objidlbase.h(6184): error C2061: syntax error: identifier '__RPC__out_xcount_part'
C:\Program Files (x86)\Windows Kits\include.0.19041.0\um\objidlbase.h(6188): error C2061: syntax error: identifier '__RPC__in_xcount_full'
C:\Program Files (x86)\Windows Kits\include.0.19041.0\um\objidlbase.h(6392): error C2061: syntax error: identifier '__RPC__out_xcount_part'
C:\Program Files (x86)\Windows Kits\include.0.19041.0\um\objidlbase.h(6396): error C2061: syntax error: identifier '__RPC__in_xcount_full'
C:\Program Files (x86)\Windows Kits\include.0.19041.0\um\objidlbase.h(6600): error C2061: syntax error: identifier '__RPC__out_xcount_part'
C:\Program Files (x86)\Windows Kits\include.0.19041.0\um\objidlbase.h(6604): error C2061: syntax error: identifier '__RPC__in_xcount_full'
C:\Program Files (x86)\Windows Kits\include.0.19041.0\um\objidl.h(14536): error C2061: syntax error: identifier '__RPC__inout_xcount'
C:\Program Files (x86)\Windows Kits\include.0.19041.0\um\objidl.h(14537): error C2061: syntax error: identifier '__RPC__in_xcount'
C:\Program Files (x86)\Windows Kits\include.0.19041.0\um\objidl.h(14541): error C2061: syntax error: identifier '__RPC__inout_xcount'
C:\Program Files (x86)\Windows Kits\include.0.19041.0\um\objidl.h(14542): error C2061: syntax error: identifier '__RPC__in_xcount'
C:\Program Files (x86)\Windows Kits\include.0.19041.0\um\objidl.h(14546): error C2061: syntax error: identifier '__RPC__inout_xcount'
C:\Program Files (x86)\Windows Kits\include.0.19041.0\um\objidl.h(14547): error C2061: syntax error: identifier '__RPC__in_xcount'
C:\Program Files (x86)\Windows Kits\include.0.19041.0\um\objidl.h(14551): error C2061: syntax error: identifier '__RPC__inout_xcount'
C:\Program Files (x86)\Windows Kits\include.0.19041.0\um\objidl.h(14552): error C2061: syntax error: identifier '__RPC__in_xcount'
C:\Program Files (x86)\Windows Kits\include.0.19041.0\um\objidl.h(14556): error C2061: syntax error: identifier '__RPC__inout_xcount'
C:\Program Files (x86)\Windows Kits\include.0.19041.0\um\objidl.h(14557): error C2061: syntax error: identifier '__RPC__in_xcount'

还有更多...

我认为会发生这种情况是因为 DirectX 在 and/or 优先于 windows header 之前加载它们时包含覆盖某些内容,所以我尝试将行替换为其中之一:

include_directories(BEFORE "C:/Program Files (x86)/Microsoft DirectX SDK (March 2008)/Include")
include_directories(AFTER "C:/Program Files (x86)/Microsoft DirectX SDK (March 2008)/Include")
include_directories(BEFORE SYSTEM "C:/Program Files (x86)/Microsoft DirectX SDK (March 2008)/Include")
include_directories(AFTER SYSTEM "C:/Program Files (x86)/Microsoft DirectX SDK (March 2008)/Include")

但没有任何改变。 我还尝试在一些 directX header 之后包含 windows.h,例如 d3d11.h d3dcompiler.h d3dcommon.h 等。希望它能做点什么,但正如预期的那样,没有任何改变。 我真的很感激一些帮助,因为我真的不知道我应该如何解决这个问题...

问题是旧版 DirectX SDK 包含许多过时的 header,并且与 Windows SDK 冲突。在这种情况下,当您包含 Windows.h 时,它来自 Windows SDK,但是当 header 寻找 rcpsal.h 时,它从遗留的 DirectX SDK 中提取了古老的副本.

Header/library 如果您将 DXSDK 放在 ,包含顺序会有所帮助,但更好的解决方案是 (a) 根本不使用旧版 DirectX SDK每 this blog post, or (b) if you must use it, trim down per this blog post.

另见 Where is the DirectX SDK (2021 Edition)?

The VCPkg version of the directxsdk port supports the 'trimmed-down' version. See this PR.