golang / go

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

doc: explain when to use -ldflags=-extar when cross-compiling #45395

Open mewalig opened 3 years ago

mewalig commented 3 years ago

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

go version go1.16.3 darwin/amd64

Does this issue reproduce with the latest release?

Yes

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

darwin + amd64

What did you do?

I am compiling Go into a static archive to be called with C code. It works when I compile for the native platform. It does not work when I try to cross-compile for Windows using mingw64

Works:

No errors or warnings:

Fails:

What did you expect to see?

No error message, and test.exe file created

What did you see instead?

Error message

ianlancetaylor commented 3 years ago

Can you show us the code that you are trying to build?

mewalig commented 3 years ago

Here's a simple example that has the same problem (at least for me).

test.go:

package main

// #include <stdlib.h>
import "C"

import (
    "fmt"
    "os"
    "unsafe"
)

//export myExportedFunction
func myExportedFunction(c_str *C.char) C.int {
    fmt.Println("hi")
    return 0
}

func main() {
    if len(os.Args) < 2 {
        println("Usage: test <any_string>\n")
    } else {
        arg1 := os.Args[1]
        arg1_c := C.CString(arg1)
        defer C.free(unsafe.Pointer(arg1_c))
        myExportedFunction(arg1_c)
    }
}

test.c:

#include "test.h"

int main(int argc, char **argv) {
  if(argc > 1)
    myExportedFunction(argv[1]);
  return 0;
}
ianlancetaylor commented 3 years ago

What happens if you use go build -buildmode=c-archive -ldflags=-extar=x86_64-w64-mingw32-ar ... ? (Keep all the environment variable setting also, just add the -ldflags=-extar flag.)

mewalig commented 3 years ago

That worked. You are the man! Thank you.

BTW: is there documentation that describes this necessary step, which I missed? In case it answers any other future questions/issues I might otherwise run into

ianlancetaylor commented 3 years ago

I'm going to reopen this to get better documentation.

We should also consider supporting an AR environment variable.

AlexRouSg commented 3 years ago

We should also consider supporting an AR environment variable.

There appears to already be an AR env var? https://github.com/golang/go/blob/4c1a7ab49c4c68907bc7f7f7f776edd9116584a5/src/cmd/go/internal/envcmd/env.go#L112

Looks like it might just be a few lines change to get ld to use the AR env https://github.com/golang/go/blob/972e8839254d59dc04a1193c4c9633a74595a2e7/src/cmd/link/internal/ld/lib.go#L1218