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/cgo: cgo + static const int results in "undefined reference" on linux #40820

Open
p8a opened this issue Aug 16, 2020 · 5 comments
Open

cmd/cgo: cgo + static const int results in "undefined reference" on linux #40820

p8a opened this issue Aug 16, 2020 · 5 comments

Comments

@p8a
Copy link

@p8a p8a commented Aug 16, 2020

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

$ go version
go version go1.14.7 linux/amd64

Does this issue reproduce with the latest release?

Have not tried

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

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
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 -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build954734301=/tmp/go-build -gno-record-gcc-switches"
root@06ba4e8d3414:/go/src/bitbucket.org/threattrack/vipre-mac/foo#

What did you do?

Linking of a program referring to static const int fails with undefined reference:

foo.h

static const int BAR = 1;

foo.go

package main

/*
#include "foo.h"
*/
import "C"
import "fmt"

const (
  BAR = int(C.BAR)
)

func main() {
  fmt.Println(BAR)
}

What did you expect to see?

Compilation succeeds on linux as it does on darwin

What did you see instead?

go build
/usr/bin/ld: $WORK/b001/_cgo_main.o:/tmp/go-build/cgo-generated-wrappers:2: undefined reference to `BAR'
collect2: error: ld returned 1 exit status
@AlexRouSg
Copy link
Contributor

@AlexRouSg AlexRouSg commented Aug 16, 2020

This seemed to be working at 1.10.8 and stopped working since 1.11

cc @ianlancetaylor

@cherrymui
Copy link
Contributor

@cherrymui cherrymui commented Aug 16, 2020

static in C means it is local to the its compilation unit. Arguably C and Go are different compilation units (and we do compile them separately).

@p8a
Copy link
Author

@p8a p8a commented Aug 17, 2020

@cherrymui in this case what would be the recommended way to keep the Go consts in sync with their C counterparts - outside of redefining them which will be a maintenance nightmare ?

This code also compiles and works on darwin with no issues.

@ianlancetaylor ianlancetaylor changed the title cgo + static const int results in "undefined reference" on linux cmd/cgo: cgo + static const int results in "undefined reference" on linux Aug 17, 2020
@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Aug 17, 2020

I think this is also mentioned in #39136.

One difference is that GCC emits a DW_AT_location for BAR where clang emits a DW_AT_const_value. Another difference is that when compiling this:

static const int BAR = 1;
enum { V = (BAR) * 1 };

clang compiles the code without error but GCC reports

foo.c:2:8: error: enumerator value for ‘V’ is not an integer constant

I'm not sure why clang doesn't give an error in that case. clang's behavior seems correct for C++ but not for C.

Note that using #define should work for both compilers.

@AlexRouSg
Copy link
Contributor

@AlexRouSg AlexRouSg commented Aug 18, 2020

I found the commit that broke it, da76981

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.