diff options
| author | Ondřej Surý <ondrej@sury.org> | 2012-01-30 15:38:19 +0100 |
|---|---|---|
| committer | Ondřej Surý <ondrej@sury.org> | 2012-01-30 15:38:19 +0100 |
| commit | 4cecda6c347bd6902b960c6a35a967add7070b0d (patch) | |
| tree | a462e224ff41ec9f3eb1a0b6e815806f9e8804ad /src/cmd/cgo/main.go | |
| parent | 6c7ca6e4d4e26e4c8cbe0d183966011b3b088a0a (diff) | |
| download | golang-4cecda6c347bd6902b960c6a35a967add7070b0d.tar.gz | |
Imported Upstream version 2012.01.27upstream-weekly/2012.01.27
Diffstat (limited to 'src/cmd/cgo/main.go')
| -rw-r--r-- | src/cmd/cgo/main.go | 108 |
1 files changed, 71 insertions, 37 deletions
diff --git a/src/cmd/cgo/main.go b/src/cmd/cgo/main.go index 106698114..f58291237 100644 --- a/src/cmd/cgo/main.go +++ b/src/cmd/cgo/main.go @@ -43,6 +43,7 @@ type Package struct { // A File collects information about a single Go input file. type File struct { AST *ast.File // parsed AST + Comments []*ast.CommentGroup // comments from file Package string // Package name Preamble string // C preamble (doc comment on import "C") Ref []*Ref // all references to C.xxx in AST @@ -122,7 +123,17 @@ var cPrefix string var fset = token.NewFileSet() var dynobj = flag.String("dynimport", "", "if non-empty, print dynamic import data for that file") +var dynout = flag.String("dynout", "", "write -dynobj output to this file") +// These flags are for bootstrapping a new Go implementation, +// to generate Go and C headers that match the data layout and +// constant values used in the host's C libraries and system calls. +var godefs = flag.Bool("godefs", false, "for bootstrap: write Go definitions for C file to standard output") +var cdefs = flag.Bool("cdefs", false, "for bootstrap: write C definitions for C file to standard output") +var objDir = flag.String("objdir", "", "object directory") + +var gccgo = flag.Bool("gccgo", false, "generate files for use with gccgo") +var importRuntimeCgo = flag.Bool("import_runtime_cgo", true, "import runtime/cgo in generated code") var goarch, goos string func main() { @@ -142,6 +153,11 @@ func main() { return } + if *godefs && *cdefs { + fmt.Fprintf(os.Stderr, "cgo: cannot use -cdefs and -godefs together\n") + os.Exit(2) + } + args := flag.Args() if len(args) < 1 { usage() @@ -159,36 +175,9 @@ func main() { usage() } - // Copy it to a new slice so it can grow. - gccOptions := make([]string, i) - copy(gccOptions, args[0:i]) - goFiles := args[i:] - goarch = runtime.GOARCH - if s := os.Getenv("GOARCH"); s != "" { - goarch = s - } - goos = runtime.GOOS - if s := os.Getenv("GOOS"); s != "" { - goos = s - } - ptrSize := ptrSizeMap[goarch] - if ptrSize == 0 { - fatalf("unknown $GOARCH %q", goarch) - } - - // Clear locale variables so gcc emits English errors [sic]. - os.Setenv("LANG", "en_US.UTF-8") - os.Setenv("LC_ALL", "C") - os.Setenv("LC_CTYPE", "C") - - p := &Package{ - PtrSize: ptrSize, - GccOptions: gccOptions, - CgoFlags: make(map[string]string), - Written: make(map[string]bool), - } + p := newPackage(args[:i]) // Need a unique prefix for the global C symbols that // we use to coordinate between gcc and ourselves. @@ -204,7 +193,7 @@ func main() { io.Copy(h, f) f.Close() } - cPrefix = fmt.Sprintf("_%x", h.Sum()[0:6]) + cPrefix = fmt.Sprintf("_%x", h.Sum(nil)[0:6]) fs := make([]*File, len(goFiles)) for i, input := range goFiles { @@ -215,9 +204,13 @@ func main() { fs[i] = f } - // make sure that _obj directory exists, so that we can write - // all the output files there. - os.Mkdir("_obj", 0777) + if *objDir == "" { + // make sure that _obj directory exists, so that we can write + // all the output files there. + os.Mkdir("_obj", 0777) + *objDir = "_obj" + } + *objDir += string(filepath.Separator) for i, input := range goFiles { f := fs[i] @@ -239,23 +232,64 @@ func main() { pkg = filepath.Join(dir, pkg) } p.PackagePath = pkg - p.writeOutput(f, input) - p.Record(f) + if *godefs { + os.Stdout.WriteString(p.godefs(f, input)) + } else if *cdefs { + os.Stdout.WriteString(p.cdefs(f, input)) + } else { + p.writeOutput(f, input) + } } - p.writeDefs() + if !*godefs && !*cdefs { + p.writeDefs() + } if nerrors > 0 { os.Exit(2) } } +// newPackage returns a new Package that will invoke +// gcc with the additional arguments specified in args. +func newPackage(args []string) *Package { + // Copy the gcc options to a new slice so the list + // can grow without overwriting the slice that args is in. + gccOptions := make([]string, len(args)) + copy(gccOptions, args) + + goarch = runtime.GOARCH + if s := os.Getenv("GOARCH"); s != "" { + goarch = s + } + goos = runtime.GOOS + if s := os.Getenv("GOOS"); s != "" { + goos = s + } + ptrSize := ptrSizeMap[goarch] + if ptrSize == 0 { + fatalf("unknown $GOARCH %q", goarch) + } + + // Reset locale variables so gcc emits English errors [sic]. + os.Setenv("LANG", "en_US.UTF-8") + os.Setenv("LC_ALL", "C") + + p := &Package{ + PtrSize: ptrSize, + GccOptions: gccOptions, + CgoFlags: make(map[string]string), + Written: make(map[string]bool), + } + return p +} + // Record what needs to be recorded about f. func (p *Package) Record(f *File) { if p.PackageName == "" { p.PackageName = f.Package } else if p.PackageName != f.Package { - error(token.NoPos, "inconsistent package names: %s, %s", p.PackageName, f.Package) + error_(token.NoPos, "inconsistent package names: %s, %s", p.PackageName, f.Package) } if p.Name == nil { @@ -265,7 +299,7 @@ func (p *Package) Record(f *File) { if p.Name[k] == nil { p.Name[k] = v } else if !reflect.DeepEqual(p.Name[k], v) { - error(token.NoPos, "inconsistent definitions for C.%s", k) + error_(token.NoPos, "inconsistent definitions for C.%s", k) } } } |
