mirror of
https://github.com/golang/go
synced 2024-11-20 10:44:41 -07:00
cmd/cgo: make Go code order deterministic
The type declarations were being generated using a range over a map, which meant that successive runs produced different orders. This will make sure successive runs produce the same files. Fixes #3707. R=golang-dev, bradfitz CC=golang-dev https://golang.org/cl/6300062
This commit is contained in:
parent
b185de82a4
commit
f51390b23c
@ -22,6 +22,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -33,9 +34,8 @@ type Package struct {
|
|||||||
GccOptions []string
|
GccOptions []string
|
||||||
CgoFlags map[string]string // #cgo flags (CFLAGS, LDFLAGS)
|
CgoFlags map[string]string // #cgo flags (CFLAGS, LDFLAGS)
|
||||||
Written map[string]bool
|
Written map[string]bool
|
||||||
Name map[string]*Name // accumulated Name from Files
|
Name map[string]*Name // accumulated Name from Files
|
||||||
Typedef map[string]ast.Expr // accumulated Typedef from Files
|
ExpFunc []*ExpFunc // accumulated ExpFunc from Files
|
||||||
ExpFunc []*ExpFunc // accumulated ExpFunc from Files
|
|
||||||
Decl []ast.Decl
|
Decl []ast.Decl
|
||||||
GoFiles []string // list of Go files
|
GoFiles []string // list of Go files
|
||||||
GccFiles []string // list of gcc output files
|
GccFiles []string // list of gcc output files
|
||||||
@ -51,7 +51,15 @@ type File struct {
|
|||||||
Ref []*Ref // all references to C.xxx in AST
|
Ref []*Ref // all references to C.xxx in AST
|
||||||
ExpFunc []*ExpFunc // exported functions for this file
|
ExpFunc []*ExpFunc // exported functions for this file
|
||||||
Name map[string]*Name // map from Go name to Name
|
Name map[string]*Name // map from Go name to Name
|
||||||
Typedef map[string]ast.Expr // translations of all necessary types from C
|
}
|
||||||
|
|
||||||
|
func nameKeys(m map[string]*Name) []string {
|
||||||
|
var ks []string
|
||||||
|
for k := range m {
|
||||||
|
ks = append(ks, k)
|
||||||
|
}
|
||||||
|
sort.Strings(ks)
|
||||||
|
return ks
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Ref refers to an expression of the form C.xxx in the AST.
|
// A Ref refers to an expression of the form C.xxx in the AST.
|
||||||
|
@ -71,7 +71,8 @@ func (p *Package) writeDefs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cVars := make(map[string]bool)
|
cVars := make(map[string]bool)
|
||||||
for _, n := range p.Name {
|
for _, key := range nameKeys(p.Name) {
|
||||||
|
n := p.Name[key]
|
||||||
if n.Kind != "var" {
|
if n.Kind != "var" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -94,14 +95,16 @@ func (p *Package) writeDefs() {
|
|||||||
}
|
}
|
||||||
fmt.Fprintf(fc, "\n")
|
fmt.Fprintf(fc, "\n")
|
||||||
|
|
||||||
for _, n := range p.Name {
|
for _, key := range nameKeys(p.Name) {
|
||||||
|
n := p.Name[key]
|
||||||
if n.Const != "" {
|
if n.Const != "" {
|
||||||
fmt.Fprintf(fgo2, "const _Cconst_%s = %s\n", n.Go, n.Const)
|
fmt.Fprintf(fgo2, "const _Cconst_%s = %s\n", n.Go, n.Const)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Fprintf(fgo2, "\n")
|
fmt.Fprintf(fgo2, "\n")
|
||||||
|
|
||||||
for _, n := range p.Name {
|
for _, key := range nameKeys(p.Name) {
|
||||||
|
n := p.Name[key]
|
||||||
if n.FuncType != nil {
|
if n.FuncType != nil {
|
||||||
p.writeDefsFunc(fc, fgo2, n)
|
p.writeDefsFunc(fc, fgo2, n)
|
||||||
}
|
}
|
||||||
@ -378,7 +381,8 @@ func (p *Package) writeOutput(f *File, srcfile string) {
|
|||||||
fmt.Fprintf(fgcc, "%s\n", f.Preamble)
|
fmt.Fprintf(fgcc, "%s\n", f.Preamble)
|
||||||
fmt.Fprintf(fgcc, "%s\n", gccProlog)
|
fmt.Fprintf(fgcc, "%s\n", gccProlog)
|
||||||
|
|
||||||
for _, n := range f.Name {
|
for _, key := range nameKeys(f.Name) {
|
||||||
|
n := f.Name[key]
|
||||||
if n.FuncType != nil {
|
if n.FuncType != nil {
|
||||||
p.writeOutputFunc(fgcc, n)
|
p.writeOutputFunc(fgcc, n)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user