Closed
Description
What version of Go are you using (go version
)?
go version go1.10.3 darwin/amd64
Does this issue reproduce with the latest release?
Unfortunately, yes.
What operating system and processor architecture are you using (go env
)?
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/jpap/Library/Caches/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/jpap/go"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.10.3/libexec"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.10.3/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/f8/2x23x3n92nb_mjyj10v_ssph0000gn/T/go-build284257526=/tmp/go-build -gno-record-gcc-switches -fno-common"
What did you do?
- Create the following files in
$GOPATH/src/github.com/exporttest
,
lib/lib.go
lib+main.go
having contents:
// lib/lib.go
package lib
import (
"C"
"fmt"
)
//export ExportedFromLib
func ExportedFromLib() {
fmt.Println("ExportedFromLib")
}
func init() {
fmt.Println("lib.init")
}
// lib+main.go
package main
import (
"C"
"fmt"
_ "github.com/exporttest/lib"
)
//export ExportedFromMain
func ExportedFromMain() {
fmt.Println("ExportedFromMain")
}
func main() {
// Empty, but required for buildmode=c-shared
}
-
Run
go build -buildmode=c-archive -o libtest.a lib+main.go
-
Observe that in the header file
libtest.h
,ExportedFromMain
is included, butExportedFromLib
is not.
What did you expect to see?
- Both exported functions
ExportedFromLib
andExportedFromMain
should be exported.
What did you see instead?
ExportedFromLib
was not exported in the header file, but it is exported in the generated static library, as the following sample C code shows:
// test.c
#include "libtest.h"
#include <stdio.h>
// Declared here as it does not exist in generated libtest.h
extern void ExportedFromLib();
int main() {
ExportedFromLib();
return 0;
}
- C call to static library executes the exported function
ExportedFromLib
that does not appear in the header file.
$ gcc -o test test.c -L. -ltest
$ ./test
lib.init
ExportedFromLib
$
Activity
[-]Generated header for buildmode=c-archive lacks exported symbols for imported library[/-][+]cmd/cgo: generated header for buildmode=c-archive lacks exported symbols for imported library[/+]ianlancetaylor commentedon Aug 22, 2018
Yes, that is how it works. The expectation is that your c-archive will only export functions from the main package, just as is done with a normal Go package.
The fact that a symbol marked with
//export
in some other package winds up being visible in the c-archive is more or less a bug.Closing as working as expected.