-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add handling of static versus dynamic linking of the C RunTime (CRT) #115
Comments
Unfortunately, no. There are a lot of different ways to enable static linking of the CRT runtime, and cargo-metadata doesn't give us any of this information. What could work is checking the .exes for exports, e.g. parse the PE and check if it requires MSVCRT.dll (or any of its variants. Checking for a dll that starts with MSVCR should work well enough). There are some really good PE parsers (I highly recommend pelite that should make automated checking painless. The hard part becomes finding which PE to parse. This is information cargo-metadata might be able to give us, but if the user modifies the WXS, we might want to instead parse the WXS to find which binaries are being included?
What if it changes afterwards? What I do think might be a good idea is having a |
Does the debug_assertions
target_arch="x86_64"
target_endian="little"
target_env="msvc"
target_family="windows"
target_feature="fxsr"
target_feature="sse"
target_feature="sse2"
target_os="windows"
target_pointer_width="64"
target_vendor="pc"
windows I see the C:\>$env:RUSTFLAGS="-C target-feature=+crt-static"; rustc --print cfg But a
Would this be further complicated by the
I looked at the pelite crate, and that is a pretty neat library. If we go this route, then it looks pretty painless to check with pelite, as @roblabla mentioned.
I would like to avoid Q&A prompts in the CLI because no other feature within cargo-wix does this...yet, but flags or options would work. I am a little lost in the order of operations relative to handling static vs dynamic linking of the CRT, so the following may be redundant, but bear with me. First, there is the Then, there is the After this discussion with myself, it appears the WXS template is going to always need the Merge WiX implementation but it should be behind a preprocessor directive to enable or disable at installer creation time. I don't see a need for anything to happen at initialization/print time. In other words, a Q&A prompt, WARN statement, CLI flags/options, configuration check, etc. about the CRT at initialization/print do not appear to be needed as long as the WXS template always includes the Merge implementation behind a WiX variable. Is any of this a concern with the How do we determine which CRT installer to include, i.e. version? Action items:
For reference: Static and Dynamic C Runtimes I should probably rename this issue as this is more than just documentation, but actually a feature. I appear to have closed #114 too soon. My apologizes. |
Well, if we go the cargo-metadata route, yes. If we go the WXS parsing route, no.
Agreed, that seems like a fairly good course of action. Always have the merge, use the
AFAIK gnu toolchain has its own CRT and doesn't rely on msvcrt. I think they statically linked the CRT by default, but someone would need to double check. Either way, I think it makes sense to make a separate ticket for this.
This is... complicated. I believe it depends on which version of the Visual Studio Build Tools you have installed. I don't know if there's a good way to know this without parsing the exe to find its DLL imports. |
Further questions to ponder and investigate after a brief exploration:
It looks like the merge modules are optional components when installing VS and build tools 2019. The merge modules are included in 2015 and 2017 by default (of course!). This complicates matters even more because while 2019 Built Tools are needed when installing Rust, now an optional component must also be installed. Another caveat/dependency must be added to cargo-wix. However, looking at my development environment, the We could just assume the developer has installed the merge modules and output an error message with appropriate directions and information for either installing the merge modules for 2019 and/or switching to static linking. As for selecting the appropriate CRT version, a simple implementation would be to force the user to explicitly state the version/path to merge module if dynamic linking is used. An error message to require a flag/option/configuration could be added that nicely indicates we need this information. The list of caveats, dependencies, questions, etc. to implement this keeps growing. The simplest resolution continues to be "enable static compiling". Let's do the following:
These steps would avoid the whole merge modules, versions, redistributables, etc. problems, but I acknowledge not the most "out-of-the-box" UX for the cargo-wix subcommand and users. I found Rust, Windows, and MSVC with discussion about the CRT, but it is long and I have not gone through all of it yet. |
Added documentation and information about the CRT dependency and static linking as of bc06cb8. This does not implement any resolution of the issue but it does resolve the original description of this issue and provides information to users until a more elegant resolution has been implemented. |
I was experimenting with adding detection of the |
See #114 for the initial information. A Windows built Rust binary (executable) needs a C RunTime (CRT). By default, the CRT is dynamically linked to the executable, which keeps the executable size smaller. As of Rust v1.19, it is possible to statically link the CRT. This results in a slightly larger executable, but eliminates distribution of a dependency and/or eliminates installation of a prerequisite for running the Windows-built Rust binary.
In the case of the default, where the CRT is dynamically linked and not included in the executable, a CRT can be added to the MSI using the
Merge
WiX Toolset tag, or needs to be installed separately before running the Rust binary on Windows.In the case of statically linking the CRT with the Rust executable, a
rustflag
can be defined in a environment variable, project configuration (Cargo.toml) or developer's Cargo configuration.Adding static linking of the CRT is a simpler solution and recommended, but there are tradeoffs and developers may not be aware of this issue for their users since most Rust developers will have the required CRT already installed. Thus, some details and possible solutions based on these options should be added to the documentation.
A side thought, is it possible to detect from the cargo-metadata crate if static linking of the CRT is enabled? Maybe a warning should be printed if dynamic linking is being used and the CRT is not included in the WXS file? Or, is it possible to detect if dynamic linking is enabled at the time of the
cargo wix init
command and the template automatically adds the CRT to the installer? This would take the CRT version of the developer's computer. For now, a simple configuration in a project's Cargo.toml file handles all of this, but it is something to think about. I do recognize this is probably what #114 was asking to implement. It just took me a moment.The text was updated successfully, but these errors were encountered: