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: cgo linking fails on Windows with GCC 11.2.0 + MinGW-w64 9.0.0 (UCRT) from winlibs.com #51007

Closed
NewUserHa opened this issue Feb 4, 2022 · 26 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Windows
Milestone

Comments

@NewUserHa
Copy link

Original post: mattn/go-sqlite3#1012

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

$ go version
go version go1.17.5 windows/amd64

Does this issue reproduce with the latest release?

maybe

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

go env Output
$ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=C:\Users\user\Desktop
set GOCACHE=C:\Users\user\AppData\Local\go-build
set GOENV=C:\Users\user\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\user\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\user\go
set GOPRIVATE=
set GOPROXY=https://goproxy.io,direct
set GOROOT=C:\Program Files\Go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=C:\Program Files\Go\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.17.5
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=NUL
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\user\AppData\Local\Temp\go-build2697353945=/tmp/go-build -gno-record-gcc-switches

What did you do?

import it and go build or go run .

What did you expect to see?

no output

What did you see instead?

> go run .
# 
C:\Program Files\Go\pkg\tool\windows_amd64\link.exe: running gcc failed: exit status 1
c:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\user\AppData\Local\Temp\go-link-2621619269\000016.o: in function `_cgo_preinit_init':
c:\go\src\runtime\cgo/gcc_libinit_windows.c:30: undefined reference to `__imp___iob_func'
c:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\user\AppData\Local\Temp\go-link-2621619269\000016.o: in function `x_cgo_sys_thread_create':
c:\go\src\runtime\cgo/gcc_libinit_windows.c:60: undefined reference to `__imp___iob_func'
c:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\user\AppData\Local\Temp\go-link-2621619269\000016.o: in function `x_cgo_notify_runtime_init_done':
c:\go\src\runtime\cgo/gcc_libinit_windows.c:101: undefined reference to `__imp___iob_func'
c:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\user\AppData\Local\Temp\go-link-2621619269\000017.o: in function `x_cgo_thread_start':
c:\go\src\runtime\cgo/gcc_util.c:18: undefined reference to `__imp___iob_func'
c:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\user\AppData\Local\Temp\go-link-2621619269\000018.o: in function `_cgo_sys_thread_start':
c:\go\src\runtime\cgo/gcc_windows_amd64.c:31: undefined reference to `__imp___iob_func'
collect2.exe: error: ld returned 1 exit status
@toothrot
Copy link
Contributor

toothrot commented Feb 4, 2022

Do you have a sample program that reproduces this issue?

@toothrot toothrot added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Feb 4, 2022
@NewUserHa
Copy link
Author

any code that causes go-sqlite3 to compile is enough.
maybe https://github.com/mattn/go-sqlite3/blob/master/_example/simple/simple.go, and the problem compiler is "GCC 11.2.0 + LLVM/Clang/LLD/LLDB 13.0.0 + MinGW-w64 9.0.0 (UCRT) - release 2" in that homepage within the original post

@bcmills
Copy link
Contributor

bcmills commented Feb 4, 2022

I haven't dug in too far, but I suspect that the problem here is skew between the precompiled runtime/cgo object file and the C compiler that you are using. (The C compiler we use to build the Go distribution is very old; see #35006.)

When we stop shipping precompiled object files (#47257) then version skew should no longer be an issue.

@NewUserHa, in the meantime you may be able to work around the problem by installing Go from source. Could you give that a try and post the results?

@NewUserHa
Copy link
Author

I don't have any toolchain for that except the only pre-build gcc compiler. so probably needs others to test

@bcmills
Copy link
Contributor

bcmills commented Feb 4, 2022

You shouldn't need much else on top of the gcc toolchain — just git to clone the Go repo, really.

@NewUserHa
Copy link
Author

NewUserHa commented Feb 4, 2022

Should follow which part of https://go.dev/doc/install/source? it says "There are two official Go compiler toolchains."

@NewUserHa
Copy link
Author

NewUserHa commented Feb 4, 2022

all.bat
Building Go cmd/dist using C:\Program Files\Go
Building Go toolchain1 using C:\Program Files\Go.
Building Go bootstrap cmd/go (go_bootstrap) using Go toolchain1.
Building Go toolchain2 using go_bootstrap and Go toolchain1.
Building Go toolchain3 using go_bootstrap and Go toolchain2.
Building packages and commands for windows/amd64.


##### Testing packages.
ok      archive/tar     0.852s
ok      archive/zip     0.967s
ok      bufio   0.395s
ok      bytes   0.626s
ok      compress/bzip2  0.499s
ok      compress/flate  1.465s
ok      compress/gzip   0.479s
ok      compress/lzw    0.419s
ok      compress/zlib   0.713s
ok      container/heap  0.406s
ok      container/list  0.362s
ok      container/ring  0.363s
ok      context 0.403s
ok      crypto  0.360s
ok      crypto/aes      0.438s
ok      crypto/cipher   0.455s
ok      crypto/des      0.381s
ok      crypto/dsa      0.389s
ok      crypto/ecdsa    0.473s
ok      crypto/ed25519  0.573s
ok      crypto/ed25519/internal/edwards25519    7.214s
ok      crypto/ed25519/internal/edwards25519/field      2.868s
ok      crypto/elliptic 0.486s
ok      crypto/elliptic/internal/fiat   0.364s
ok      crypto/hmac     0.340s
ok      crypto/internal/subtle  0.377s
ok      crypto/md5      0.321s
ok      crypto/rand     0.376s
ok      crypto/rc4      0.382s
ok      crypto/rsa      0.852s
ok      crypto/sha1     0.359s
ok      crypto/sha256   0.341s
ok      crypto/sha512   0.432s
ok      crypto/subtle   0.469s
ok      crypto/tls      2.519s
ok      crypto/x509     3.518s
ok      database/sql    1.244s
ok      database/sql/driver     0.400s
ok      debug/dwarf     0.651s
ok      debug/elf       0.597s
ok      debug/gosym     0.464s
ok      debug/macho     0.517s
--- FAIL: TestInternalLinkerDWARF (4.33s)
    file_test.go:389: building test executable for linktype 2 failed: exit status 2 # command-line-arguments
        c:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/lib/../lib/libmsvcrt.a(/697): duplicate symbol reference: fprintf in both libgcc(.text) and libgcc(.data)
        runtime/cgo(.text): relocation target __imp___acrt_iob_func not defined
        runtime/cgo(.text): relocation target __imp___acrt_iob_func not defined
        runtime/cgo(.text): relocation target __imp___acrt_iob_func not defined
FAIL
FAIL    debug/pe        23.802s
ok      debug/plan9obj  0.325s
ok      embed/internal/embedtest        0.353s
ok      encoding/ascii85        0.499s
ok      encoding/asn1   0.465s
ok      encoding/base32 0.439s
ok      encoding/base64 0.425s
ok      encoding/binary 0.455s
ok      encoding/csv    0.441s
ok      encoding/gob    0.649s
ok      encoding/hex    0.506s
ok      encoding/json   1.146s
ok      encoding/pem    0.599s
ok      encoding/xml    0.542s
ok      errors  0.516s
ok      expvar  0.596s
ok      flag    1.144s
ok      fmt     0.558s
ok      go/ast  0.528s
ok      go/build        11.913s
ok      go/build/constraint     0.399s
ok      go/constant     0.371s
ok      go/doc  1.566s
ok      go/format       0.464s
ok      go/importer     1.084s
ok      go/internal/gccgoimporter       0.919s
ok      go/internal/gcimporter  1.168s
ok      go/internal/srcimporter 19.412s
ok      go/parser       0.608s
ok      go/printer      1.036s
ok      go/scanner      0.377s
ok      go/token        0.918s
ok      go/types        8.574s
ok      hash    0.438s
ok      hash/adler32    0.364s
ok      hash/crc32      0.443s
ok      hash/crc64      0.348s
ok      hash/fnv        0.348s
ok      hash/maphash    0.559s
ok      html    0.418s
ok      html/template   0.822s
ok      image   0.720s
ok      image/color     0.372s
ok      image/draw      0.460s
ok      image/gif       1.995s
ok      image/jpeg      1.313s
ok      image/png       0.857s
ok      index/suffixarray       0.608s
ok      internal/abi    0.979s
ok      internal/cpu    0.374s
ok      internal/execabs        0.458s
ok      internal/fmtsort        0.378s
ok      internal/itoa   0.414s
ok      internal/poll   0.457s
ok      internal/profile        0.493s
ok      internal/reflectlite    0.614s
ok      internal/singleflight   0.382s
ok      internal/syscall/windows        0.616s
ok      internal/syscall/windows/registry       0.373s
ok      internal/trace  0.842s
ok      internal/unsafeheader   0.409s
ok      internal/xcoff  0.583s
ok      io      0.423s
ok      io/fs   0.383s
ok      io/ioutil       0.441s
ok      log     0.359s
ok      math    0.380s
ok      math/big        2.177s
ok      math/bits       0.487s
ok      math/cmplx      0.379s
ok      math/rand       0.723s
ok      mime    0.469s
ok      mime/multipart  0.728s
ok      mime/quotedprintable    0.502s
ok      net     11.028s
ok      net/http        17.491s
ok      net/http/cgi    2.778s
ok      net/http/cookiejar      1.272s
ok      net/http/fcgi   1.219s
ok      net/http/httptest       2.955s
ok      net/http/httptrace      0.486s
ok      net/http/httputil       1.683s
ok      net/http/internal       0.436s
ok      net/http/internal/ascii 0.411s
ok      net/http/pprof  5.961s
ok      net/internal/socktest   0.362s
ok      net/mail        0.397s
ok      net/rpc 0.782s
ok      net/rpc/jsonrpc 0.589s
ok      net/smtp        0.665s
ok      net/textproto   0.411s
ok      net/url 0.748s
ok      os      11.524s
# runtime/cgo.test
c:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/lib/../lib/libmsvcrt.a(/697): duplicate symbol reference: fprintf in both libgcc(.text) and libgcc(.data)
runtime/cgo(.text): relocation target __imp___acrt_iob_func not defined
runtime/cgo(.text): relocation target __imp___acrt_iob_func not defined
runtime/cgo(.text): relocation target __imp___acrt_iob_func not defined
ok      os/exec 26.003s
ok      os/signal       5.534s
ok      os/user 0.363s
ok      path    0.332s
ok      path/filepath   5.598s
ok      plugin  0.554s
ok      reflect 0.978s
ok      regexp  0.742s
ok      regexp/syntax   0.806s
ok      runtime 225.056s
FAIL    runtime/cgo [build failed]
ok      runtime/debug   0.488s
ok      runtime/internal/atomic 0.369s
ok      runtime/internal/math   0.634s
ok      runtime/internal/sys    0.369s
ok      runtime/metrics 0.349s
ok      runtime/pprof   18.631s
ok      runtime/trace   1.720s
ok      sort    0.404s
ok      strconv 0.782s
ok      strings 0.658s
ok      sync    2.788s
ok      sync/atomic     3.048s
ok      syscall 29.554s
ok      testing 2.061s
ok      testing/fstest  0.444s
ok      testing/iotest  0.408s
ok      testing/quick   0.471s
ok      text/scanner    0.445s
ok      text/tabwriter  0.450s
ok      text/template   0.883s
ok      text/template/parse     0.494s
ok      time    3.451s
ok      unicode 0.441s
ok      unicode/utf16   0.408s
ok      unicode/utf8    0.723s
ok      cmd/addr2line   17.369s
ok      cmd/api 28.216s
ok      cmd/asm/internal/asm    3.019s
ok      cmd/asm/internal/lex    0.524s
ok      cmd/compile/internal/dwarfgen   7.364s
ok      cmd/compile/internal/importer   3.238s
ok      cmd/compile/internal/ir 1.277s
ok      cmd/compile/internal/logopt     13.477s
ok      cmd/compile/internal/noder      0.664s
ok      cmd/compile/internal/ssa        0.880s
ok      cmd/compile/internal/ssagen     0.094s
ok      cmd/compile/internal/syntax     0.425s
ok      cmd/compile/internal/test       23.373s
ok      cmd/compile/internal/typecheck  1.999s
ok      cmd/compile/internal/types      0.152s
ok      cmd/compile/internal/types2     1.906s
ok      cmd/cover       10.132s
ok      cmd/doc 0.615s
ok      cmd/fix 38.606s
ok      cmd/go  147.079s
ok      cmd/go/internal/auth    0.171s
ok      cmd/go/internal/cache   0.954s
ok      cmd/go/internal/fsys    0.568s
ok      cmd/go/internal/generate        0.280s
ok      cmd/go/internal/get     0.423s
ok      cmd/go/internal/imports 0.520s
ok      cmd/go/internal/load    0.316s
ok      cmd/go/internal/lockedfile      0.865s
ok      cmd/go/internal/lockedfile/internal/filelock    0.768s
ok      cmd/go/internal/modconv 0.220s
ok      cmd/go/internal/modfetch        0.306s
ok      cmd/go/internal/modfetch/codehost       0.294s
ok      cmd/go/internal/modfetch/zip_sum_test   0.305s
ok      cmd/go/internal/modload 0.330s
ok      cmd/go/internal/mvs     0.240s
ok      cmd/go/internal/par     0.301s
ok      cmd/go/internal/search  0.269s
ok      cmd/go/internal/str     0.457s
ok      cmd/go/internal/test    0.404s
ok      cmd/go/internal/txtar   0.355s
ok      cmd/go/internal/vcs     0.712s
ok      cmd/go/internal/web     0.854s
ok      cmd/go/internal/work    0.503s
ok      cmd/gofmt       0.556s
ok      cmd/internal/archive    22.850s
ok      cmd/internal/buildid    0.636s
ok      cmd/internal/dwarf      0.522s
ok      cmd/internal/edit       0.549s
ok      cmd/internal/goobj      0.535s
ok      cmd/internal/moddeps    8.203s
ok      cmd/internal/obj        1.691s
ok      cmd/internal/obj/ppc64  2.910s
ok      cmd/internal/obj/riscv  3.074s
ok      cmd/internal/obj/s390x  0.624s
ok      cmd/internal/obj/x86    23.545s
ok      cmd/internal/objabi     0.621s
ok      cmd/internal/pkgpath    2.596s
ok      cmd/internal/src        0.911s
ok      cmd/internal/sys        0.375s
ok      cmd/internal/test2json  0.483s
ok      cmd/link        69.161s
ok      cmd/link/internal/benchmark     0.604s
--- FAIL: TestWindowsBuildmodeCSharedASLR (0.00s)
    --- FAIL: TestWindowsBuildmodeCSharedASLR/no-aslr (15.25s)
        ld_test.go:223: IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA flag should not be set
        ld_test.go:232: IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag should not be set
FAIL
FAIL    cmd/link/internal/ld    40.757s
ok      cmd/link/internal/loader        0.741s
--- FAIL: TestInternalLinkerCgoExec (29.84s)
    nm_test.go:121: building test executable failed: exit status 2 # command-line-arguments
        c:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/lib/../lib/libmsvcrt.a(/697): duplicate symbol reference: fprintf in both libgcc(.text) and libgcc(.data)
        runtime/cgo(.text): relocation target __imp___acrt_iob_func not defined
        runtime/cgo(.text): relocation target __imp___acrt_iob_func not defined
        runtime/cgo(.text): relocation target __imp___acrt_iob_func not defined
FAIL
FAIL    cmd/nm  39.402s
ok      cmd/objdump     41.741s
ok      cmd/pack        34.414s
ok      cmd/pprof       5.465s
ok      cmd/trace       0.691s
ok      cmd/vet 25.478s
FAIL
go tool dist: Failed: exit status 2

@bcmills
Copy link
Contributor

bcmills commented Feb 4, 2022

Thanks!

Perhaps not surprisingly, many of those test failures are the same tests (but with different failure modes) as what @thanm observed in #35006 (comment).

@bcmills
Copy link
Contributor

bcmills commented Feb 4, 2022

The failure mode for cmd/link/internal/ld.TestWindowsBuildmodeCSharedASLR is identical with both updated C toolchains.

The link errors in debug/pe.TestInternalLinkerDWARF, runtime/cgo.test, and cmd/nm.TestInternalLinkerCgoExec are different, but the correlation between those tests is a bit uncanny. 😅

@bcmills
Copy link
Contributor

bcmills commented Feb 4, 2022

Intriguingly, the string "__imp___acrt_iob_func" is hard-coded into the Go linker:
https://cs.opensource.google/go/go/+/master:src/cmd/link/internal/loadpe/ldpe.go;l=505;drc=69262d48717771cedb1da86563eb3f1b094b4e92

@NewUserHa
Copy link
Author

ok.
will that issue get fixed anytime soon?
will go support MSVC?

@bcmills
Copy link
Contributor

bcmills commented Feb 4, 2022

will that issue get fixed anytime soon?

No idea, but I would really like it to be fixed before Go 1.19 because I want to be able to test cgo build reproducibility on Windows. 😅

will go support MSVC?

That is tracked in #20982. It is currently milestoned Unplanned, so I would not expect it to happen unless a contributor outside the Go project steps up to implement it.

@NewUserHa
Copy link
Author

thanks.

@bcmills bcmills changed the title go-sqlite3: fail to build on windows with a few compiler cmd/link: cgo linking fails on Windows with GCC 11.2.0 + MinGW-w64 9.0.0 (UCRT) from winlibs.com Feb 4, 2022
@bcmills bcmills added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Windows and removed WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. labels Feb 4, 2022
@bcmills bcmills added this to the Unplanned milestone Feb 4, 2022
@thanm
Copy link
Contributor

thanm commented Feb 7, 2022

I have a CL that should (in theory) take care of this problem, https://go-review.googlesource.com/c/go/+/382837. When I get that stack checked in (other parts still need work) I'll be sure to test this scenario (winlib + gosqlite). Thanks.

@steowens
Copy link

steowens commented Dec 25, 2022

This message seems to happen in any program that uses featurs such as import "C" and import '

Here is a simple go file which will cause go build to fail with this error:

`
package main

import "C"
import (
	"log"
	"golang.org/x/sys/windows"
)

var hModule windows.Handle

func init() {
    err := windows.GetModuleHandleEx(0x01, nil, &hModule)
    if err != nil {
	    panic(err)
    }
}

func main() {
	log.Println("Hello")
}

`

go build

github.com/steowens/goWebview

C:\Program Files\Go\pkg\tool\windows_amd64\link.exe: running gcc failed: exit status 1
c:/program files/winlibs-x86_64-posix-seh-gcc-12.2.0-llvm-14.0.6-mingw-w64ucrt-10.0.0-r2/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\steve\AppData\Local\Temp\go-link-2891155275\000005.o: in function _cgo_preinit_init': \\_\_\runtime\cgo/gcc_libinit_windows.c:40: undefined reference to __imp___iob_func'
c:/program files/winlibs-x86_64-posix-seh-gcc-12.2.0-llvm-14.0.6-mingw-w64ucrt-10.0.0-r2/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\steve\AppData\Local\Temp\go-link-2891155275\000005.o: in function x_cgo_notify_runtime_init_done': \\_\_\runtime\cgo/gcc_libinit_windows.c:105: undefined reference to __imp___iob_func'
c:/program files/winlibs-x86_64-posix-seh-gcc-12.2.0-llvm-14.0.6-mingw-w64ucrt-10.0.0-r2/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\steve\AppData\Local\Temp\go-link-2891155275\000005.o: in function _cgo_beginthread': \\_\_\runtime\cgo/gcc_libinit_windows.c:149: undefined reference to __imp___iob_func'
c:/program files/winlibs-x86_64-posix-seh-gcc-12.2.0-llvm-14.0.6-mingw-w64ucrt-10.0.0-r2/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\steve\AppData\Local\Temp\go-link-2891155275\000006.o: in function x_cgo_thread_start': \\_\_\runtime\cgo/gcc_util.c:18: undefined reference to __imp___iob_func'
collect2.exe: error: ld returned 1 exit status

@thanm
Copy link
Contributor

thanm commented Dec 27, 2022

@steowens thanks for the note.

Much work has been done on the Go linker's windows host object loading phase since this issue was filed last February. Things are better now on Go tip (e.g. the version about to be released as Go 1.20). I tested your example by hand using Go 1.20 RC1 and these compilers from winlibs.com, and things work ok for me.

If you get a change, perhaps you can download the release candidate and try it yourself, see this email.

@thanm
Copy link
Contributor

thanm commented Jan 12, 2023

@AMDG2

Your compile/link recipe doesn't look right. In general for C++ programs it is not a viable strategy to invoke the linker directly -- one needs to invoke the C++ driver during the link stage, and then the C++ driver will run the linker passing the right flags and libraries.

Here is an example (linux machine):

thanm@cetina:~$ cat himom.cpp
#include <iostream>
int main(int argc, char **argv) {
  std::cout << "hi mom\n";
  return 0;
}
$ clang++ -c himom.cpp
$ ld.lld -o himom.exe himom.o 
ld.lld: error: undefined symbol: std::cout
ld.lld: error: undefined symbol: std::basic_ostream<char, std::char_traits<char> >& std::operator<<<std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
ld.lld: error: undefined symbol: std::ios_base::Init::Init()
...
$ clang++ -o himom.exe himom.o
$ ./himom.exe
hi mom

Try running the last command above with "-v" and you can see all of the various libraries being passed to the linker by the driver.

Also want to add that the use of MSVC (e.g. cl.exe, link.exe) is something that is not supported/test by the Go team at the moment; I would recommend instead sticking with mingw-based compilers and linkers.

@AMDG2
Copy link

AMDG2 commented Jan 12, 2023

@thanm Thank you for the quick reply! I tried to make it simpler, but you are right, we usually link through the compiler.

I changed my build script for this repro to build and link with the compiler in one step, and I also added building with GCC (I also fixed the Go code, so it actually prints the string instead of the address, but it does not matter).

new build.ps1
# This requires MSVC, go, tdm-gcc and clang in PATH.
Set-PSDebug -Trace 1

# Build the go static library
# Commented out, so the header changes don't get overriden.
cd golib
$env:GODEBUG="cgocheck=2"
go version
go build -buildmode=c-archive -o ../golib.lib .
cd ..

# Patch the header, otherwise both MSVC and Clang complains about the complex types.
Set-Content -Path "golib.h" -Value (get-content -Path "golib.h" | Select-String -Pattern '#include <complex.h>' -NotMatch)
Set-Content -Path "golib.h" -Value (get-content -Path "golib.h" | Select-String -Pattern 'typedef _Fcomplex GoComplex64;' -NotMatch)
Set-Content -Path "golib.h" -Value (get-content -Path "golib.h" | Select-String -Pattern 'typedef _Dcomplex GoComplex128;' -NotMatch)

# Build the C++ executable with MSVC
# ===========================================
# Generate object file.
cl.exe /MP /MD /EHsc  main.cpp /link golib.lib /out:main-msvc.exe
if ($?) { ./main-msvc.exe "MSVC" }

# Build the C++ executable with Clang
# ===========================================
# Generate object file.
clang-cl.exe --version
clang-cl.exe /MP /MD /EHsc  main.cpp /link golib.lib /out:main-clang.exe
if ($?) { ./main-clang.exe "Clang" }

# Build the C++ executable with GCC
# ===========================================
# Generate object file.
g++.exe --version
g++.exe main.cpp -lgolib -L. -o main-gcc.exe
if ($?) { ./main-gcc.exe "GCC" }

Set-PSDebug -Trace 0

I get the following output:

build.ps1 output
DEBUG:    6+  >>>> cd golib
DEBUG:    7+  >>>> $env:GODEBUG="cgocheck=2"
DEBUG:    8+  >>>> go version
go version go1.20rc2 windows/amd64
DEBUG:    9+  >>>> go build -buildmode=c-archive -o ../golib.lib .
DEBUG:   10+  >>>> cd ..
DEBUG:   13+  >>>> Set-Content -Path "golib.h" -Value (get-content -Path "golib.h" | Select-String -Pattern '#include <complex.h>' -NotMatch)
DEBUG:   14+  >>>> Set-Content -Path "golib.h" -Value (get-content -Path "golib.h" | Select-String -Pattern 'typedef _Fcomplex GoComplex64;' -NotMatch)
DEBUG:   15+  >>>> Set-Content -Path "golib.h" -Value (get-content -Path "golib.h" | Select-String -Pattern 'typedef _Dcomplex GoComplex128;' -NotMatch)
DEBUG:   20+  >>>> cl.exe /MP /MD /EHsc  main.cpp /link golib.lib /out:main-msvc.exe
Microsoft (R) C/C++ Optimizing Compiler Version 19.34.31933 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

main.cpp
Microsoft (R) Incremental Linker Version 14.34.31933.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:main.exe
golib.lib
/out:main-msvc.exe
main.obj
golib.lib(000005.o) : error LNK2019: unresolved external symbol __mingw_vfprintf referenced in function fprintf
golib.lib(000006.o) : error LNK2001: unresolved external symbol __mingw_vfprintf
main-msvc.exe : fatal error LNK1120: 1 unresolved externals
DEBUG:   21+ if ( >>>> $?) { ./main-msvc.exe "MSVC" }
DEBUG:   26+  >>>> clang-cl.exe --version
clang version 15.0.3
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Corona\tmp\conan-windows\.conan\data\llvm\15.0.3\legion\20221108\package\cc04f447872ac4d8c0f858193dd82ce97bad89bf\bin
DEBUG:   27+  >>>> clang-cl.exe /MP /MD /EHsc  main.cpp /link golib.lib /out:main-clang.exe
clang-cl: warning: argument unused during compilation: '/MP' [-Wunused-command-line-argument]
golib.lib(000005.o) : error LNK2019: unresolved external symbol __mingw_vfprintf referenced in function fprintf
golib.lib(000006.o) : error LNK2001: unresolved external symbol __mingw_vfprintf
main-clang.exe : fatal error LNK1120: 1 unresolved externals
clang-cl: error: linker command failed with exit code 1120 (use -v to see invocation)
DEBUG:   28+ if ( >>>> $?) { ./main-clang.exe "Clang" }
DEBUG:   33+  >>>> g++.exe --version
g++.exe (tdm64-1) 10.3.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

DEBUG:   34+  >>>> g++.exe main.cpp -lgolib -L. -o main-gcc.exe
DEBUG:   35+ if ( >>>> $?) { ./main-gcc.exe "GCC" }
DEBUG:   35+ if ($?) {  >>>> ./main-gcc.exe "GCC" }
Hello GCC
DEBUG:   37+  >>>> Set-PSDebug -Trace 0

So, it still does not work with MSVC and Clang, but it works with GCC as one would expect. Is there any plan to extend the support to at least Clang & LLVM toolchain, if not MSVC?

@thanm
Copy link
Contributor

thanm commented Jan 12, 2023

@AMDG2 you are using clang-cl.exe, which is the MSVC-compatible version of clang. Please use a mingw-based version of clang (such as https://github.com/mstorsjo/llvm-mingw)

chris-olszewski added a commit to vercel/turbo that referenced this issue Sep 22, 2023
### Description

Due to the latest `windows-2022` runner image no longer including a
"built from source" Go binary, we're running into
golang/go#51007

Luckily as of `1.20` Go is no longer shipping these precompiled object
files so we will hopefully not run into the issues.

### Testing Instructions

CI


Closes TURBO-1344

---------

Co-authored-by: Chris Olszewski <Chris Olszewski>
assafmo added a commit to scrtlabs/SecretNetwork that referenced this issue Oct 5, 2023
This might also fix the CLI build for Windows: golang/go#51007
hajimehoshi added a commit to hajimehoshi/hitsumabushi that referenced this issue Oct 6, 2023
…y changes

Apparently issues with stdio was fixed in Go 1.20. See golang/go#51007
hajimehoshi added a commit to hajimehoshi/hitsumabushi that referenced this issue Oct 6, 2023
…y changes

Apparently issues with stdio was fixed in Go 1.20. See golang/go#51007
hajimehoshi added a commit to hajimehoshi/hitsumabushi that referenced this issue Oct 6, 2023
…y changes

Apparently issues with stdio was fixed in Go 1.20. See golang/go#51007
hajimehoshi added a commit to hajimehoshi/hitsumabushi that referenced this issue Oct 6, 2023
…y changes

Apparently issues with stdio was fixed in Go 1.20. See golang/go#51007
jbowens added a commit to jbowens/pebble that referenced this issue Oct 16, 2023
This commit updates the Windows CI job to use Go 1.19 instead of Go 1.18.

See golang/go#51007.
jbowens added a commit to jbowens/pebble that referenced this issue Oct 16, 2023
This commit updates the Windows CI job to use Go 1.20 instead of Go 1.18.

See golang/go#51007.
bradfitz added a commit to perkeep/perkeep that referenced this issue Dec 30, 2023
This also makes Windows pass tests again (fixed in Go 1.20:
golang/go#51007)

Signed-off-by: Brad Fitzpatrick <brad@danga.com>
bradfitz added a commit to perkeep/perkeep that referenced this issue Dec 31, 2023
This also makes Windows pass tests again (fixed in Go 1.20:
golang/go#51007)

Signed-off-by: Brad Fitzpatrick <brad@danga.com>
@golang golang locked and limited conversation to collaborators Jan 12, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Windows
Projects
None yet
Development

No branches or pull requests

12 participants