I recently wanted to add D3D12 support for my hobby rendering engine project "Arkose", which has pretty much just been running on Vulkan up until this point. Besides the fun challenge of adding another rendering backend, I was faced with the less fun challenge of getting things building & linking nicely in my CMake-based build system. I won't go into the full story here but I figured the end result might be useful for other taking this path.
First, before you make it more complex than it needs to be, note that DirectX 12 and DirectXShaderCompiler are now both included in the Windows SDK, so you might not need the Agility SDK. However, the Windows SDK release will not include all the latest features, so if you want that then the Agility SDK would be for you. You can read this official page for more info. If you are fine with using a basic D3D12 feature level and Shader Model 5.0 (and you're on a reasonably recent version of Windows 10 or 11), then all you need to do is link against the libraries, and everything should just work: target_link_libraries(YOUR_TARGET d3d12 dxgi dxguid dxc)
I like to keep my repositories clean of both 3rd-party code and libraries/binaries. Most of my dependencies are hosted as source in GitHub, where I can use CMake's FetchContent to download and build these dependencies locally, in-tree. I do this for all my dependencies, except for the Vulkan SDK which I simply ask the user to have installed on their PC. When it comes to the Agility SDK, however, there's no source available to build and there's no convenient installer. There's mostly just the NuGet package and some vague instructions. I've never used NuGet before and I'm already using FetchContent a lot, so I figured there was a way to use the former with the latter. Here's my solution:
Suprisingly, FetchContent seems to understand that a NuGet package is simply a zip-file with a weird extension and unpacks it for you. I couldn't find this documented anywhere, but hey, it works! Most details here don't matter too much, but you do want to make sure to expose AGILITYSDK_VERSION_MAJOR, AGILITYSDK_D3D12CORE_DLL, and AGILITYSDK_D3D12SDKLAYERS_DLL, as they are needed for your target. Below you can see how I integrate it with my target (ArkoseRenderer):
The reason I set ARKOSE_AGILITY_SDK_VERSION as a compile definition is to I can use the "__declspec(dllexport) keyword" method to specify the Agility SDK version for my project. This way I only need to change the version in the CMake file to upgrade, which I like.
You still have to link against d3d12 (remember that Windows handles the DLL redirection for you) and the other libraries, but make sure you also include agilitysdk to get use the correct headers. Here's what I do:
If you're using the Agility SDK you likely also want to use a recent version of the DirectXShaderCompiler (DXC), which is officially hosted on GitHub. While it's technically possible to build it yourself with add_subproject, it's a pretty big project to build with a somewhat complex build setup and dependencies of its own, so in this case I opted for prebuild binaries. Fortunately, they are provided as GitHub releases, which are easy to use with CMake. Simply copy the link of the release zip-file you're interested in, e.g. dxc_2024_03_22.zip, to get a permalink source. From there it's pretty easy:
As we set up DXC as an "imported library" we can now just call target_link_libraries(YOUR_TARGET dxc) and don't have to worry about manually copying its DLLs around. However, you do still have to tell CMake to copy any runtime DLLs to the executable location. If you don't already have that set up for your project you can simply add something like this:
That should be all! None of this is very hard to figure out on your own, but there's a lot of annoying build system details to get right. I sure didn't enjoy the process of figuring it all out, so by sharing it I can hopefully make it easier for the next person.
If you have any questions or things aren't working, just send me a message on Twitter/X and I'd be happy to help!
Follow @SimonMoos