Skip to content

Add static linking feature#25

Open
ThierryBerger wants to merge 7 commits intoFloatyMonkey:mainfrom
ThierryBerger:static-build
Open

Add static linking feature#25
ThierryBerger wants to merge 7 commits intoFloatyMonkey:mainfrom
ThierryBerger:static-build

Conversation

@ThierryBerger
Copy link

@ThierryBerger ThierryBerger commented Sep 29, 2025

Hello, linking dynamically requires library users to either:

  • Bundle their final binary with dynamic libraries
  • Provide a way for users to provide their path, and teach them how to do it.

It also makes it difficult to have a self-contained binary, where you just move it anywhere and it works.

An alternative is to statically link as much as we can. Users still need to provide path to libraries when compiling, but the above requirements can be ignored.

This PR adds a feature gate to statically link slang, this linking requires an additional SLANG_EXTERNAL_DIR env variable.

I built my slang library from source, setting "SLANG_LIB_TYPE": "STATIC" in the CMakePresets.json.

bindgen = "0.72.0"

[features]
default = ["static"]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm open to make dynamic the default

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer dynamic be the default as long as Slang doesn't distribute static libraries in their releases or through the Vulkan SDK.

println!("cargo:rustc-link-lib=static=miniz");
println!("cargo:rustc-link-lib=static=lz4");
// Standard C++ library
println!("cargo:rustc-link-lib=static=stdc++");
Copy link
Author

@ThierryBerger ThierryBerger Sep 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it may be better to link dynamically for stdc++ ? This would remove the added stdc++ path env variable, and ends up being easier to use on apple:

println!("cargo:rustc-flags=-l dylib=c++");

But this doesn't seem to work on my popOS ; I'm not sure if I should expose somehow my libc++ or conditionally choose the strategy depending on OS.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm mostly familiar with Windows, so not sure of the requirements or best solutions for Apple/Linux.
If we could do this without additional dependencies, however small, that would be great.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@laurooyen laurooyen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR, even updating the documentation!
Static linking is certainly a welcome addition, just a shame Slang doesn't distribute static libraries by default.

println!("cargo:rustc-link-lib=static=miniz");
println!("cargo:rustc-link-lib=static=lz4");
// Standard C++ library
println!("cargo:rustc-link-lib=static=stdc++");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm mostly familiar with Windows, so not sure of the requirements or best solutions for Apple/Linux.
If we could do this without additional dependencies, however small, that would be great.

bindgen = "0.72.0"

[features]
default = ["static"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer dynamic be the default as long as Slang doesn't distribute static libraries in their releases or through the Vulkan SDK.

Comment on lines +72 to +77
if cfg!(not(target_env = "msvc")) {
// MinGW: Link libstdc++
println!("cargo:rustc-link-lib=stdc++");
} else {
// No linking necessary on Windows, the MSVC runtime is linked by default.
}
Copy link
Author

@ThierryBerger ThierryBerger Oct 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those paths haven´t been tested, so please report your findings :)

Comment on lines +68 to +70
// The C++ lib has to be the same as the one used to compile Slang,
// otherwise you will get errors about missing symbols.
// The following is only a best guess depending on platform's defaults.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this note as I was reading through https://github.com/dtolnay/link-cplusplus/blob/master/README.md and other resources more carefully.

I believe link-cplusplus solution is better, as in this PR, a user on linux could build the slang lib against libc++ (not stdc++), and then shader-slang-sys wouldn't find c++ symbols due to incompatible ABIs...

As an actionable call for action, I recommend either:

  • keep it as-is, best effort is better than no effort, adjust when/if complaints arise.
  • add link-cplusplus dependency
  • vendor/copy link-cplusplus code in slang-rs.

Your call :)

@ThierryBerger
Copy link
Author

@laurooyen I addressed the feedbacks, and tested successfully on mac + linux (popOS).

  • I can't test on windows so I'm calling out for your tests.
  • Comment about c++ linking may require special attention.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants