使用CMake和MinGW查找DirectX12库

问题描述

我正在尝试使用CMake查找DirectX 12并将其链接到可执行文件。到目前为止,我在使用MSVC进行编译时可以正常工作,但是在使用GCC进行编译时却失败了: Could NOT find D3D12 (missing: D3D12_LIBRARIES)

我使用的FindD3D12.cmake的版本略有改变:

# Find the win10 SDK path.
if ("$ENV{WIN10_SDK_PATH}$ENV{WIN10_SDK_VERSION}" STREQUAL "" )
        get_filename_component(WIN10_SDK_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0;InstallationFolder]" ABSOLUTE CACHE)
        get_filename_component(TEMP_WIN10_SDK_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0;ProductVersion]" ABSOLUTE CACHE)
        get_filename_component(WIN10_SDK_VERSION ${TEMP_WIN10_SDK_VERSION} NAME)
elseif(TRUE)
        set (WIN10_SDK_PATH $ENV{WIN10_SDK_PATH})
        set (WIN10_SDK_VERSION $ENV{WIN10_SDK_VERSION})
endif ("$ENV{WIN10_SDK_PATH}$ENV{WIN10_SDK_VERSION}" STREQUAL "" )

# WIN10_SDK_PATH will be something like C:\Program Files (x86)\Windows Kits\10
# WIN10_SDK_VERSION will be something like 10.0.14393 or 10.0.14393.0; we need the
# one that matches the directory name.

if (IS_DIRECTORY "${WIN10_SDK_PATH}/Include/${WIN10_SDK_VERSION}.0")
        set(WIN10_SDK_VERSION "${WIN10_SDK_VERSION}.0")
endif (IS_DIRECTORY "${WIN10_SDK_PATH}/Include/${WIN10_SDK_VERSION}.0")


# Find the d3d12 and dxgi include path,it will typically look something like this.
# C:\Program Files (x86)\Windows Kits\10\Include\10.0.10586.0\um\d3d12.h
# C:\Program Files (x86)\Windows Kits\10\Include\10.0.10586.0\shared\dxgi1_4.h
find_path(
        D3D12_INCLUDE_DIR    # Set variable D3D12_INCLUDE_DIR
        d3d12.h              # Find a path with d3d12.h
        HINTS "${WIN10_SDK_PATH}/Include/${WIN10_SDK_VERSION}/um"
        DOC "path to WIN10 SDK header files"
        HINTS
)

find_path(
        dxgi_INCLUDE_DIR    # Set variable dxgi_INCLUDE_DIR
        dxgi1_4.h           # Find a path with dxgi1_4.h
        HINTS "${WIN10_SDK_PATH}/Include/${WIN10_SDK_VERSION}/shared"
        DOC "path to WIN10 SDK header files"
        HINTS
)
set(D3D12_INCLUDE_Dirs ${D3D12_INCLUDE_DIR} ${dxgi_INCLUDE_DIR})

# Find D3D libraries
set(D3D12_LIB_NAMES d3d12.lib dxgi.lib d3dcompiler.lib dxguid.lib)

set(D3D12_LIBRARIES)
foreach (D3D12_LIB_NAME ${D3D12_LIB_NAMES})
        find_library(${D3D12_LIB_NAME}_LOC NAMES ${D3D12_LIB_NAME} HINTS ${D3D12_HINTS_PATH})
        set(D3D12_LIBRARIES ${D3D12_LIBRARIES} ${${D3D12_LIB_NAME}_LOC})
endforeach(D3D12_LIB_NAME)

include(FindPackageHandleStandardArgs)
# handle the QUIETLY and required arguments and set D3D12_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(
        D3D12  DEFAULT_MSG
        D3D12_INCLUDE_Dirs D3D12_LIBRARIES
)

mark_as_advanced(D3D12_INCLUDE_Dirs D3D12_LIBRARIES)

然后将其链接为:target_link_libraries(<name> ${D3D12_LIBRARIES})

D3D12_INCLUDE_Dirs变量设置为正确的值,问题仅出在库上。

DirectX 12库与GCC和CMake不兼容是否足够聪明以至于可以解决这一问题,还是在尝试查找它们时我做错了什么?

编辑:

作为答案,不需要FindD3D12.cmake模块。在Windows上编译时,DirectX库是系统库,因此可以执行target_link_libraries(<name> PRIVATE d3d12.lib dxgi.lib d3dcompiler.lib dxguid.lib)

解决方法

DirectX 12库是否与GCC不兼容

每个编译器都有自己的库格式,cl使用.lib库,而gcc使用.a.so库。您不能只使用cl的库(Windows SDK中存储的库)并将它们提供给gcc。

,

================================================ =======

Windows:

DirectX是Windows SDK的一部分。

如果您正在Windows上进行编译,则无法使用SDK进行编译。因此,不必担心处理include目录和其他内容。

因此,您可以将Directx库视为常规系统库,并且以下命令将起作用。这就是cmake的魔力。

因此,您的大部分cmake并不是必需的。至少如果您使用Visual Studio。 如果您不使用Visual Studio,则可能需要编写工具链(https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html?highlight=cmake_cxx_compiler_id#cmake-toolchains-7

# DX12 libraries
target_link_libraries(foobar PRIVATE
    d3d12.lib
    dxgi.lib
    dxguid.lib
)

================================================ =======

Linux:

第二,DirectX12将具有Linux支持: https://devblogs.microsoft.com/directx/directx-heart-linux/

但是,我认为它不允许使用图形功能,而只能使用计算功能。但是,不管假设微软没有让它变得非常痛苦,cmake都应该大致相似。

================================================ =======

最后,如果您想知道要针对哪个版本的SDK进行检验,请查看CMAKE_SYSTEM_VERSION

在Windows上,在第一个项目调用之前对此进行设置可设置SDK版本。因为这就是SDK版本的意思。 Windows版本的版本。

也要格外小心,在代码库中添加额外的static_asserts,以确保您使用的SDK版本想要包含“ Windows.h”,而您可能已经拥有了该版本。然后检查是否有编译器定义,这些定义可以告诉您正在编译的Windows OS版本。

”使用Windows SDK时,可以指定代码可以在哪些版本的Windows上运行。预处理程序宏WINVER和_WIN32_WINNT指定代码支持的最低操作系统版本。VisualStudio和Microsoft C ++编译器支持针对Windows的版本7 SP1和更高版本。较旧的工具集包括对Windows XP SP2,Windows Server 2003 SP1,Vista和Windows Server 2008的支持。不支持Windows 95,Windows 98,Windows ME,Windows NT和Windows 2000。 -Microsoft文档(https://docs.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt?view=msvc-160

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...