shaderc icon indicating copy to clipboard operation
shaderc copied to clipboard

Sanitize build system for packagers

Open ubitux opened this issue 2 years ago • 2 comments

The current build system is unusable for any packager because of the hard ties with its third parties.

The work of the packager is usually to build separate controlled packages for every unit. In the case of shaderc, there will be a package for spirv-headers, a package for spirv-tools, and a package for glslang. All of them will deploy all the necessary libs and headers in the appropriate prefix.

To build shaderc on top of that, I had to hack the build system. Here is a draft:

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0c8d1ae..f9fbf53 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -110,9 +110,13 @@ if(MSVC)
 endif(MSVC)


+option(SHADERC_ENABLE_THIRD_PARTY "Pull third party dependencies" ON)
+
+if (SHADERC_ENABLE_THIRD_PARTY)
 # Configure subdirectories.
 # We depend on these for later projects, so they should come first.
 add_subdirectory(third_party)
+endif()

 add_subdirectory(libshaderc_util)
 add_subdirectory(libshaderc)
@@ -121,11 +125,19 @@ if(${SHADERC_ENABLE_EXAMPLES})
     add_subdirectory(examples)
 endif()

+if (SHADERC_ENABLE_THIRD_PARTY)
 add_custom_target(build-version
   ${PYTHON_EXECUTABLE}
   ${CMAKE_CURRENT_SOURCE_DIR}/utils/update_build_version.py
   ${shaderc_SOURCE_DIR} ${spirv-tools_SOURCE_DIR} ${glslang_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/build-version.inc
   COMMENT "Update build-version.inc in the Shaderc build directory (if necessary).")
+else()
+  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/build-version.inc
+    "\"shaderc TODO\\n\"\n"
+    "\"spirv-tools TODO\\n\"\n"
+    "\"glslang TODO\\n\"\n"
+  )
+endif()

 function(define_pkg_config_file NAME LIBS)
   add_custom_target(${NAME}-pkg-config ALL
diff --git a/glslc/CMakeLists.txt b/glslc/CMakeLists.txt
index 31664d1..bcd7cb6 100644
--- a/glslc/CMakeLists.txt
+++ b/glslc/CMakeLists.txt
@@ -53,7 +53,9 @@ shaderc_default_compile_options(glslc_exe)
 target_include_directories(glslc_exe PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/.. ${spirv-tools_SOURCE_DIR}/include)
 set_target_properties(glslc_exe PROPERTIES OUTPUT_NAME glslc)
 target_link_libraries(glslc_exe PRIVATE glslc shaderc_util shaderc)
+if (SHADERC_ENABLE_THIRD_PARTY)
 add_dependencies(glslc_exe build-version)
+endif()

 shaderc_add_tests(
   TEST_PREFIX glslc
diff --git a/libshaderc_util/src/compiler.cc b/libshaderc_util/src/compiler.cc
index 8a8d12b..92d8279 100644
--- a/libshaderc_util/src/compiler.cc
+++ b/libshaderc_util/src/compiler.cc
@@ -20,7 +20,7 @@
 #include <thread>
 #include <tuple>

-#include "SPIRV/GlslangToSpv.h"
+#include "glslang/SPIRV/GlslangToSpv.h"
 #include "libshaderc_util/format.h"
 #include "libshaderc_util/io_shaderc.h"
 #include "libshaderc_util/message.h"

Of course, this has several caveats as is:

  • There is no detection of the presence of these dependencies, which means it breaks at compilation instead of configure if you haven't manually set glslang_SOURCE_DIR and spirv-tools_SOURCE_DIR to the appropriate include path, and likewise the link library is missing. Usually, you want to use find_library(), but given how messy the Khronos dependencies are deployed, this might be a challenge. Of course, there is also the hope that these dependencies end up deploying a .pc (pkg-config) containing version, link libraries, include paths, etc, which would solve all of this.
  • The versions are not extracted (pkg-config would help here again) for build-version.inc, but they are only used for a help print, so I skipped them for now
  • The glslang include breaks the third party code path, but this is the appropriate path if glslang is installed.

I don't know how we can proceed from here, but the current state really is terrible.

ubitux avatar Aug 13 '21 23:08 ubitux

Agreed, I'm back to building shaderc after a long while, and it's a nightmare. There's too many options & dependencies, but well the largest problem is really that the KhronosGroup dependencies is a spider web of dependencies & poor design.

Sairony avatar Sep 10 '21 12:09 Sairony

The cause of the complexity is that Shaderc is built in various configurations:

  • sometimes everything is built from source, not from installs.
  • sometimes dependencies are in shaderc's third_party, and sometimes everything is in peer directories under a higher-level project's third_party

Also, the directory structure of various dependencies have changed over time, and the current setup "works".

You're correct, the support for pkg-config has been spotty and inconsistent.

Changes to improve things would have to ensure at least the following downstream projects do not break in the meantime:

  • LunarG's Vulkan SDK
  • Android NDK

dneto0 avatar Oct 13 '21 22:10 dneto0