golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.17k stars 17.56k forks source link

debug/pe: big-obj is not supported #24341

Open k-takata opened 6 years ago

k-takata commented 6 years ago

cgo doesn't support the big-obj format.

What version of Go are you using (go version)?

go version go1.10 windows/amd64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

set GOARCH=amd64
set GOOS=windows

What did you do?

I tried to link a .o file which is generated with the -Wa,-mbig-obj gcc option. See the following background for detail.

What did you expect to see?

The big-obj format is supported by cgo.

What did you see instead?

cannot parse gcc output $WORK\b001\\_cgo_.o as ELF, Mach-O, PE object

The message is produced at here: https://github.com/golang/go/blob/5c432fe0e3755255d70d1ad601725b039becb7ad/src/cmd/cgo/gcc.go#L1586

I suppose debug/pe doesn't support the big-obj format.

Background

I'm now trying to use wxGo, but the size of an executable file is quite big (~30MB), so I tried to reduce the size by using -fdata-sections -ffunction-sections CPPFLAGS and -Wl,--gc-sections LDFLAGS. (See: https://stackoverflow.com/a/6770305/4570471) However, this caused the following error:

C:/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/5.1.0/../../../../x86_64-w64-mingw32/bin/as.exe: $WORK\b001\_x003.o: too many sections (70137)
C:\Users\*******\AppData\Local\Temp\ccjbnMxS.s: Fatal error: can't close $WORK\b001\_x003.o: File too big

This is because the traditional PE-COFF format stores the number of sections with a 16-bit signed integer. To support more than 32K sections, the big-obj format is needed, and the -Wa,-mbig-obj CPPFLAGS can be used for that. However, cgo doesn't support the big-obj format.

Steps to reproduce:

path C:\TDM-GCC-64\bin;%PATH%
set "CGO_LDFLAGS_ALLOW=-Wl,--subsystem,windows|-mwindows"
set "CGO_CPPFLAGS_ALLOW=-fdata-sections|-ffunction-sections|-Wa,-mbig-obj"
go get -u -d github.com/dontpanic92/wxGo/wx
cd %GOPATH%\src\github.com\dontpanic92\wxGo

Then apply the following patch to wxGo:

--- a/wx/setup_windows_amd64.go
+++ b/wx/setup_windows_amd64.go
@@ -1,6 +1,6 @@
 package wx

-// #cgo CPPFLAGS: -I${SRCDIR}/windows_amd64/ -I${SRCDIR}/../wxWidgets/wxWidgets-3.1.0/include -D_FILE_OFFSET_BITS=64 -D__WXMSW__
+// #cgo CPPFLAGS: -I${SRCDIR}/windows_amd64/ -I${SRCDIR}/../wxWidgets/wxWidgets-3.1.0/include -D_FILE_OFFSET_BITS=64 -D__WXMSW__ -fdata-sections -ffunction-sections -Wa,-mbig-obj
 // #cgo !wxgo_binary_package_build LDFLAGS: -L${SRCDIR}/windows_amd64/lib -lwxmsw31u -lwxmsw31u_gl -lwxscintilla -lwxregexu -lwxexpat -lwxtiff -lwxjpeg -lwxpng -lwxzlib
 // #cgo mingw_workaround LDFLAGS: -Wl,--subsystem,windows,--allow-multiple-definition
 // #cgo !mingw_workaround LDFLAGS: -Wl,--subsystem,windows

Then:

cd wx
go install -x .

The following error is shown:

cannot parse gcc output $WORK\b001\\_cgo_.o as ELF, Mach-O, PE object

Cf. in case of Haskell: https://ghc.haskell.org/trac/ghc/ticket/13815

andybons commented 6 years ago

/cc @ianlancetaylor

ianlancetaylor commented 6 years ago

I think this will all start working if we modify the debug/pe package to support the big-obj format. I haven't looked at the format, but assuming there is nothing weird about it we should just go ahead and do that.

Labelled as "help wanted".