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/go: linking a binary compiled with gccgo #7303

Closed
mwhudson opened this issue Feb 11, 2014 · 4 comments
Closed

cmd/go: linking a binary compiled with gccgo #7303

mwhudson opened this issue Feb 11, 2014 · 4 comments

Comments

@mwhudson
Copy link
Contributor

What steps will reproduce the problem?
If possible, include a link to a program on play.golang.org.
1. You need a package that depends on a library which is not installed, e.g. (in
$GOPATH):

(trusty-amd64)mwhudson@narsil:juju-core-1.17.2$ cat src/dep/dep.go 
package dep

func Dep () {
    println("hello")
}
(trusty-amd64)mwhudson@narsil:juju-core-1.17.2$ cat src/bin/bin.go 
package main

import ("dep")

func main () {
    dep.Dep()
}

2. Try to install it with -compiler gccgo ("go install -compiler gccgo bin")

What is the expected output?

Nothing, and a binary appears in ./bin.

What do you see instead?

(trusty-amd64)mwhudson@narsil:juju-core-1.17.2$ go install -compiler gccgo bin
# bin
gccgo: error: $WORK/libdep.a: No such file or directory

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

gccgo

Which operating system are you using?

Ubuntu Trusty

Which version are you using?  (run 'go version')

go version devel +7abe32ccffb1 Wed Jan 22 15:55:56 2014 -0800 linux/amd64

Please provide any additional information below.

You can make it work by passing -work, which makes me very much suspect these lines in
build.go:

http://code.google.com/p/go/source/browse/src/cmd/go/build.go#1013
@mwhudson
Copy link
Contributor Author

Comment 1:

Eh, that "additional information" comment is a bit wrong headed.  I'll post something
that makes sense tomorrow :-)

@davecheney
Copy link
Contributor

Comment 2:

Can you do the same with 
go install -x -compiler gccgo bin
As you rightly suspect, the final binary is probably not being copied out of the
temporary build director.

Labels changed: added release-none, repo-gccgo.

Status changed to WaitingForReply.

@mwhudson
Copy link
Contributor Author

Comment 3:

Yes, that would have been useful, wouldn't it?
(trusty-amd64)mwhudson@narsil:juju-core-1.17.2$ ~/go/bin/go install -compiler gccgo -x
bin
WORK=/tmp/go-build895530139
mkdir -p $WORK/dep/_obj/
mkdir -p $WORK/
cd /home/mwhudson/src/juju-core-1.17.2/src/dep
gccgo -I $WORK -c -g -m64 -fgo-pkgpath=dep
-fgo-relative-import-path=_/home/mwhudson/src/juju-core-1.17.2/src/dep -o
$WORK/dep/_obj/dep.o ./dep.go
ar cru $WORK/libdep.a $WORK/dep/_obj/dep.o
mkdir -p /home/mwhudson/src/juju-core-1.17.2/pkg/gccgo_linux_amd64/
cp $WORK/libdep.a /home/mwhudson/src/juju-core-1.17.2/pkg/gccgo_linux_amd64/libdep.a
mkdir -p $WORK/bin/_obj/
mkdir -p $WORK/bin/_obj/exe/
cd /home/mwhudson/src/juju-core-1.17.2/src/bin
gccgo -I $WORK -I /home/mwhudson/src/juju-core-1.17.2/pkg/gccgo_linux_amd64 -c -g -m64
-fgo-relative-import-path=_/home/mwhudson/src/juju-core-1.17.2/src/bin -o
$WORK/bin/_obj/main.o ./bin.go
ar cru $WORK/libbin.a $WORK/bin/_obj/main.o
cd .
gccgo -o $WORK/bin/_obj/exe/a.out $WORK/bin/_obj/main.o -Wl,-( -m64 $WORK/libdep.a
/home/mwhudson/src/juju-core-1.17.2/pkg/gccgo_linux_amd64/libdep.a -Wl,-)
# bin
gccgo: error: $WORK/libdep.a: No such file or directory
So it's not that the file doesn't get copied out of the working directory, or even that
the installed file is not passed to the link command, it's that the now-deleted
temporary location is _also_ passed to the link command.  This is because the target of
all actions is passed to the link command, even when there is a build and an install
action for the same library.  This complete hack:
diff -r 16f0b6d4f8ff src/cmd/go/build.go
--- a/src/cmd/go/build.go       Tue Feb 11 09:34:43 2014 +0100
+++ b/src/cmd/go/build.go       Wed Feb 12 09:04:54 2014 +1300
@@ -1013,6 +1013,7 @@
        if !buildWork {
                defer os.RemoveAll(a1.objdir)
                defer os.Remove(a1.target)
+               defer func () { a1.target = a.target }()
        }
 
        if a.p.usesSwig() {
makes things work but doesn't really seem like the right fix.  I don't know if there is
a way to tell from an  "building" action object if it is followed by an "installation"
action object or if a way needs to be added or ... something else.  BTW, I think this
would fail even with -work if /tmp was on the same file system as GOPATH because then
the .a file would be moved, not copied...

@rsc
Copy link
Contributor

rsc commented Mar 13, 2014

Comment 4:

This issue was closed by revision 12474d0.

Status changed to Fixed.

@golang golang locked and limited conversation to collaborators Jun 25, 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

4 participants