1
0
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:
Russ Cox 2012-06-07 12:37:50 -04:00
parent b185de82a4
commit f51390b23c
2 changed files with 20 additions and 8 deletions

View File

@ -22,6 +22,7 @@ import (
"path/filepath" "path/filepath"
"reflect" "reflect"
"runtime" "runtime"
"sort"
"strings" "strings"
) )
@ -34,7 +35,6 @@ type Package struct {
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
@ -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.

View File

@ -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)
} }