Repository: conan-io/conan-center-index

Issue:
[package] diligent-core/2.5.1: cannot include headers from Direct3D backends
### Package and Environment Details (include every applicable attribute)
  * Package Name/Version: **diligent-core/2.5.1**
  * Operating System+version: **Windows 10**
  * Compiler+version: **MSVC 19.29.30139.0 (Visual Studio 16 2019)**
  * Docker image: **N/A**
  * Conan version: **conan 1.46.0**
  * Python version: **Python 3.8.1**

### Conan profile (output of `conan profile show default` or `conan profile show <profile>` if custom profile is in use)
```
[settings]
os=Windows
os_build=Windows
arch=x86_64
arch_build=x86_64
compiler=Visual Studio
compiler.version=16
build_type=Release
[options]
[conf]
[build_requires]
[env]
```

### Steps to reproduce (Include if Applicable)
Use `diligent-core/2.5.1` as a requirement in a project. Include `EngineFactoryD3D11.h` in your C++ code because you want to use the D3D11 backend, as indicated by [Diligent's documentation](https://diligentgraphics.com/diligent-engine/using-the-api/#Win32). Compilation fails because the header cannot be found.

Same problem for the D3D12 backend.

### Logs (Include/Attach if Applicable)
```
fatal error C1083: Cannot open include file: 'EngineFactoryD3D11.h': No such file or directory
```



Discussion:
I've managed to fix this problem locally by adding these lines to the recipe's `package_info()`:
```
self.cpp_info.includedirs.append(os.path.join("include", "DiligentCore", "Graphics", "GraphicsEngineD3D11", "interface"))
self.cpp_info.includedirs.append(os.path.join("include", "DiligentCore", "Graphics", "GraphicsEngineD3D12", "interface"))
```
The problem was that the recipe was not exposing these paths as include paths for downstream consumers.


However, this led to a second problem:
I had to explicitly link against the Direct3D system libraries in my project.
Diligent does this for you in [its CMakeLists.txt](https://github.com/DiligentGraphics/DiligentCore/blob/v2.5.1/Graphics/GraphicsEngineD3D11/CMakeLists.txt#L124), but the conan recipe does not contain this info. I suspect that adding these to `self.cpp_info.system_libs` would solve it, but the problem is that diligent-core is a single library for all backends, so that's undesirable.

Perhaps the diligent-core recipe needs to be rewritten to use components, but I'm not sure about any backwards compatibility concerns. I'd appreciate expert advice on the library issue.
We should add it only for windows to self.cpp_info.system_libs
We are talking about     
dxgi.lib
d3d11/12.lib
d3dcompiler.lib
right?

I am not sure, what is the best way to link them. Maybe we should create system recipe similar to egl/system?
@ericLemanissier @SSE4 @uilianries @jgsogo @prince-chrismc 
I don't think system package is needed, `system_libs` should be enough. nowadays, these libs provided as a part of Windows SDK, and don't require to install DirectX SDK.
> We should add it only for windows to self.cpp_info.system_libs

But we don't want to add both D3D11 *and* D3D12, do we? That way any consumer will always try to link with both. This is what I wrote in my first comment, too. Also, even on Windows, someone might want to use the Vulkan or OpenGL backend instead.

Should this recipe be rewritten to use components so users can choose which backend they want to use and only link the relevant system libraries?  
> But we don't want to add both D3D11 _and_ D3D12, do we? That way any consumer will always try to link with both. This is what I wrote in my first comment, too. Also, even on Windows, someone might want to use the Vulkan or OpenGL backend instead.
> 
> Should this recipe be rewritten to use components so users can choose which backend they want to use and only link the relevant system libraries?

sorry, I have no idea how project is organized. there are several command approaches:

1. backends are mutually exclusive. in this case, it should provide an option to choose the backend. `system_libs` will link either to d3d11, or d3d12, but never both at the same time.
2. backends are plug-ins, and you can choose a one to link with. in this case, recipe should model components, and each of them will will have their own `system_libs`, one plug-in - d3d11, another plug-in - d3d12
3. backends can be linked together. in this case, rendering API is not chosen in build time, but at run-time. in that case, it's perfectly fine to link with both d3d11 and d3d12 in the same time. anyway, they provide different sets of symbols and don't collide.
From what I can see, Diligent-Core has a CMake target per backend, and then some supporting targets. Applications can choose which backend to link against.

IMO, modeling the recipe as components gives consumers the most freedom, including having a plugin architecture, which is pretty common for applications that want to target multiple graphics backends.

Resolving patch:
diff --git a/recipes/diligent-core/all/conanfile.py b/recipes/diligent-core/all/conanfile.py
--- a/recipes/diligent-core/all/conanfile.py
+++ b/recipes/diligent-core/all/conanfile.py
@@ -184,6 +184,8 @@ def package_info(self):
         self.cpp_info.includedirs.append(os.path.join("include", "DiligentCore", "Platforms", "Basic", "interface"))
         self.cpp_info.includedirs.append(os.path.join("include", "DiligentCore", "Platforms", "Linux", "interface"))
         self.cpp_info.includedirs.append(os.path.join("include", "DiligentCore", "Graphics", "GraphicsEngine", "interface"))
+        self.cpp_info.includedirs.append(os.path.join("include", "DiligentCore", "Graphics", "GraphicsEngineD3D11", "interface"))
+        self.cpp_info.includedirs.append(os.path.join("include", "DiligentCore", "Graphics", "GraphicsEngineD3D12", "interface"))
         self.cpp_info.includedirs.append(os.path.join("include", "DiligentCore", "Graphics", "GraphicsEngineVulkan", "interface"))
         self.cpp_info.includedirs.append(os.path.join("include", "DiligentCore", "Graphics", "GraphicsEngineOpenGL", "interface"))
         self.cpp_info.includedirs.append(os.path.join("include", "DiligentCore", "Graphics", "GraphicsAccessories", "interface"))


Test patch: