cmd/compile: add -dolinkobj flag

When set to false, the -dolinkobj flag instructs the compiler
not to generate or emit linker information.

This is handy when you need the compiler's export data,
e.g. for use with go/importer,
but you want to avoid the cost of full compilation.

This must be used with care, since the resulting
files are unusable for linking.

This CL interacts with #18369,
where adding gcflags and ldflags to buildid has been mooted.
On the one hand, adding gcflags would make safe use of this
flag easier, since if the full object files were needed,
a simple 'go install' would fix it.
On the other hand, this would mean that
'go install -gcflags=-dolinkobj=false' would rebuild the object files,
although any existing object files would probably suffice.

Change-Id: I8dc75ab5a40095c785c1a4d2260aeb63c4d10f73
Reviewed-on: https://go-review.googlesource.com/37384
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Josh Bleecher Snyder 2017-02-22 00:05:18 -08:00
parent 2b2870fff8
commit 005c77dde8
3 changed files with 37 additions and 29 deletions

View file

@ -118,6 +118,7 @@ var pragcgobuf string
var outfile string var outfile string
var linkobj string var linkobj string
var dolinkobj bool
var bout *bio.Writer var bout *bio.Writer

View file

@ -181,6 +181,7 @@ func Main() {
obj.Flagcount("live", "debug liveness analysis", &debuglive) obj.Flagcount("live", "debug liveness analysis", &debuglive)
obj.Flagcount("m", "print optimization decisions", &Debug['m']) obj.Flagcount("m", "print optimization decisions", &Debug['m'])
flag.BoolVar(&flag_msan, "msan", false, "build code compatible with C/C++ memory sanitizer") flag.BoolVar(&flag_msan, "msan", false, "build code compatible with C/C++ memory sanitizer")
flag.BoolVar(&dolinkobj, "dolinkobj", true, "generate linker-specific objects; if false, some invalid code may compile")
flag.BoolVar(&nolocalimports, "nolocalimports", false, "reject local (relative) imports") flag.BoolVar(&nolocalimports, "nolocalimports", false, "reject local (relative) imports")
flag.StringVar(&outfile, "o", "", "write output to `file`") flag.StringVar(&outfile, "o", "", "write output to `file`")
flag.StringVar(&myimportpath, "p", "", "set expected package import `path`") flag.StringVar(&myimportpath, "p", "", "set expected package import `path`")
@ -450,38 +451,40 @@ func Main() {
timings.Start("fe", "escapes") timings.Start("fe", "escapes")
escapes(xtop) escapes(xtop)
// Phase 7: Transform closure bodies to properly reference captured variables. if dolinkobj {
// This needs to happen before walk, because closures must be transformed // Phase 7: Transform closure bodies to properly reference captured variables.
// before walk reaches a call of a closure. // This needs to happen before walk, because closures must be transformed
timings.Start("fe", "xclosures") // before walk reaches a call of a closure.
for _, n := range xtop { timings.Start("fe", "xclosures")
if n.Op == ODCLFUNC && n.Func.Closure != nil { for _, n := range xtop {
Curfn = n if n.Op == ODCLFUNC && n.Func.Closure != nil {
transformclosure(n) Curfn = n
transformclosure(n)
}
} }
}
Curfn = nil Curfn = nil
// Phase 8: Compile top level functions. // Phase 8: Compile top level functions.
// Don't use range--walk can add functions to xtop. // Don't use range--walk can add functions to xtop.
timings.Start("be", "compilefuncs") timings.Start("be", "compilefuncs")
fcount = 0 fcount = 0
for i := 0; i < len(xtop); i++ { for i := 0; i < len(xtop); i++ {
n := xtop[i] n := xtop[i]
if n.Op == ODCLFUNC { if n.Op == ODCLFUNC {
funccompile(n) funccompile(n)
fcount++ fcount++
}
} }
} timings.AddEvent(fcount, "funcs")
timings.AddEvent(fcount, "funcs")
if nsavederrors+nerrors == 0 { if nsavederrors+nerrors == 0 {
fninit(xtop) fninit(xtop)
} }
if compiling_runtime { if compiling_runtime {
checknowritebarrierrec() checknowritebarrierrec()
}
} }
// Phase 9: Check external declarations. // Phase 9: Check external declarations.

View file

@ -41,12 +41,16 @@ const (
) )
func dumpobj() { func dumpobj() {
if !dolinkobj {
dumpobj1(outfile, modeCompilerObj)
return
}
if linkobj == "" { if linkobj == "" {
dumpobj1(outfile, modeCompilerObj|modeLinkerObj) dumpobj1(outfile, modeCompilerObj|modeLinkerObj)
} else { return
dumpobj1(outfile, modeCompilerObj)
dumpobj1(linkobj, modeLinkerObj)
} }
dumpobj1(outfile, modeCompilerObj)
dumpobj1(linkobj, modeLinkerObj)
} }
func dumpobj1(outfile string, mode int) { func dumpobj1(outfile string, mode int) {