<p>I was able to solve the <strong>#include</strong> issue by linking both the <strong>shaderc/glslc</strong> and <strong>shaderc/shaderc_util</strong> libraries and using file_includer.h and file_finder.h as suggested in a comment by ACskyline.</p>
<pre><code>  #include &lt;shaderc/glslc/src/file_includer.h&gt;
  #include &lt;shaderc/libshaderc_util/include/libshaderc_util/file_finder.h&gt;

  // [...]
  
  // somewhere before using the compiler
  shaderc_util::FileFinder fileFinder;
  options.SetIncluder(std::make_unique&lt;glslc::FileIncluder&gt;(&amp;fileFinder));
<span class="math-container">```</span>
</code></pre>

CC BY-SA 4.0
2021-05-26T20:20:22.027Z
2021-05-26T20:20:22.027Z
MadShadow
<p>It is <em>your</em> responsibility to support includes by instantiating an <a href="https://github.com/google/shaderc/blob/master/libshaderc/include/shaderc/shaderc.hpp#L182" rel="nofollow noreferrer"><code>IncluderInterface</code></a> instance and calling <a href="https://github.com/google/shaderc/blob/master/libshaderc/include/shaderc/shaderc.hpp#L199" rel="nofollow noreferrer"><code>SetIncluder(...)</code></a> on the <code>options</code> instance.  </p>

<p>The interface includer API consists of the following methods:</p>

<pre><code>// Handles shaderc_include_resolver_fn callbacks.
virtual shaderc_include_result* GetInclude(const char* requested_source,
                                           shaderc_include_type type,
                                           const char* requesting_source,
                                           size_t include_depth) = 0;

// Handles shaderc_include_result_release_fn callbacks.
virtual void ReleaseInclude(shaderc_include_result* data) = 0;
</code></pre>

<p>It will therefore also be your responsibility to implement these functions and interpret the <code>#include</code> directives from the GLSL into <code>shaderc_include_result</code> instances that will be used by shaderc to complete the preprocessing of the GLSL.</p>

CC BY-SA 4.0
2019-06-14T02:22:33.160Z
Thanks! Solved it with FileIncluder from shaderc/glslc/src/file_includer.h and shaderc/glslc/src/file_includer.cc
ACskyline
CC BY-SA 4.0
2021-05-05T01:55:47.743Z
@ACskyline did you have to do anything other than implementing the interface? Did you have to call something to trigger a preprocessor? I am trying to do this same thing but gslc is not replacing the include with the body of the included file.
Makogan
CC BY-SA 4.0
2019-06-13T17:00:01.503Z
2019-06-13T17:00:01.503Z
Jherico
<p>I'm using shaderc to compile glsl code in to spirv module and pass to pipelie in REAL-TIME. I want to use #include to reuse some of the shader code but shaderc is having problems recognizing it. Any one know how to solve this? (I'm NOT using command line to compile shader upfront.)</p>

<p>The error I got from shaderc is:</p>

<pre><code>standard.vert:6: error: '#include' : #error unexpected include directive for header name: GlobalInclude.glsl
</code></pre>

<p>Here are my shaders and client codes:</p>

<p>standard.vert</p>

<pre><code>#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_KHR_vulkan_glsl : enable
#extension GL_GOOGLE_include_directive : enable

#include "GlobalInclude.glsl"

layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inColor;
layout(location = 2) in vec2 inTexCoord;

layout(location = 0) out vec3 fragColor;
layout(location = 1) out vec2 fragTexCoord;

void main() {
  gl_Position = passUBO.proj * passUBO.view * objectUBO.model * vec4(inPosition, 1.0);
  fragColor = inColor;
  fragTexCoord = inTexCoord;
}
</code></pre>

<p>standard.frag</p>

<pre><code>#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_KHR_vulkan_glsl : enable
#extension GL_GOOGLE_include_directive : enable

#include "GlobalInclude.glsl"

layout(set = PASS_SET, binding = TEXTURE_SLOT(0)) uniform sampler2D texSamplerAlbedo;

layout(location = 0) in vec3 fragColor;
layout(location = 1) in vec2 fragTexCoord;

layout(location = 0) out vec4 outColor;

void main() {
  //outColor = vec4(fragTexCoord, 0.0, 1.0);
  outColor = texture(texSamplerAlbedo, fragTexCoord);
}
</code></pre>

<p>GlobalInclude.glsl</p>

<pre><code>#define FRAME_SET 0//per frame
#define SCENE_SET 1//per scene
#define PASS_SET 2//per pass
#define OBJECT_SET 3//per draw call

#define UNIFORM_BUFFER_BINDING_START 0
#define TEXTURE_BINDING_START 1

#define TEXTURE_SLOT(NUMBER) TEXTURE_BINDING_START + NUMBER

layout(set = SCENE_SET, binding = UNIFORM_BUFFER_BINDING_START + 0) uniform SceneUniformBufferObject {
  uint time;
} sceneUBO;

layout(set = PASS_SET, binding = UNIFORM_BUFFER_BINDING_START + 0) uniform PassUniformBufferObject {
  mat4 proj;
  mat4 view;
  uint passNum;
} passUBO;

layout(set = OBJECT_SET, binding = UNIFORM_BUFFER_BINDING_START + 0) uniform ObjectUniformBufferObject {
  mat4 model;
} objectUBO;

layout(set = FRAME_SET, binding = UNIFORM_BUFFER_BINDING_START + 0) uniform FrameUniformBufferObject {
  uint frameNum;
} frameUBO;
</code></pre>

<p>Compile shader using shaderc API:</p>

<pre><code>bool Shader::CreateShaderFromFile(shaderc_shader_kind kind, bool optimize)
{
  // read shader string
  if (!ReadShaderFromFile())
      return false;

  shaderc::Compiler compiler;
  shaderc::CompileOptions options;

  // like -DMY_DEFINE=1
  //options.AddMacroDefinition("MY_DEFINE", "1");
  if (optimize) options.SetOptimizationLevel(shaderc_optimization_level_size);

  std::cout &lt;&lt; "output 1:" &lt;&lt; shaderString &lt;&lt; std::endl;

  // preprocess
  shaderc::PreprocessedSourceCompilationResult preprocessed = compiler.PreprocessGlsl(shaderString, kind, fileName.c_str(), options);

  if (preprocessed.GetCompilationStatus() != shaderc_compilation_status_success) 
  {
      throw std::runtime_error(preprocessed.GetErrorMessage());
      return false;
  }

  shaderString = { preprocessed.cbegin(), preprocessed.cend() };

  std::cout &lt;&lt; "output 2:" &lt;&lt; shaderString &lt;&lt; std::endl;

  // compile
  shaderc::SpvCompilationResult module = compiler.CompileGlslToSpv(shaderString, kind, fileName.c_str(), options);

  if (module.GetCompilationStatus() != shaderc_compilation_status_success)
  {
      throw std::runtime_error(module.GetErrorMessage());
      return false;
  }

  shaderBytecode = { module.cbegin(), module.cend() };// not sure why sample code copy vector like this

  return true;
}
</code></pre>

<shader><vulkan>
shaderc compile through api with #include
ACskyline
# shaderc compile through api with #include

(Asked by: username_0 on 2019-06-13)

I'm using shaderc to compile glsl code in to spirv module and pass to pipelie in REAL-TIME. I want to use #include to reuse some of the shader code but shaderc is having problems recognizing it. Any one know how to solve this? (I'm NOT using command line to compile shader upfront.)

The error I got from shaderc is:

```
standard.vert:6: error: '#include' : #error unexpected include directive for header name: GlobalInclude.glsl

```

Here are my shaders and client codes:

standard.vert

```
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_KHR_vulkan_glsl : enable
#extension GL_GOOGLE_include_directive : enable

#include "GlobalInclude.glsl"

layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inColor;
layout(location = 2) in vec2 inTexCoord;

layout(location = 0) out vec3 fragColor;
layout(location = 1) out vec2 fragTexCoord;

void main() {
  gl_Position = passUBO.proj * passUBO.view * objectUBO.model * vec4(inPosition, 1.0);
  fragColor = inColor;
  fragTexCoord = inTexCoord;
}

```

standard.frag

```
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_KHR_vulkan_glsl : enable
#extension GL_GOOGLE_include_directive : enable

#include "GlobalInclude.glsl"

layout(set = PASS_SET, binding = TEXTURE_SLOT(0)) uniform sampler2D texSamplerAlbedo;

layout(location = 0) in vec3 fragColor;
layout(location = 1) in vec2 fragTexCoord;

layout(location = 0) out vec4 outColor;

void main() {
  //outColor = vec4(fragTexCoord, 0.0, 1.0);
  outColor = texture(texSamplerAlbedo, fragTexCoord);
}

```

GlobalInclude.glsl

```
#define FRAME_SET 0//per frame
#define SCENE_SET 1//per scene
#define PASS_SET 2//per pass
#define OBJECT_SET 3//per draw call

#define UNIFORM_BUFFER_BINDING_START 0
#define TEXTURE_BINDING_START 1

#define TEXTURE_SLOT(NUMBER) TEXTURE_BINDING_START + NUMBER

layout(set = SCENE_SET, binding = UNIFORM_BUFFER_BINDING_START + 0) uniform SceneUniformBufferObject {
  uint time;
} sceneUBO;

layout(set = PASS_SET, binding = UNIFORM_BUFFER_BINDING_START + 0) uniform PassUniformBufferObject {
  mat4 proj;
  mat4 view;
  uint passNum;
} passUBO;

layout(set = OBJECT_SET, binding = UNIFORM_BUFFER_BINDING_START + 0) uniform ObjectUniformBufferObject {
  mat4 model;
} objectUBO;

layout(set = FRAME_SET, binding = UNIFORM_BUFFER_BINDING_START + 0) uniform FrameUniformBufferObject {
  uint frameNum;
} frameUBO;

```

Compile shader using shaderc API:

```
bool Shader::CreateShaderFromFile(shaderc_shader_kind kind, bool optimize)
{
  // read shader string
  if (!ReadShaderFromFile())
      return false;

  shaderc::Compiler compiler;
  shaderc::CompileOptions options;

  // like -DMY_DEFINE=1
  //options.AddMacroDefinition("MY_DEFINE", "1");
  if (optimize) options.SetOptimizationLevel(shaderc_optimization_level_size);

  std::cout << "output 1:" << shaderString << std::endl;

  // preprocess
  shaderc::PreprocessedSourceCompilationResult preprocessed = compiler.PreprocessGlsl(shaderString, kind, fileName.c_str(), options);

  if (preprocessed.GetCompilationStatus() != shaderc_compilation_status_success) 
  {
      throw std::runtime_error(preprocessed.GetErrorMessage());
      return false;
  }

  shaderString = { preprocessed.cbegin(), preprocessed.cend() };

  std::cout << "output 2:" << shaderString << std::endl;

  // compile
  shaderc::SpvCompilationResult module = compiler.CompileGlslToSpv(shaderString, kind, fileName.c_str(), options);

  if (module.GetCompilationStatus() != shaderc_compilation_status_success)
  {
      throw std::runtime_error(module.GetErrorMessage());
      return false;
  }

  shaderBytecode = { module.cbegin(), module.cend() };// not sure why sample code copy vector like this

  return true;
}

```

**Tags:** shader, vulkan


---

## 2 answers

### Answer by username_2 on 2019-06-13. Score: 4 | Accepted answer

It is *your* responsibility to support includes by instantiating an [`IncluderInterface`](https://github.com/google/shaderc/blob/master/libshaderc/include/shaderc/shaderc.hpp#L182) instance and calling [`SetIncluder(...)`](https://github.com/google/shaderc/blob/master/libshaderc/include/shaderc/shaderc.hpp#L199) on the `options` instance.

The interface includer API consists of the following methods:

```
// Handles shaderc_include_resolver_fn callbacks.
virtual shaderc_include_result* GetInclude(const char* requested_source,
                                           shaderc_include_type type,
                                           const char* requesting_source,
                                           size_t include_depth) = 0;

// Handles shaderc_include_result_release_fn callbacks.
virtual void ReleaseInclude(shaderc_include_result* data) = 0;

```

It will therefore also be your responsibility to implement these functions and interpret the `#include` directives from the GLSL into `shaderc_include_result` instances that will be used by shaderc to complete the preprocessing of the GLSL.

> **Comments:**
> **username_0**: Thanks! Solved it with FileIncluder from shaderc/glslc/src/file_includer.h and shaderc/glslc/src/file_includer.cc  
> **username_3**: @username_0 did you have to do anything other than implementing the interface? Did you have to call something to trigger a preprocessor? I am trying to do this same thing but gslc is not replacing the include with the body of the included file.  

---

### Answer by username_1 on 2021-05-26. Score: 0

I was able to solve the **#include** issue by linking both the **shaderc/glslc** and **shaderc/shaderc\_util** libraries and using file\_includer.h and file\_finder.h as suggested in a comment by username_0.

```
  #include <shaderc/glslc/src/file_includer.h>
  #include <shaderc/libshaderc_util/include/libshaderc_util/file_finder.h>

  // [...]
  
  // somewhere before using the compiler
  shaderc_util::FileFinder fileFinder;
  options.SetIncluder(std::make_unique<glslc::FileIncluder>(&fileFinder));
```

```


---

