Skip to content
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

generated msi does not include vc runtime #114

Closed
pm100 opened this issue Oct 31, 2020 · 4 comments
Closed

generated msi does not include vc runtime #114

pm100 opened this issue Oct 31, 2020 · 4 comments
Assignees
Labels

Comments

@pm100
Copy link

pm100 commented Oct 31, 2020

this means that on a clean windows install the package wont run. Although I could create a custom wxs file I think that should be standard.

The fiddly bit will be knowing what vcredist to include since I guess that will change as the rust tool chain gets upgraded. At the moment it needs vcruntime140.dll

@volks73
Copy link
Owner

volks73 commented Nov 1, 2020

Thank you for the issue/feature request. I have read the sibling issue at extrawurst/gitui#394, but including a VC runtime appears to be an issue specific to your project. It is not clear to me at the moment, how this is a requirement for every Rust project using cargo-wix or a bug with the cargo-wix code.

My current understanding and reading of the issues: you want cargo-wix to include a Visual C++ Redistributable with every installer by default, i.e. "standard". I think this means you would like the template WXS file created by cargo-wix with the cargo wix init command to bundle/merge a VC runtime DLL. What about projects that do not need a Visual C++ Redistributable? How common is it for Rust projects wanting an installer (MSI) that also need the VC runtime DLL? As you mention, which version should be included and how to manage different versions?

It appears if a user would like to include VC runtime with his or her installer, it can be added to the WXS file after the template is created by modifying the XML with a text editor. Reviewing the WiX Toolset documentation, adding a Visual C++ Redistributable to an installer appears to be relatively straight-forward within the WXS file:

<DirectoryRef Id="TARGETDIR">
    <Merge Id="VCRedist" SourceFile="MySourceFiles\Microsoft_VC80_CRT_x86.msm" DiskId="1" Language="0"/>
</DirectoryRef>
<Feature Id="VCRedist" Title="Visual C++ 8.0 Runtime" AllowAdvertise="no" Display="hidden" Level="1">
    <MergeRef Id="VCRedist"/>
</Feature>

Generally, the workflow would be to create a main.wxs file using the cargo wix init command. The cargo wix init command only needs to be executed once. Then, open the wix\main.wxs file (assuming defaults were used) in your favorite text/code editor and add the above six lines of XML according to the WiX Toolset documentation with the appropriate VC runtime DLL version. Modification of the main.wxs to add the redistributable only needs to be done once as well. Then, any time you want to create an installer, cargo wix. The main.wxs file should be added to version control, too.

If can you elaborate a little more on your usage of cargo-wix and its involvement in your project's workflow, then maybe I can see how this issue could more broadly apply to any Rust project using cargo-wix and be something that requires modification to the cargo-wix codebase for resolution?

However, are you suggesting that a VC runtime is needed in order to run any cargo-wix command? This would be odd to me as the VC runtime requirement would be a Rust/Cargo requirement for Windows. Would the VC Build Tools (a prerequisite for installing Rust on any Windows machine) include the needed VC runtime?

@volks73
Copy link
Owner

volks73 commented Nov 1, 2020

Looking a little closer at the gitui source code, project, and CI configuration, I think the issue is that you are creating a new WXS file every time the release build is executed, i.e. CI. By including the cargo wix init step in the CI build, a new WXS file (wix\main.wxs) is created. This is going to cause problems because a new upgrade code and product code (GUIDs) are created every time. Thus, upgrading from one release to the next release will not work. Windows will treat each MSI as a separate application to install, as opposed to uninstalling/overwriting with the new release.

At the moment, the solution is to create a wix\main.wxs file using the cargo wix init command outside of the CI build process. Modify wix\main.wxs file to add the Visual C++ redistributable and add to version control. Remove the cargo wix init step from the Makefile and CI configuration and just execute the cargo wix command. The upgrade code and product code will be constant and stored as part of the source code within the WXS file. This will require adding the wix\main.wxs file to the source code, but it should be considered source code similar to a Makefile.

I think you might be interested in Ephemeral Builds and Command (#88) feature request and discussion. Please review #88. I would appreciate any feedback and information about its utility and implementation for your needs.

@pm100
Copy link
Author

pm100 commented Nov 1, 2020

every default built windows rust exe needs vcruntime140.dll. A rust exe simply will not run if its not present.

A users expectation is that an MSI installs all the bits needed to use the app. Ie I run the installer, next thing is that I can use the app. That does not happen at the moment

try it out, build rust hello world using defaults, use cargo wix to create an msi. Take that msi to a virgin windows install and install it. When you try to run the binary nothing happens. Ran from the command line you just get another prompt.

I know how to modify wxs to install vcruntime, but since all rust exe's need it I though you would want a global fix.

Anyway I worked out a simpler solution which is to statically link the app.

RUSTFLAGS="-C target-feature=+crt-static"

@volks73
Copy link
Owner

volks73 commented Nov 1, 2020

Thank you for the additional information. I am glad you were able to find a simpler solution. Just to expand on your solution in case others have similar concerns: it appears since Rust v1.19, the -C target-feature=+crt-static flag is available. This can be specified using the RUSTFLAGS environment variable as you have indicated, but it can also be placed in the project's manifest (Cargo.toml) for a specific target as well:

[target.x86_64-pc-windows-msvc]
rustflags = ["-C", "target-feature=+crt-static"]

or even in a Cargo user's configuration for all his or her Rust projects on Windows. The "How to generate statically linked executables" Stack Overflow question and answers has more information about this, specifically Arkod's answer.

This actually complicates things a little bit further as some projects will use this flag and some will not. In cases where the C runtime (CRT) is statically linked, then nothing needs to happen with the installer. In the case where the C runtime (CRT) is dynamically linked, then the CRT becomes a dependency/prerequisite that the developer may or may not want to include in the installer.

Given all of this, I think the best course of action might be to actually just update the documentation for cargo-wix to highlight the potential issue for developers and provide some details on how to create a problem-free first run experience either by statically linking the CRT (Recommended) or by including the CRT with the merge tag from the WiX Toolset. I will close this issue and create another one to track updating the documentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants