vsg-dev / VulkanSceneGraph

Vulkan & C++17 based Scene Graph Project
http://www.vulkanscenegraph.org
MIT License
1.32k stars 212 forks source link

Inability to compile vsg with gslang support in build environments without network access #1035

Closed psi29a closed 4 months ago

psi29a commented 11 months ago

Describe the bug glslang support in vsg seems tied to a specific fork of glslang (upstream + patches). This is problematic for several reasons:

Expected behavior

vsg should be making use of the system glslang, and if not available but still required, then the project should make use of cmake's FetchContent: https://cmake.org/cmake/help/latest/module/FetchContent.html FetchContent is more secure as it also requires a hash of the release or commit version you wish to download to limit supply-chain attacks.

Additional context How necessary are the patches to glslang and why are they needed? It is possible to use FetchContent to apply patches so there is no need to fork.

Being able to package vsg with glslang support Debian and Ubuntu is currently blocked.

Building projects, like vsgopenmw, using flatpak are also blocked as they also do not have network access while in the build environment.

robertosfield commented 11 months ago

The integrated of glslang with patches in the way I've done it is essentially the best of bad bunch of possible solutions. FetchContent has it's own problems, depending on 3rd party sources for glslang also introduced a range of problems due the inconsistent way glslang version has been done historically.

The patches that I applied to glslang were all warning fixes as gslang itself is built with such lax warnings when built as part of the VSG it generates hundreds of warnings making it impossible to spot any within the VSG itself. My plan has to be upstream these warnings fixes but glslang process for submissions meant I couldn't quickly jump through the hoops to get a submission - I have remained so busy since I was forced to make these fixes that I haven't had a chance to follow up.

I don't know if glslang version available by package managers has improved since I was forced to move the build of glsalng into the core VSG itself, so there is chance things have improved, but there is good chance that it's still a complete dogs dinner and trying to rely upon it would cause far more "BUGS" that it fixes.

In my ideal world an alternative to glslang would magically appear that doesn't have all the problems that it introduces. Happy to take suggestions, but all those chip in suggestions need to be aware that we've tried lots of different approach and there are failures that happen on different build combinations, what works for one set of users breaks for another. We have to find a solution that works for more users without over-burdening myself and others with an endless tasks of wake-a-mole of problems that one dependency introduces.

psi29a commented 11 months ago

Could we instead use FetchContent, apply your patches (so you can still maintain them as needed and target a specific release of gslang), and then build? This seems to me more manageable solution then maintain a fork? :)

AnyOldName3 commented 11 months ago

All the things people have told me are bad about FetchContent before (many of which are optional, e.g. if you're concerned about the network access, there's a command-line argument to tell CMake where you've already fetched it to) are the same or worse with the approach taken. I also suspect some/all of the patches could be dropped if ExternalProject was used instead of FetchContent as it does everything within its own scope, so it's more similar to dealing with a precompiled system library.

robertosfield commented 11 months ago

I don't recall off the top of my head why FetchContent failed, I tried it and it had it's own suit of problems that forced me to opt for doing a "roll your own" equivalent of FetchContent to fix the problems.

The solution I've ended up was the result of trying all the standard approaches to working with glslang, every single approach broke for different sets of users, I could never get it working for all users.

A big part of why this is a mess is glslang itself. glslang is evolving so there is chance that they've begun moving towards support use as library better and fixing the CMake side so it integrates with repo's and building in different ways that users need. I don't have the time right now to dive into the glslang quagmire as I know it could well suck days of work and only end up fixing build for some users but breaking it for others.

I say this because I've gone round and round over this way too many times since the inception of the VSG 5 years ago. It's been a horrible experience needing glslang to compile shaders to SPIRV.

As a general note, I consider the VSG developing too fast to be distributed as a stable part of 3rd party repositories. There will come a point in the future that the VSG feature set is mature enough that a high % of users can make do with the older versions available in 3rd party repositories, but we aren't there yet.

For now I'd recommend that projects build the VSG themselves, picking either the latest release or master.. We've put effort into make the VSG play nicely with cmake so you can use it as a submodule, via FetchContent or ExternalProject, this route insulates projects from being dependent on how quickly 3rd party repositories start support software.

psi29a commented 11 months ago

Would you mind if I took it for a spin? I've already invested a bit of time trying to get things working, with my own fork of your fork. :)

As I said, providing a generic linux build, like flatpak, prevents network use while building. So even projects who use VSG are running into problems, which was why I raised the issue in the first place. :)

robertosfield commented 11 months ago

You are welcome to play.

Getting things to work on one system may well produce different results than once you start trying all the different combinations that end users have - this is where I came a cropper many times - trying something that worked well on all the systems I had to had, but then checked it then different users report problems, then you iterate.

So... I am concerned that you could spend time reinventing the same problems that I've come across, but just not knowing problems exist until it gets widely tested. I don't have time to help out with going around this merry-go-round at this point.

If the glslang team have changed things for the better, then that's really the best time to try things out afresh. So rather fork and fork, I'd see if there is value in going back to glslang main branch to see if they've improved their cmake config support and versioning. Ideally I'd like to have glslang solve all the problems associated with using it so we can simplify our end.

robertosfield commented 11 months ago

Looking that glslang github repo: https://github.com/KhronosGroup/glslang

First item on the NEWS list is:

  1. C++17 (all platforms) and Visual Studio 2019 (Windows) are now required. This change was driven by the external dependency on SPIRV-Tools.

To compile without pulling in SPIRV-Tools I had to add -DENABLE_OPT=0 on the cmake line, so this worked:

~/3rdParty/glslang/build$ cmake .. -DCMAKE_INSTALL_PREFIX=~/ExperimentalInstall -DENABLE_OPT=0

It then builds and installs OK. I haven't tried against the VSG, but such changes investigating what has changed. These changes will take a while before they feed through to the main 3rd repos, but it looks like the VulkanSDK will be tracking these changes more rapidly.

Perhaps we could set a requirement this modern glslang version, but this would mean that 3rd repos will be the sticking point, but they are anyway as they have older and problematic versions of glslang.

robertosfield commented 11 months ago

This morning I got a notifaction from a thread on glslang Issue I posted to about the broken cmake config support:

The Issue: https://github.com/KhronosGroup/glslang/issues/2570#issuecomment-1830897326

The PR that hey suggest fixes it: https://github.com/KhronosGroup/glslang/pull/2989

However, the date on the PR is August 2022 so pre-dates when I had to abandon pulling in glslang via find_package. However, the PR might not made it upstream at the point I was doing the last round of attempts to fix the glslang dependency.

It may be worth trying find_package once more and specifying a recent glslang version, We'd need to figure out what is the minimum.

psi29a commented 11 months ago

I have tested find_package on macos and linux without issue.

Then perhaps this is enough?

If not found, should we fall back to your git solution for the time being and leave the fetch_content for another PR? That would at least get a few issues unstuck.

robertosfield commented 11 months ago

The challenge is that historically the some systems may or may not have find_package, the cmake config files not installed, or they would be installed and broken - this means just testing a couple of platform combinations doesn't mean it's works reliably everywhere.

Do you know what the sitation with the VulkanSDK on Windows now? The VulaknSDK on non Windows systems was installed the cmake config support for glslang but the Windows version of the SDK wasn't install any cmake config support. Perhaps the Windows VulkanSDK has now been fixed, if so we'll need to find a way of checking the VulkanSDK version.

This is just a small snapshot of the issues I've struggled with glsang since the inception of the VSG project.

AnyOldName3 commented 11 months ago

I can give it a spin on Windows if someone sends me a link to a branch.

AnyOldName3 commented 11 months ago

Without needing to try anything, though, I can see that the Vulkan SDK for Windows does include glslang libraries and headers, but no CMake config to go with them (or for anything else it includes by default, either). Looking at their issue tracker, it's never even been reported as a problem, so it's not a surprise that they've not done anything to fix it. I've opened https://vulkan.lunarg.com/issue/view/656df8aa5df1125b58afb491 to remedy that.

AnyOldName3 commented 10 months ago

I got an email last night saying they'd resolved that, and the next version of the Windows Vulkan SDK will include the CMake config files. That means simply using find_package(glslang CONFIG) will work on all platforms when that releases, provided we're okay either bumping the minimum required Vulkan SDK version on Windows, or telling Windows developers they'll need to build glslang themselves and add it to their CMake prefix path if they want to use an older version.

robertosfield commented 10 months ago

Thanks for following that up Chris. Once the next VulkanSDK is out we can create a branch of the VSG and start experimenting with pulling in glslang from external sources again.

There may be dragons lying quietly to be awoken once we start testing this out across all platforms but hopefully this time around glslang will be more stable base to build against and we can finally get rid of the internal glslang for the next stable release which will be v1.2.0. I don't have a time frame for this release as it'll depend upon how glslang as well as many other items converge.

AnyOldName3 commented 10 months ago

Disappointingly, I've discovered that find_pacakge(glslang CONFIG) won't work yet in the MinGW UCRT64 environment provided by MSYS2 (and therefore probably any other MSYS2-provided environment) as the glslang version predates this MR https://github.com/KhronosGroup/glslang/pull/3420, which is needed to use the glslang::SPIRV target that provides <SPIRV/GlslangToSpv.h>. I suspect the same problem exists on Arch Linux, as that uses the same version, and if Arch's version of something is too old, it's usually a sign that every other distro's going to have the same problem.

This is a particular problem for MSYS2-provided MinGW UCRT64 as the version of glslang that the VSG currently fetches predates https://github.com/KhronosGroup/glslang/pull/3144, so that doesn't build, either.

I think that everything would be fine if we did find_package(glslang 14 CONFIG), and then, if after that glslang_FOUND was still unset, fell back to fetching a recent upstream glslang commit (whether via FetchContent or something resembling the existing approach). I don't think the fork's necessary anymore. It at least worked when I set it up that way under MSYS2's MinGW UCRT64 environment.

robertosfield commented 10 months ago

Perhaps it would be worth creating a spreadsheet/table with OS/build tool combinations and the glslang version that comes with them, and if it's possible to find out when it'll be upgrade to the required glslang version if it isn't already modern often.

Perhaps requiring users use a modern VulkanSDK for OS/build tool combination when their OS/build tool doesn't out of the box have a modern enough version,

robertosfield commented 8 months ago

@psi29a & @AnyOldName3

I had just occurred to me that another approach for glslang support would be to dynamic load glslang.so at runtime when it's required and then import the symbols we use. This would avoid the need for compiling against glslang. I am also wondering if we could do this for Xcb and Wayland support as well.

AnyOldName3 commented 8 months ago

You might have seen that I've submitted a slew of PRs to glslang, and as well as that, I've got a branch locally where glslang is grabbed via find_package that should work everywhere that has glslang 14 available. I did this because I was trying a build via MSYS2, which has GCC 13.x, and the glslang version the VSG uses at the moment can't be built with that version. Unfortunately, glslang 14 isn't available everywhere yet (in fact, it's really just Windows where you can expect it - the first Vulkan SDK build that included the glslang CMake config had glslang 14, and MSYS2 provides glslang 14, but on the Unix end, not even Arch is on glslang 14 yet). To that end, I made a CMake option to specify an older version (most of the issues were fixed by glslang 13, so on lots of platforms, that should be fine), but I also tried making it so that we could use a nested build of upstream glslang as a fallback. Obviously, glslang 14 had already released by the time I started this, so it wouldn't be exactly the same version as find_package was looking for, but it should be basically the same as it's only a few weeks worth of difference.

The problems I hit with upstream glslang were:

robertosfield commented 5 months ago

@psi29a as a heads up I have created an external_glslang branch of the VSG to see if it's now possible to rely upon 3rd party glslang libs. I've written up this work on discussion thread #1199. I'm hopeful one of the benefits of linking to an external glslang we'll be able to build without network access.

This something that will need to be tested across platform of course but my hope is that the extenral_glslang can be made to work well across platforms and be part of the up coming VulkanSceneGrasph-1.2 stable release.

robertosfield commented 4 months ago

I'm closing this Issue as I believe the change to using an external glslang should resolve the problems with compiling without network access.

psi29a commented 4 months ago

Brilliant, thanks :)