akavel / rsrc

Tool for embedding .ico & manifest resources in Go programs for Windows.
MIT License
1.22k stars 122 forks source link

64 bit issue #11

Closed zhangpy closed 8 years ago

zhangpy commented 9 years ago

I have this issue when I cross build windows 64bit app on ubuntu. I use rsrc to generate syso file and user follow command to build

export GOOS=windows
export GOARCH=amd64
export CGO_ENABLED=1
export CGO_LDFLAGS="-lssp"
export CC=x86_64-w64-mingw32-gcc
export CXX=x86_64-w64-mingw32-g++
go build -o app.exe test/app

the output is:

/usr/local/go/pkg/tool/linux_amd64/link: running x86_64-w64-mingw32-gcc failed: exit status 1
/usr/bin/x86_64-w64-mingw32-ld: i386 architecture of input file `/tmp/go-link-589012901/000000.o' is incompatible with i386:x86-64 output
collect2: error: ld returned 1 exit status

when I user 32bit gcc, no such issue. My go version: go version go1.5beta3 linux/amd64

Please let me know if you need more info.

akavel commented 9 years ago

Could you please report this on http://golang.org/issue/ and add a link here? I seemed to believe that .syso files would be treated as "architecture independent" by the Go toolchain, but I might be wrong, and also rsrc is a semi-unofficial hack, which is not under any compatibility promise on Go side, I think. That said, I believe that reporting an issue on golang could help us get an answer from the Go authors if they'd consider this as an issue which could be solved in the Go toolchain, or if they refuse to do that and it'd fall on rsrc to try to adapt.

Also, can you please write what exactly command you use to generate the .syso file?

YijinLiu commented 8 years ago

I have the same issue. Here is the manifest file: <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity version="9.0.0.0" name="list_device.exe" type="win32" /> <description>A tool to list local devices.</description> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/> </requestedPrivileges> </security> </trustInfo> </assembly>

And command to generate the syso file: bin/rsrc.exe -manifest=EXE.manifest -o EXE.syso

alexbrainman commented 8 years ago

@akavel, I grepped your code:

# grep Machine * -n
110:                    Machine:              0x014c, //FIXME: find out how to differentiate this value, or maybe not necessary for Go
181:                    Machine:              0x014c, //FIXME: find out how to differentiate this value, or maybe not necessary for Go

and I can see you have a TODO for this bug. I think you have to use IMAGE_FILE_MACHINE_AMD64 (see cmd/link/internal/ld/pe.go) when building amd64 objects.

Alex

akavel commented 8 years ago

@alexbrainman The problem with solving this FIXME is that it would require building two separate .syso files (or more for more machines). And if going this way, I don't know how then to let the go tool know that it should only choose (link) one of them, depending on what's the target ARCH?

Initially I hoped that it might be a regression in Go, but from https://github.com/golang/go/issues/13070 I understand it's not seen as such. As a stop-gap solution, I'll then try to add flag to specify target ARCH, and ask you guys if it helped, but I'm totally interested in any ideas how this could be resolved while still making a resulting project go-gettable on both amd64 & x86...

Thanks all for helping with this.

akavel commented 8 years ago

@zhangpy @YijinLiu @jhowardmsft @jfrazelle Could you please try go get -u github.com/akavel/rsrc and check if the new option -arch amd64 would fix it for you? If yes, then it would be especially great if you could also test if building two .syso files with appropriate GOARCH suffix and having them both together in one directory at the same time would work OK — that is, something like:

cd your_project
rsrc -manifest=EXE.manifest -arch amd64 -o EXE_amd64.syso
rsrc -manifest=EXE.manifest -arch 386 -o EXE_386.syso
go build .

or something similar. Thanks in advance!

I've tried some easy attempt at fixing it for starters, but I don't have easy way to test if it works. I do use Win64, but I don't use cgo, so don't have experience with setting it up.

(And wow, didn't know rsrc is used by Docker & Microsoft; I'm glad it has shown useful ;) )

lowenna commented 8 years ago

Of course. Yes, I'll give this a go (no pun intended!). It might be tomorrow though - am tied up with other things which urgently need doing today. Thx.

(And yes, it was quite a find to find a native way of manifesting a go application on Windows. My other workarounds were almost non-workable, at least in the docker build environment. Thank you for writing this!!)

lowenna commented 8 years ago

Yes! That works :) Had to give it a quick try. Need to fathom the complete set of changes but using -arch amd64, I was able to link 64-bit docker without using the linkmode internal workaround.

akavel commented 8 years ago

@jhowardmsft Awesome, thanks! :)

(For future record, related discussion on golang-nuts: https://groups.google.com/forum/#!topic/golang-nuts/pZB_QQQk2Z4)

lowenna commented 8 years ago

@akavel Ah, no, I take that back. It links, but won't run :(

akavel commented 8 years ago

@jhowardmsft Eh, yeah, I was afraid something like that might happen. That's no good, unfortunately. I'll have to dive deeper, and not sure how long it may take. That said, if you could provide me with some small easy project reproducing this, and potentially also any help on how to setup cgo/MinGW appropriately on 64bit Windows, I'd be very grateful. I understand the files you uploaded on golang-nuts are something like that, yes?

lowenna commented 8 years ago

@akavel - Try this repo for a simple repro: https://github.com/jhowardmsft/sql1.5.1. For mingw-64, I installed v5.2 from http://sourceforge.net/projects/mingw-w64/files/latest/download with these options (based on the directory path of the install): x86_64-5.2.0-win32-seh-rt_v4-rev0

akavel commented 8 years ago

@jhowardmsft By the way, I feel obliged to tell you, that the pragmatic solution for you at this point would be probably to use windres.exe, given that you seem to be using cgo (and thus gcc) anyway. Something like:

c:> type main.rc
#include "winuser.h"
1 RT_MANIFEST "c:/path/to/your.manifest"
2 ICON "c:/path/to/your.ico"
c:> windres --input=main.rc --input-format=rc --output=main.syso --output-format=coff

might build a nice .syso. Not sure whether that would be the amd64 or 386 one, but maybe the --target flag would be of some help here. Diffing against results of windres and trying to find out the meaning of the bytes is part of my process when developing rsrc...

lowenna commented 8 years ago

Fascinating! I had no idea that utility was present. I'd have to verify it works cross-platform too though (the docker official build is a cross-compile from Linux...). For now, the internal linkmode is a viable workaround though, but I'll certainly keep that in my pocket.

alexbrainman commented 8 years ago

@akavel you can test your generated syso files by just linking them to simple C program with mingw gcc. Just write smallest possible program compile it and then link compiled objects + your syso file into executable. You should be able to run executable and see all your resources (icons) and others as expected. That is what effectively cgo does when using external linking. You can use objdump from mingw (or dumpbin from microsoft) to analyse all object and executable files. Feel free to ask for help, but I don't know a lot about this. I will help whatever way I can.

Alex

akavel commented 8 years ago

@jhowardmsft & guys, would you be willing to test another version? I found and fixed one more I386 const to its apparently AMD64 variant; the Windows error message box doesn't seem to appear anymore after running a linked .exe, at least for me™...

alexbrainman commented 8 years ago

google for pecoff.doc. The document has pretty good description of pe file guts.

Alex

akavel commented 8 years ago

I've found some time to test with the repro sources at: https://github.com/jhowardmsft/sql1.5.1 (thanks @jhowardmsft !), and it seems to work as of now. Full transcript of my testing session is at: https://gist.github.com/akavel/4acd7e163774f337b84a

Thanks everybody for help; it's purely a hobby project for me (and one of much too many...), so all your help is extremely useful and appreciated. Given the evidence I have, and no reports of failure in the last 24 days, I'm closing this issue now. But if you find out it still fails for you in some specific case, please do reopen (with appropriate info), and please do keep being as patient with me as you all were. Thanks.

PS. I'll try to find some more time to update the readmes & precompiled downloads with the new version.