build: Fix compilation and runtime errors with LLVM 22#2124
Merged
Conversation
This commit fixes compilation and runtime errors of the OSL against specific builds of LLVM 22. When LLVM is compiled with LLVM_LINK_LLVM_DYLIB=OFF (default value) an extra set of libraries needs to be used for Clang: - The clangOptions library is needed because getDriverOptTable() used from clangFrontend was moved from clangDriver to clangOptions. - Similarly, printStats() used from clangSema has been moved to clangAnalysisLifetimeSafety. This linking error could be reproduced when LLVM is compiled with the following options: ``` cmake \ -GNinja \ -DCMAKE_BUILD_TYPE=Release \ -DLLVM_INCLUDE_TESTS=OFF \ -DLLVM_INCLUDE_EXAMPLES=OFF \ -DLLVM_BUILD_LLVM_C_DYLIB=OFF \ -DLLVM_ENABLE_UNWIND_TABLES=OFF \ -DLLVM_ENABLE_ZSTD=OFF \ -DLLVM_ENABLE_ZLIB=OFF \ -DLLVM_ENABLE_PROJECTS=clang \ -DCMAKE_INSTALL_PREFIX=/opt/local/llvm/22.1.7 \ ../llvm ``` A couple of notes: - The linking issue can not be reproduced when using Homebrew's LLVM 22 because it uses LLVM_LINK_LLVM_DYLIB=ON. This seems to be leading to a situation when the linker issue is side-steps because of the symbols that are pulled by the dynamic LLVM library. - Passing LLVM_STATIC does not help with this case, since this flag only affects the way LLVM libraries are handled and does not change the way Clang libraries are handled: `llvm-config --libfiles --link-static` does not print any Clang-related libraries. Since LLVM version 22 the VFS is to be explicitly created for the CompilerInstance. Prior to version 22 this was done implicitly by the LLVM when calling createFileManager(), but now this is no longer the case, and LLVM has an assertion for it. The createVirtualFileSystem() with default arguments solves this problem, and initializes CompilerInstance's VFS the same way how it was done implicitly in the older versions of LLVM. Without this, compilation of OSO triggers an assert() in LLVM: ``` Assertion failed: (VFS && "CompilerInstance needs a VFS for creating FileManager"), function createFileManager, file CompilerInstance.cpp, line 387. ``` It is unclear whether this was causing any actual issue with release builds of LLVM, but it is better to use the API in the way it is expected to be used and create the VFS. Last but not least, this change also fixes the following assert on the LLVM side when running OSL's test suite on macOS: ``` Assertion failed: ((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) && "Invalid size"), function emitIntValue, file MCStreamer.cpp, line 135. ``` The value that trips on this assert statement comes from the DW_AT_APPLE_major_runtime_vers that the code in DwarfDebug.cpp, and it comes from the RuntimeVersion (RV) argument of the createCompileUnit(). This runtime value is supposed to indicate Obj-C runtime version which is either 1 or 2 (value 2 is for Objective-C 2.0). Passing OSL version as the runtime version does not fit single byte, and that is why the assertion trips. This change follows Clang's code which sets the runtime version to 0 for non-Objective-C languages. It is unclear what side-effects this change could bring, but it is also a bit strange to use OSL version for things that distinguish system runtime. In order to be able to run OSL regression tests with LLVM compiled in debug mode, LLVM_LINK_LLVM_DYLIB=ON had to be used. Without this, the following assert in the LLVM triggers upon testrender startup: ``` : CommandLine Error: Option 'openmp-ir-builder-optimistic-attributes' registered more than once! LLVM ERROR: inconsistency in registered CommandLine options ``` This is to do with the way how LLVM registers command line arguments. It uses static variable initialization for this, and having LLVM as a static library that is pulled via CLang into both oslcomp and oslexec that are then pulled into testrender causes this situation to happen. For some reason, it does not happen if LLVM is compiled as static but release library. The need of debug versions of OSL and LLVM libraries comes from the need to compile Blender on Windows in Debug mode, and libraries need to be compiled with a different CRT ABI. Tested with the ctest with both LLVM 20 and 22 compiled in release. With all these changes the test suite passes to the same degree for LLVM 20 and 22, both Debug and Release. The only failing tests are related to Python module, and those I did not yet manage to get passing on a local development machine. Signed-off-by: Sergey Sharybin <sergey@blender.org>
lgritz
approved these changes
Jun 5, 2026
Collaborator
lgritz
left a comment
There was a problem hiding this comment.
LGTM, thanks for the deep dive in tracking this down and explaining it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This commit fixes compilation and runtime errors of the OSL against specific builds of LLVM 22.
When LLVM is compiled with LLVM_LINK_LLVM_DYLIB=OFF (default value) an extra set of libraries needs to be used for Clang:
The clangOptions library is needed because getDriverOptTable() used from clangFrontend was moved from clangDriver to clangOptions.
Similarly, printStats() used from clangSema has been moved to clangAnalysisLifetimeSafety.
This linking error could be reproduced when LLVM is compiled with the following options:
A couple of notes:
The linking issue can not be reproduced when using Homebrew's LLVM 22 because it uses LLVM_LINK_LLVM_DYLIB=ON. This seems to be leading to a situation when the linker issue is side-steps because of the symbols that are pulled by the dynamic LLVM library.
Passing LLVM_STATIC does not help with this case, since this flag only affects the way LLVM libraries are handled and does not change the way Clang libraries are handled:
llvm-config --libfiles --link-staticdoes not print any Clang-related libraries.Since LLVM version 22 the VFS is to be explicitly created for the CompilerInstance. Prior to version 22 this was done implicitly by the LLVM when calling createFileManager(), but now this is no longer the case, and LLVM has an assertion for it. The createVirtualFileSystem() with default arguments solves this problem, and initializes CompilerInstance's VFS the same way how it was done implicitly in the older versions of LLVM. Without this, compilation of OSO triggers an assert() in LLVM:
It is unclear whether this was causing any actual issue with release builds of LLVM, but it is better to use the API in the way it is expected to be used and create the VFS.
Last but not least, this change also fixes the following assert on the LLVM side when running OSL's test suite on macOS:
The value that trips on this assert statement comes from the DW_AT_APPLE_major_runtime_vers that the code in DwarfDebug.cpp, and it comes from the RuntimeVersion (RV) argument of the createCompileUnit(). This runtime value is supposed to indicate Obj-C runtime version which is either 1 or 2 (value 2 is for Objective-C 2.0). Passing OSL version as the runtime version does not fit single byte, and that is why the assertion trips. This change follows Clang's code which sets the runtime version to 0 for non-Objective-C languages. It is unclear what side-effects this change could bring, but it is also a bit strange to use OSL version for things that distinguish system runtime.
In order to be able to run OSL regression tests with LLVM compiled in debug mode, LLVM_LINK_LLVM_DYLIB=ON had to be used. Without this, the following assert in the LLVM triggers upon testrender startup:
This is to do with the way how LLVM registers command line arguments. It uses static variable initialization for this, and having LLVM as a static library that is pulled via CLang into both oslcomp and oslexec that are then pulled into testrender causes this situation to happen. For some reason, it does not happen if LLVM is compiled as static but release library.
The need of debug versions of OSL and LLVM libraries comes from the need to compile Blender on Windows in Debug mode, and libraries need to be compiled with a different CRT ABI.
Tested with the ctest with both LLVM 20 and 22 compiled in release. With all these changes the test suite passes to the same degree for LLVM 20 and 22, both Debug and Release. The only failing tests are related to Python module, and those I did not yet manage to get passing on a local development machine.
------ ✂️ -------------------------------------------------------------------
Checklist:
and if I used AI coding assistants, I have an
Assisted-by: TOOL / MODELline in the pull request description above.
behavior.
PR, by pushing the changes to my fork and seeing that the automated CI
passed there. (Exceptions: If most tests pass and you can't figure out why
the remaining ones fail, it's ok to submit the PR and ask for help. Or if
any failures seem entirely unrelated to your change; sometimes things break
on the GitHub runners.)
fixed any problems reported by the clang-format CI test.