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: ld: symbol(s) not found for architecture x86_64 #31409

Closed
nitishsaboo opened this issue Apr 11, 2019 · 11 comments

Comments

@nitishsaboo
Copy link

commented Apr 11, 2019

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

$ go version
go version go1.12.1 darwin/amd64

Does this issue reproduce with the latest release?

Not Sure

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

go env Output
$ go env
GOARCH="amd64"
GOBIN="/Users/nitish.saboo/Documents/goworkspace/bin"
GOCACHE="/Users/nitish.saboo/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/nitish.saboo/Documents/goworkspace/"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
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 -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/3n/gnx8m6wx6zndptdxj3z3n61mfnyqn2/T/go-build510179167=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

greeter.c

#include "greeter.h"
#include <stdio.h>

void greet(const char *name, int year) {

    printf("Greetings, %s from %d! We come in peace :)", name, year);

}

greeter.h

#ifndef _GREETER_H
#define _GREETER_H

void greet(const char *name, int year);
#endif

maing.go

package main

// #cgo CFLAGS: -g -Wall
// #include <stdlib.h>
// #include "greeter.h"
import "C"
import (
	"unsafe"
)

func main() {
	name := C.CString("Gopher")
	defer C.free(unsafe.Pointer(name))

	year := C.int(2018)

	C.greet(name, year)

}

What did you expect to see?

I thought the code would build succesfully

What did you see instead?

command-line-arguments

Undefined symbols for architecture x86_64:
"_greet", referenced from:
__cgo_d6ff402930ca_Cfunc_greet in _x002.o
(maybe you meant: __cgo_d6ff402930ca_Cfunc_greet)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

@nitishsaboo

This comment has been minimized.

Copy link
Author

commented Apr 11, 2019

@ianlancetaylor @bcmills Can you please help me on this ?

@nitishsaboo

This comment has been minimized.

Copy link
Author

commented Apr 11, 2019

@bradfitz can I get help on this ?

@nitishsaboo

This comment has been minimized.

Copy link
Author

commented Apr 11, 2019

clang --version
Apple LLVM version 10.0.1 (clang-1001.0.46.3)
Target: x86_64-apple-darwin18.2.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

@bradfitz

This comment has been minimized.

Copy link
Member

commented Apr 11, 2019

@nitishsaboo, you gave this only 8 hours before you started pinging everybody. Please be patient. Especially because your bug report looks more like a question (perhaps better suited to golang-nuts@ or another https://golang.org/wiki/Questions forum) than a bug report.

@bcmills

This comment has been minimized.

Copy link
Member

commented Apr 11, 2019

I can't reproduce the failure (on Linux with a much older clang).

example.com$ cat >./main.go <<EOF
package main

// #cgo CFLAGS: -g -Wall
// #include <stdlib.h>
// #include "greeter.h"
import "C"
import (
 "unsafe"
)

func main() {
 name := C.CString("Gopher")
 defer C.free(unsafe.Pointer(name))

 year := C.int(2018)

 C.greet(name, year)

}
EOF

example.com$ cat >./greeter.h <<EOF
#ifndef _GREETER_H
#define _GREETER_H

void greet(const char *name, int year);
#endif
EOF

example.com$ cat >./greeter.c <<EOF
#include "greeter.h"
#include <stdio.h>

void greet(const char *name, int year) {
    printf("Greetings, %s from %d! We come in peace :)\n", name, year);
}
EOF

example.com$ cat >./go.mod <<EOF
module example.com

go 1.12
EOF

example.com$ $(go env CC) --version
clang version 4.0.1-10 (tags/RELEASE_401/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

example.com$ go1.12.3 build -o greeter

example.com$ ./greeter
Greetings, Gopher from 2018! We come in peace :)

example.com$

Often with issues on MacOS we find that the problem is some issue with either a bad XCode installation or some additional (interfering) C toolchain installed somewhere in $PATH. It seems likely to be a problem with your C compiler, although a problem in cgo's use of the compiler isn't impossible.

As a diagnostic step, could you try setting CC explicitly in your environment?

You could also try running go clean -cache; go build -x, then running each of the steps individually and checking for errors in the resulting artifacts.

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Apr 11, 2019

If that doesn't help show us the complete output of go build -x.

@nitishsaboo

This comment has been minimized.

Copy link
Author

commented Apr 12, 2019

I did not make any changes to CC environment variable.
I ran 'go clean -cache' and then 'go build -x'.It generated 'greetings'.
./greetings
Greetings, Gopher from 2018! We come in peace :)90-F0QJJG5M-3R0:greetings nitish.saboo

How did it work this time ?

Output of go build -x

WORK=/var/folders/3n/gnx8m6wx6zndptdxj3z3n61mfnyqn2/T/go-build101211381
mkdir -p $WORK/b001/
cat >$WORK/b001/importcfg.link << 'EOF' # internal
packagefile greetings=/Users/nitish.saboo/Library/Caches/go-build/97/97b03eb447b772cd798d9b3856252b4d5768a05ee3820bef291d484eb5d9f582-d
packagefile runtime/cgo=/usr/local/go/pkg/darwin_amd64/runtime/cgo.a
packagefile syscall=/usr/local/go/pkg/darwin_amd64/syscall.a
packagefile runtime=/usr/local/go/pkg/darwin_amd64/runtime.a
packagefile errors=/usr/local/go/pkg/darwin_amd64/errors.a
packagefile internal/race=/usr/local/go/pkg/darwin_amd64/internal/race.a
packagefile sync=/usr/local/go/pkg/darwin_amd64/sync.a
packagefile internal/bytealg=/usr/local/go/pkg/darwin_amd64/internal/bytealg.a
packagefile internal/cpu=/usr/local/go/pkg/darwin_amd64/internal/cpu.a
packagefile runtime/internal/atomic=/usr/local/go/pkg/darwin_amd64/runtime/internal/atomic.a
packagefile runtime/internal/math=/usr/local/go/pkg/darwin_amd64/runtime/internal/math.a
packagefile runtime/internal/sys=/usr/local/go/pkg/darwin_amd64/runtime/internal/sys.a
packagefile sync/atomic=/usr/local/go/pkg/darwin_amd64/sync/atomic.a
EOF
mkdir -p $WORK/b001/exe/
cd .
/usr/local/go/pkg/tool/darwin_amd64/link -o $WORK/b001/exe/a.out -importcfg $WORK/b001/importcfg.link -buildmode=exe -buildid=nCIAoLwR6blAM0b35qOA/0L87jRCIU8h8q-J6CJt0/NrO_ik_2-gUxsOVCuIwi/nCIAoLwR6blAM0b35qOA -extld=clang /Users/nitish.saboo/Library/Caches/go-build/97/97b03eb447b772cd798d9b3856252b4d5768a05ee3820bef291d484eb5d9f582-d
/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/exe/a.out # internal
mv $WORK/b001/exe/a.out greetings
rm -r $WORK/b001/

But,
Output of go build maing.go

command-line-arguments

Undefined symbols for architecture x86_64:
"_greet", referenced from:
__cgo_d6ff402930ca_Cfunc_greet in _x002.o
(maybe you meant: __cgo_d6ff402930ca_Cfunc_greet)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

go build succeeds whereas go build main.go fails. Am i missing something here ?

@bcmills

This comment has been minimized.

Copy link
Member

commented Apr 12, 2019

go build succeeds whereas go build main.go fails. Am i missing something here ?

go build without further arguments builds the entire package in the current directory, including all Go and C source files.

go build main.go builds only the file main.go, as if that file is the entire Go package. (Search for “If the arguments are a list of .go files” in https://golang.org/cmd/go/#hdr-Compile_packages_and_dependencies.)

In the context of a cgo build, go build main.go would assume that all of the necessary C libraries are already compiled and installed (and presumably specified using a // #cgo LDFLAGS: -lfoo comment or similar). So if that's the difference you observed, then it sounds like everything is working as documented.

@bcmills bcmills closed this Apr 12, 2019

@nitishsaboo

This comment has been minimized.

Copy link
Author

commented Apr 12, 2019

@bcmills Thanks for the clarification.So if my C libraries are not compiled and I use 'go build' to build the program and it generates a file(like greetings in above case), does it mean that I have no issues on MacOS with respect to environment and C compiler ?
The reason I am asking this is because I have a different project where I am facing the same issue 'Undefined symbols for architecture x86_64:...'

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Apr 12, 2019

does it mean that I have no issues on MacOS with respect to environment and C compiler ?

Probably yes. Your problems more likely have something to do with how the program is being built.

@Arshiamidos

This comment has been minimized.

Copy link

commented Aug 5, 2019

i my case i put declartion of function in greeter.c file into greeter.h and it worked!

#ifndef _GREETER_H
#define _GREETER_H
int greet(const char *name, int year, char *out) {
    int n;
    n = sprintf(out, "Greetings, %s from %d! We come in peace :)", name, year);

    return n;
}
#endif

something like that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.