-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
FEAT(installer): Bundle C++ redistributables #6789
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
FEAT(installer): Bundle C++ redistributables #6789
Conversation
Presently, the version required check is at least |
Nice, thank you very much. I still have a conceptual question: Why exactly does the VC installer have to be present at compile time and being downloaded when running the Mumble installer? Wouldn't the version used at build time be overwritten by the downloaded one anyway?
If we really need to have this at build time, we can make use/adapt this CMake function to download the mumble/3rdparty/rnnoise-build/CMakeLists.txt Lines 49 to 56 in f304e0a
Of course then it would make sense to declare the download url in CMake and write this variable to the |
That's a good question. The ExePackage has a child element called RemotePayload that has fields about the download file including a sha1 hash that it uses to validate the download when a user runs the installer. (The validation can be toggled off with In the commit you commented on, I didn't specify the However, it looks like the That means if, in the future, you change the |
I have read this a couple of times, not sure if I got this right. But it sounds to me like it would be possible to download |
I probably didn't explain it well. Right now in this branch, if you manually place The alternative is providing the metadata in the The first option has the advantage where, if you change the version of the distributables you depend on, you just change the The advantage of the second option is not having to worry about having the redistributables installer around at compile time, so it makes things a bit simpler. It kind of comes down to your preference. The second option is maybe a bit less convenient if you change what version of redistributables you depend on -- but my guess is that is very rare. If you want, I can write a new commit in this branch to show you what I mean exactly. (That way I can actually test that the second option actually works like I think it will.) And you can squash/edit the changesets as you wish before merging. |
Ok, I get it now, but I also think we are having two different conversations :)
My point is, it does not currently do that automatically. That is why the CI pipeline is failing. We/You/I can change the As a developer, having to download the redistributable and manually placing it in the directory when building is not an option. We need to be able to automatically build Mumble and the installer |
Yeah I agree. I might have misunderstood your question. I wasn't sure what your preference was between either having cmake download the redistributables or an option where the download wasn't required and instead the metadata was included in the source code. If you prefer the first option, I can have a go at making the required changes to cmake. I'm not real sure if cscs.exe (the program that starts the toolchain for building the mumble installer) has macros like the |
Yeah, that would be awesome. Downloading stuff at build time using CMake instead of doing it manually is fine. This will make the CI happy then I suppose :) |
I've updated this branch so that cmake downloads the redistributable and passes the download URL as a command line argument to cscs when building the installer so that the URL is only defined in one place. Let me know if you have any other questions or would like other adjustments. |
@sqwishy Looks reasonable to me like this. However, the Windows ecosystem is a mystery to me. @davidebeatrici Could you please test the installer on a Windows test machine? @Krzmbrzl Any thoughts? I would like to merge this before the next 1.5 release |
ddfeb69
to
318d551
Compare
Yeah, I mentioned this earlier #6789 (comment) . MumbleInstall.cs specifies a minimum version required.
I left it at 14.x in this pull request because I wasn't quite sure what you wanted to require as the minimum version. But I mentioned it so could set it to behave how you want. You might chose whatever version you have installed on the build server? I'm not quite sure what your dependencies are. But modifying that value in the MumbleInstall.cs file should be a way for you to configure it to your liking. Edit: If you're really not sure what version you require, you could probably err on the safe side and set it to the version that the installer downloads. (14.42.34438.0 I think?) I didn't pick that version because it's the right version or the minimum version that mumble needs, I just couldn't get links to less recent versions of the redistributable. And it's probably a good idea to download a more recent version anyway if they need to be installed. Edit Again: But if the mumble installer doesn't update old redistributables, I'm not sure it's actually a problem unless mumble doesn't run on the old redistributable that you show in the screenshot. |
Mumble appears to run just fine with 14.38.33135.0, however Microsoft broke ABI compatibility at least one time in the series: #6659 Honestly, I would just attempt to install the package without any checks on our side. If it's an older version compared to the one that is installed on the system, their installer should exit. |
That's surprising. I'm not really an expert in this but it looks to me what might have happened is that your releases of 1.5.634 and 1.5.735 were built with different versions of the toolchain. I can't see the logs for those builds so I can't really know for sure, but in the build logs for this PR it seems to be building on a very recent toolchain, so maybe the CI is set up to always a recent version. And some of Microsoft's docs for this say (emphasis mine):
So the minor version of the redistributable must be the same or higher than the toolset it was built with. "Must" is a strong word there since it probably isn't guaranteed to break if that condition isn't held, but it seems not supported. So if it is the case that the CI is building using the most recent version of the toolchain, you'd want to ship the most recent redistributable as well. I had assumed, when working on this, that the toolchain version, as any other dependency, was fixed and only updated manually. That's what I had in mind when I wrote the comment earlier about filling in whatever your minimum redistributable version is. So if you want to keep the CI as it is and not pin the version of the toolchain, then I might have to spend a bit more time thinking about this, but these are my initial thoughts if you have preferences. A simplistic approach is to build the installer with a link to aka.ms/vs/17/release/vc_redist.x64.exe instead of a link to a particular version of the redistributable. My understanding is that would require disabling download verification in the installer. And I don't feel super comfortable with that. This seems like an unusual thing for an installer to do. I'm apprehensive about this and worried there are good reasons to not do this that I'm not aware of right now. Possibly a better approach is to modify the cmake to resolve that link's redirect to get the download URL and use that when building the installer. This means the installer will always try to install a particular version of the redistributable (latest at build time) rather than the latest at install time. But that should be fine, since the version of the redistributable you need to run mumble shouldn't depend on when it was installed, just the toolchain version it was built with (or when it was built in this case). If the user's system has a newer version of the redistributable, hopefully it will do nothing -- I'll want to test that -- otherwise maybe we can maybe avoid installing older versions if we build the installer with VCREDIST_REQUIRED set appropriately based on the version that is resolved at build time. |
A little more information on this: We are using a different CI pipeline for the Windows release (as opposed to the test builds which happen here on GitHub), which has already proven multiple times as problematic. As in: We experience build issues not present in the GitHub CI. While this is not ideal, it allows us to get the binary properly signed (for free I think?) This is probably something that I should have specified earlier.
IIRC we do not (and can not?) specify the exact VC version in our release pipeline. They have automatically updating VM images used in the builders with god knows which version included. We specify something like Just an idea: Would it be possible, and I really have no clue that's why I am asking, to retrieve the version information of the VC that is installed on the builder at build time using cmake and insert that into the installer? The VM image might or might not have the latest version of VC installed afaik. |
I think one difficulty is mapping the version of the build toolchain to the runtime redistributable. The version I linked above in the CI uses The other difficulty is just getting the download URL for a particular version. Given a version of a redistributable, I do not know how to get a download link for it. The link that Microsoft provides redirects to the latest. So you do get a link to that version. But I'm not sure how to get a link to just any version. There was a page on the Microsoft website somewhere about getting particular versions but it seemed to be paywalled so I didn't look into it any further. |
As long as we always provide the latest redistributable at the time of the build we should never encounter any issues whatsoever. Visual C++ guarantees backwards compatibility, otherwise there would be no way to run programs built with different versions of the toolchain without installing the redistributable for every single one. The issue I mentioned was actually an extraordinary case, which as far as I know @microsoft never commented on. In fact, we first encountered the breakage with one of their own tools: appveyor/ci#3937 |
Yes
Correct I think going with the latest redist version at build time should be fine. That should always work (otherwise Microsoft screwed something up) as everything else wouldn't make any sense whatsoever (remember, we don't use preview versions of Visual Studio or something like that) |
The redistrituable are backward compatible. From what I can tell, the minor version version of the redistributable you ship must be greater or equal to the toolset version you build with. And it's a little unusual to have a dependency where the version is a moving target, but if that's all you have to work with in your build environment, then yeah it makes sense to just try to work around it in this case. My previous commit will resolve the URL to the latest distributable and pass that to the program that build the installer. It also includes the version so that in the installer can compare the system installed version to the distributable it has a link to. This means that in the above, where you 14.38 installed, you should find that the redistributable is updated when installing mumble in that case (provided the installer can access the internet when the user is running it). Just so you know, the process of resolving the link to the latest redistributable is done when at the when cmake generates the build directory. That is, the first step in using cmake which generates the build system before actually building. But that seems consistent with how some of the other packaging stuff worked. (Like for some reason it wouldn't copy changes to the installer .cs files from the source to build when modifying them unless regenerating the build system.) But my hunch is this isn't a huge issue as the link only needs to be re-resolved if the toolset you build with changes and that probably requires cmake to cleanly regenerate the build system anyway. And I assume your build system uses a clean environment between builds? But if you think this is going to be an issue, let me know. I just wasn't quite sure what to do about it as I am not super familiar with cmake. But I thought it's worth mentioning it so you are aware. |
@davidebeatrici Could you please re-check the latest version of this MR? |
Same issue unfortunately. |
Hmm, strange, but I'll double check. 🤔 Just to confirm, the latest redistributable on the system was 33135 but it didn't install a newer redistributable when you ran the new installer with internet access?
…On May 16, 2025 9:20:37 PM PDT, Davide Beatrici ***@***.***> wrote:
davidebeatrici left a comment (mumble-voip/mumble#6789)
Same issue unfortunately.
--
Reply to this email directly or view it on GitHub:
#6789 (comment)
You are receiving this because you were mentioned.
Message ID: ***@***.***>
|
Ah 💡 nice. I got this wrong then. Well then I'd say just adapt the CI pipeline such that we upload the .exe as artifact instead of the .msi |
@davidebeatrici Could you please take a look at this again? |
Yep, for reference here's the code in the commit about that: /* By default, if the installer does not have an internet connection, the download
* will fail and the entire install will fail. Setting Vital to false means that
* the install for the redistributables can fail silently and Mumble's install
* will continue. */
Vital = false, So by default, the entire install will fail if the user doesn't have internet access at the time of install. But that code sets a flag where it will skip it. If you want the install to fail, let me know, or just change/remove that setting in Another alternative is to include the redistributable along with the mumble installer so it can install it without an internet connection. (IIRC this is done by setting |
Until now I thought our CI pipeline was downloading the redistributable 😆 I think what we want is:
If I understand your post correctly, |
Agreed. A downgrade is not going to happen in case there is already a matching redistributable on the system with an equal or greater version. |
To be clear, the CI was and is downloading the redistributable. Even if the redistributable isn't embedded, the installer uses the file to determine a sha1 hash at build time, which is then used to verify the download at install time. Embedding the redistributable is super easy. Unfortunately, I just noticed that the "bootstrapper" application in the exe, which now runs in place of the msi, doesn't really have multi-language support? It looked like it was built to support it but none of the themes wix provides are actually localized in anything other than English as far as I can tell. This is a bit surprising to me and it seems like a downgrade over the multi-language msi you were providing. I really wish there was a straightforward way for the bootstrapper to run silently and show the msi interface instead. That way, there wouldn't be anything to localize and it would look as it did before. But as it is, the exe installer seems to always display in english regardless of the user's system language. If this is a blocker, let me know and I can see if I can figure out a solution. |
Ah, I see. I think this is where I got lost on the way.
The bootstrapper starts the msi at some point, right? Is the user asked for a language when the msi starts? Edit:
I take this as no... |
The bootstrapper UI runs in place of the msi and shows the licence and stuff so it basically looks and acts the same. It's possible to hide the msi UI but not the bootstrapper UI, so making the bootstrapper show the license makes the install process resemble your current installer the most. Except in regard to multi-language support as I've just noticed. It's possible to show the bootstrapper and the msi UI both but the experience is far from seamless. But if multi-language support is important, which I imagine it is, then it might be best to do that and keep the bootstrapper as simple as possible. |
Any updates on this @davidebeatrici @sqwishy |
@davidebeatrici Could you please test the latest installer? It should now bundle the redistributable |
The multi-language support is still missing, I haven't had time to look more into that. Not sure how important that is to you.
…On June 14, 2025 2:55:25 AM PDT, Hartmnt ***@***.***> wrote:
Hartmnt left a comment (mumble-voip/mumble#6789)
@davidebeatrici Could you please test the latest installer? It should now bundle the redistributable
--
Reply to this email directly or view it on GitHub:
#6789 (comment)
You are receiving this because you were mentioned.
Message ID: ***@***.***>
|
Yes, feel free to do more research on that. No pressure.
I don't know what the others have to say about this, but as far as I am personally concerned, my empathy with Windows and its users is limited. Crashing the application without error message when the redistributable is not installed (or up-to-date) is a red line for me though 😅. So that is my focus on this. |
yeah, I also feel like fixing the crash has higher priority than retaining a localized installer |
@davidebeatrici could you please test this again? I would like to merge this before drafting a release |
After building each server and client MSI, the installer script creates an EXE bundle that includes a step to download and install the Visual C++ redistributables.
On Windows, CMake will use PowerShell to get the URL for the latest visual c++ redistributable. CMake downloads it, reads the version from the file, and includes that information in the exe installer bundle.
4bbaaa6
to
f79534a
Compare
Thank you very much for all the work! |
💚 All backports created successfully
Questions ?Please refer to the Backport tool documentation and see the Github Action logs for details |
Thanks again @sqwishy for your excellent work and persistence. We would have taken much much longer to get anywhere without you. |
Due to PR mumble-voip#6789 we are now bundling the C++ redistributables ourselves. That means we will need to upload and distribute the new .exe files instead of the old .msi (which are included in the .exe files)
After building each server and client msi, the installer script creates an exe bundle that includes a step to download and install the visual c++ redistributables.
re #5549
This commit needs the redistrituables installer downloaded to
installer/VC_redist.x64.exe
. It includes a change in cmake to copy the file from there to the build directory. The wixsharp installer building stuff needsVC_redist.x64.exe
when building the bundle, even though the file isn't embedded in the resulting exe.I presume you would rather configure cmake download
VC_redist.x64.exe
or something instead of adding it to version control, so I didn't commit it.I left some comments in the C# code to try to explain what is going on with the installer and how the Wix stuff works. Let me know if you have any other questions.
The way the bundle works in this commit is that it hides the UI from the .msi installer and just displays is own UI in its place. So the license and logo are copied in to the bundle UI and it ends up resembling the .msi a bit. Here's a screenshot of what to expect.
Checks