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

cmd/link: generate manifest in EXE files #17835

Open
quentinmit opened this issue Nov 7, 2016 · 19 comments
Open

cmd/link: generate manifest in EXE files #17835

quentinmit opened this issue Nov 7, 2016 · 19 comments

Comments

@quentinmit
Copy link
Contributor

@quentinmit quentinmit commented Nov 7, 2016

On Windows 10 and later, apps can opt into long path support by embedding an XML manifest:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx

We should automatically embed this manifest when linking EXE files. For prior art, see this third-party tool for generating a .syso file containing a manifest:

josephspurrier/goversioninfo@f8c5d36#diff-88fef3681df95cd75f2ac89251404081

@minux
Copy link
Member

@minux minux commented Nov 8, 2016

@quentinmit
Copy link
Contributor Author

@quentinmit quentinmit commented Nov 8, 2016

I'm proposing the former for a start, since it doesn't require any UI changes.

Presumably any fix should continue to allow a user-specified .syso file to override the manifest.

@minux
Copy link
Member

@minux minux commented Nov 8, 2016

@alexbrainman
Copy link
Member

@alexbrainman alexbrainman commented Nov 8, 2016

We should automatically embed this manifest when linking EXE files. For prior art, see this third-party tool for generating a .syso file containing a manifest:

It is probably not important, but do you plan to generate .syso file with the manifest and link it with the executable, or modify linker to append manifest as executable is built?

Alex

@bradfitz bradfitz added this to the Go1.10Early milestone May 3, 2017
@bradfitz bradfitz removed this from the Go1.9Early milestone May 3, 2017
@bradfitz bradfitz removed this from the Go1.10Early milestone Jun 14, 2017
@bradfitz bradfitz added this to the Go1.10 milestone Jun 14, 2017
@bradfitz bradfitz added this to the Go1.10 milestone Jun 14, 2017
@bradfitz bradfitz removed this from the Go1.10Early milestone Jun 14, 2017
@rsc
Copy link
Contributor

@rsc rsc commented Nov 22, 2017

What would the benefit be if we made this change? Now that we use long path syntax transparently in the Go APIs I don't see what adding the XML manifest would add (other than XML).

@rsc rsc removed this from the Go1.10 milestone Nov 22, 2017
@rsc rsc added this to the Go1.11 milestone Nov 22, 2017
@fkollmann
Copy link

@fkollmann fkollmann commented Mar 8, 2018

The main benefit is that the syscall.GetVersion() number would return the correct Windows version.

Applications not manifested for Windows 8.1 or Windows 10 will return the Windows 8 OS version value (6.2).

see https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439

@fkollmann
Copy link

@fkollmann fkollmann commented Mar 9, 2018

Example:

winver, _ := syscall.GetVersion()

fmt.Printf("Windows version: %v.%v.%v", byte(winver), byte(winver>>8), uint16(winver>>18))

With manifest: Windows version: 10.0.4074
Without manifest: Windows version: 6.2.2300

@fkollmann
Copy link

@fkollmann fkollmann commented Mar 9, 2018

@quentinmit thanks for the hint on goversioninfo. This is how we currently approach it: https://github.com/konsorten/ktn-build-info/blob/master/ver/go.go

@bradfitz bradfitz removed this from the Go1.11 milestone May 18, 2018
@bradfitz bradfitz added this to the Go1.12 milestone May 18, 2018
@bradfitz bradfitz removed this from the Go1.12 milestone May 18, 2018
@ianlancetaylor ianlancetaylor added this to the Go1.12 milestone Jun 1, 2018
@andlabs
Copy link
Contributor

@andlabs andlabs commented Sep 2, 2018

Note that the gcc that comes with MSYS2 under default configurations forces a manifest to be included; see msys2/MSYS2-packages#454 In a cgo build, it gets included in the output _cgo_.o file.

@tandr
Copy link

@tandr tandr commented Feb 3, 2020

Just got hit by this again on goimports on windows machine. Fixing this only for single executable is possible, but way painful - there are too many of them. Fixing it for all Go-built executables would be absolutely wonderful...

@andlabs
Copy link
Contributor

@andlabs andlabs commented Feb 3, 2020

Any solution would need to not interfere with a manifest that's provided by the programmer — for example, through cgo, or as a syso file. The MinGW thing I mentioned above will defer to a manifest you provide if you provide one.

Example showing my current solution, though in this case for selecting side-by-side assemblies instead of enabling Windows 10 version detection: https://github.com/andlabs/ui/tree/master/winmanifest

Also note that the OS version manifest is a promise that the program is well-written and uses the OS version information correctly — and there are incorrect uses of version detection, such as feature guards where a simple LazyDLL lookup will suffice instead. Even if Go does this automatically, the burden will still fall on the Go programmer as well.

@gonutz
Copy link

@gonutz gonutz commented Sep 29, 2020

I am currently working on a Windows GUI library and to get around the user having to create a manifest file I load one at runtime using CreateActCtx and ActivateActCtx, see here:

https://github.com/gonutz/wui/blob/de4f85fed213c34377fd068ef39e1b2f0e04ea7d/window.go#L1119

which is another way the manifest file can be overwritten.

@networkimprov
Copy link

@networkimprov networkimprov commented Feb 11, 2021

We need someone to file a separate proposal to support a user-provided manifest on Windows. And also MacOS?

cc @zx2c4 @jstarks @eliasnaur

@zx2c4
Copy link
Contributor

@zx2c4 zx2c4 commented Feb 12, 2021

XML file + windres (from llvm or binutls) ==> .syso, which go gladly accepts. This works fine for me and lets me use other features of Windows resources.

@eliasnaur
Copy link
Contributor

@eliasnaur eliasnaur commented Feb 12, 2021

FWIW, Gio has a tool for building Windows executables and adding a manifest to specify its icon: https://git.sr.ht/~eliasnaur/gio/tree/main/item/cmd/gogio/windowsbuild.go. I believe the Fyne project has something similar, including support for macOS.

@zx2c4
Copy link
Contributor

@zx2c4 zx2c4 commented Feb 12, 2021

Right. There are many ways to generate resource files -- they're just PE/COFF objects, after all. The point is, I'm not sure this is something that the Go toolchain needs now, beyond ingesting .syso files created by tools like yours or windres or others.

@jstarks
Copy link

@jstarks jstarks commented Feb 12, 2021

A counterargument is that various Win32 API behavior is tweaked according to the contents of the manifest. We've already identified the long path behavior as one case, but there is various compatibility-related behavior keyed off the more generic supportedOS element:

  • GetVersion only reports the correct version if you advertise Windows 8+ support.
  • The heap applies some extra optimizations to limit commit use if you advertise Windows 10+ support.
  • The system is more aggressive about faulting on invalid handle use if you advertise Windows 10+ support.
  • CreateFile and GetOverlappedResult have stricter behavior if you advertise Windows 10+ support.

Regardless what is decided about the long path bit, it may be in Go's interest to make setting these easy or automatic rather than rely on each application to construct and link a manifest manually.

@networkimprov
Copy link

@networkimprov networkimprov commented Feb 12, 2021

@jstarks (or anyone) how should this work in practice?

Build-time recognition of a manifest source file for GOOS=windows? And automatic generation of a manifest with the features you listed (which could then be modified by user)? Should it issue warnings if it finds a manifest without those features?

@networkimprov
Copy link

@networkimprov networkimprov commented Feb 20, 2021

Filed #44466 - proposal: create manifest when building for Windows.

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

Successfully merging a pull request may close this issue.

None yet