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: link error on OS X (unsupported scattered relocation) #3253

Closed
gopherbot opened this issue Mar 8, 2012 · 19 comments
Closed

cmd/cgo: link error on OS X (unsupported scattered relocation) #3253

gopherbot opened this issue Mar 8, 2012 · 19 comments

Comments

@gopherbot
Copy link

by ranveerkunal:

What steps will reproduce the problem?
I am trying to use:
https://github.com/nsf/termbox-go

but when I do go build on the code I get link errors.

Little Details:
Code:
############################################
package main

import(
       "log"

       termbox "github.com/nsf/termbox-go"
)

func main() {
       err := termbox.Init()
       if err != nil {
               log.Fatalf("termbox.Init() failed: %v", err)
       }
       defer termbox.Shutdown()
       log.Printf("termbox.Init() success")
}

############################################

Error:
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(input.o)(__TEXT/__text): keys: not defined
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(input.o)(__TEXT/__text): keys: not defined
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(term.o)(__TEXT/__text): keys: not defined
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(term.o)(__TEXT/__text): funcs: not defined
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(term.o)(__TEXT/__text): keys: not defined
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(term.o)(__TEXT/__text): funcs: not defined
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(term.o)(__TEXT/__text): keys: not defined
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(term.o)(__TEXT/__text): keys: not defined
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(term.o)(__TEXT/__text): keys: not defined
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(term.o)(__TEXT/__text): keys: not defined
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(term.o)(__TEXT/__text): keys: not defined
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(term.o)(__TEXT/__text): funcs: not defined
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(termbox.o)(__TEXT/__text): funcs: not defined
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(termbox.o)(__TEXT/__text): funcs: not defined
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(termbox.o)(__TEXT/__text): funcs: not defined
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(termbox.o)(__TEXT/__text): funcs: not defined
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(termbox.o)(__TEXT/__text): funcs: not defined
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(termbox.o)(__TEXT/__text): funcs: not defined
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(termbox.o)(__TEXT/__text): funcs: not defined
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(termbox.o)(__TEXT/__text): funcs: not defined
/Users/ranveer/gocode/pkg/darwin_amd64/github.com/nsf/termbox-
go.a(termbox.o)(__TEXT/__text): funcs: not defined
too many errors

What is the expected output?
Should compile.

What do you see instead?
Linking errors

Which compiler are you using (5g, 6g, 8g, gccgo)?


Which operating system are you using?
MacOsx

Which revision are you using?  (hg identify)
a45cc1950c26 tip

Please provide any additional information below.
@rsc
Copy link
Contributor

rsc commented Mar 9, 2012

Comment 1:

Marking this Priority-Go1 for now, but more a hope than a promise.

Labels changed: added priority-go1, removed priority-triage.

Owner changed to builder@golang.org.

Status changed to Accepted.

@cookieo9
Copy link
Contributor

cookieo9 commented Mar 9, 2012

Comment 2:

It also happens for me on 10.6 386 (latest tip: 885465912b99). It looks to be an issue
with extern pointers, in the simple example I have provided, an extern int works fine,
but an extern *int doesn't.
I'm fairly certain this only happens when ld is trying to link gcc compiled code
statically, since we would have run into this problem with most cgo libraries otherwise.
I think this issue is relatively high priority since it seems to affect all darwin
builds, and makes providing custom C-code to packages (that can be built trivially with
the go tool) a potential minefield for portability.

Attachments:

  1. foo.zip (1562 bytes)

@nsf
Copy link

nsf commented Mar 11, 2012

Comment 3:

I'm the author of that termbox library btw. Just tried to make it work on MacOSX and
succeeded (thanks goes to LeNsTR for providing me with ssh access to his Mac machine).
It seems that adding "-fno-common" flag to cgo gcc files (when compiling, not linking)
does the job.
The reason why it works is a mistery to me.

@cookieo9
Copy link
Contributor

Comment 4:

-fno-common affects the placement and initialization of global variables (see:
http://gcc.gnu.org/onlinedocs/gcc-4.6.3/gcc/Code-Gen-Options.html). There seems to be
some bug in the 8l/6l linkers WRT mach-o files when statically linking files compiled
with -fcommon (the default option).
Unfortunately using "CGO_CFLAGS=-fno-common" doesn't solve the solution for me though,
because for the above code, and in my own sample I now get:
malformed mach-o file: unsupported scattered relocation 2/1
Which is an error similar to when I try to link to objective-c code (to interact with
OSX) this is a known problem with go in Snow Leopard on 386 (the last version of OSX to
support 386).
Although the above problem (failing to link on Lion) could be solved by adding
-fno-common to the link flags for all gcc compile tasks, this may result in trading one
set of uncompilable code for another.

@nsf
Copy link

nsf commented Mar 11, 2012

Comment 5:

Oh, I see. Well, I guess this bug requires Go linker changes then.

@cookieo9
Copy link
Contributor

Comment 6:

To solve the specific issue of building your package on Lion (and most likely amd64
Darwin as well) -fno-common will work, and the user just has to build the code with:
$ CGO_LDFLAGS="-fno-common" go install
Which you can put in your README.
I was able to solve the problem completely (no build errors) by moving all the code into
a single *.c file and changing the 2 globals in question to be static instead of extern.
But this would problably be unfeasible for most projects.

@gopherbot
Copy link
Author

Comment 7 by ranveerkunal:

Thanks for the temp solution. I can move the development back to mac.

@nsf
Copy link

nsf commented Mar 14, 2012

Comment 8:

Since this library (termbox) is part of the issue. I want to leave a note here, that
I've rewritten the library. It doesn't use cgo anymore, it's 100% Go now. Although there
are still few problem with mac (missing syscall.Termios). But I'll fix them soon.

@minux
Copy link
Member

minux commented Mar 14, 2012

Comment 9:

I think -fno-common should always be used on Mac OS X. Any opinions?

@cookieo9
Copy link
Contributor

Comment 10:

That is probably the fastest solution, since the ammount of code it will break will
probably be minimal, as it should only affect a small subset of GCC compiled Go files.
There's still the situation that it leads to unsupported scattered relocation code which
is a problem for the darwin/386 linker (not a Lion issue), and has no solution apart
from code-rewrite.
I think it might be good that this be documented somewhere because no matter how you
solve it, short of fixing the linker, a package developer needs to know what they can
try to do to solve the problem.
Also, I see a better way to pass the flag than my earlier use of environment variables,
use a cgo directive:
// #cgo: darwin CFLAGS: -fno-common
This way it requires no action on the part of users, and can be specified on a per-file
basis if necessary.

@minux
Copy link
Member

minux commented Mar 14, 2012

Comment 11:

Oh, I think this flag should be the default in cmd/go. I will propose a CL for this
change.

@rsc
Copy link
Contributor

rsc commented Mar 15, 2012

Comment 12:

http://golang.org/cl/5822050/

Status changed to Started.

@minux
Copy link
Member

minux commented Mar 17, 2012

Comment 13:

Should this issue be considered fixed?

@rsc
Copy link
Contributor

rsc commented Mar 26, 2012

Comment 14:

You said we still needed scattered relocations?
If they are done, sure, mark it fixed.

@rsc
Copy link
Contributor

rsc commented Mar 26, 2012

Comment 15:

If this is fixed, great.  If this is not fixed, it will have to wait until after Go 1.
It is too late to be making linker changes.

Labels changed: added priority-later, removed priority-go1.

@minux
Copy link
Member

minux commented Apr 20, 2012

Comment 16:

A test case for "unsupported scattered relocation 2/1" on Darwin/386:
package main
/*
int hola = 0;
int testHola() { return hola; }
*/
import "C"
func main() { println(C.hola, C.testHola()) }

@minux
Copy link
Member

minux commented Aug 24, 2012

Comment 17:

Status changed to Duplicate.

Merged into issue #1635.

@minux
Copy link
Member

minux commented Aug 29, 2012

Comment 18:

I reopened this bug, because fix for issue #1635 (rev bb2316abeea5) doesn't fix this
issue on Mac OS X 10.7
http://build.golang.org/log/08f42de48d3118cc017a1bedd8daabca32ba318f

Status changed to Accepted.

@minux
Copy link
Member

minux commented Sep 1, 2012

Comment 19:

the build failure mentioned in last comment turns out unrelated to this (ld unable to
handle zero filled sections, see CL 6492069)
this issue is (already) fixed.

Status changed to Fixed.

@golang golang locked and limited conversation to collaborators Jun 24, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants