mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/go: Add support for including C++ files in packages
* Add a CXXFiles field to Package, which includes .cc, .cpp and .cxx files. * CXXFiles are compiled using g++, which can be overridden using the CXX environment variable. * Include .hh, .hpp and .hxx files in HFiles. * Add support for CPPFLAGS (used for both C and C++) and CXXFLAGS (used only for C++) in cgo directive. * Changed pkg-config cgo directive to modify CPPFLAGS rather than CFLAGS, so both C and C++ files get any flag returned by pkg-config --cflags. Fixes #1476. R=iant, r CC=bradfitz, gobot, golang-dev, iant, minux.ma, remyoudompheng, seb.binet https://golang.org/cl/8248043
This commit is contained in:
parent
ab5c762a46
commit
84485361f9
7 changed files with 141 additions and 41 deletions
|
|
@ -24,7 +24,7 @@ the C parts of the package. For example:
|
||||||
// #include <errno.h>
|
// #include <errno.h>
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
CFLAGS and LDFLAGS may be defined with pseudo #cgo directives
|
CPPFLAGS, CFLAGS, CXXFLAGS and LDFLAGS may be defined with pseudo #cgo directives
|
||||||
within these comments to tweak the behavior of gcc. Values defined
|
within these comments to tweak the behavior of gcc. Values defined
|
||||||
in multiple directives are concatenated together. Options prefixed
|
in multiple directives are concatenated together. Options prefixed
|
||||||
by $GOOS, $GOARCH, or $GOOS/$GOARCH are only defined in matching
|
by $GOOS, $GOARCH, or $GOOS/$GOARCH are only defined in matching
|
||||||
|
|
@ -36,7 +36,7 @@ systems. For example:
|
||||||
// #include <png.h>
|
// #include <png.h>
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
Alternatively, CFLAGS and LDFLAGS may be obtained via the pkg-config
|
Alternatively, CPPFLAGS and LDFLAGS may be obtained via the pkg-config
|
||||||
tool using a '#cgo pkg-config:' directive followed by the package names.
|
tool using a '#cgo pkg-config:' directive followed by the package names.
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
|
|
@ -44,7 +44,7 @@ For example:
|
||||||
// #include <png.h>
|
// #include <png.h>
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
The CGO_CFLAGS and CGO_LDFLAGS environment variables are added
|
The CGO_CPPFLAGS, CGO_CFLAGS, CGO_CXXFLAGS and CGO_LDFLAGS environment variables are added
|
||||||
to the flags derived from these directives. Package-specific flags should
|
to the flags derived from these directives. Package-specific flags should
|
||||||
be set using the directives, not the environment variables, so that builds
|
be set using the directives, not the environment variables, so that builds
|
||||||
work in unmodified environments.
|
work in unmodified environments.
|
||||||
|
|
|
||||||
|
|
@ -185,6 +185,18 @@ func isSpaceByte(c byte) bool {
|
||||||
return c == ' ' || c == '\t' || c == '\n' || c == '\r'
|
return c == ' ' || c == '\t' || c == '\n' || c == '\r'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fileExtSplit expects a filename and returns the name
|
||||||
|
// and ext (without the dot). If the file has no
|
||||||
|
// extension, ext will be empty.
|
||||||
|
func fileExtSplit(file string) (name, ext string) {
|
||||||
|
dotExt := filepath.Ext(file)
|
||||||
|
name = file[:len(file)-len(dotExt)]
|
||||||
|
if dotExt != "" {
|
||||||
|
ext = dotExt[1:]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
type stringsFlag []string
|
type stringsFlag []string
|
||||||
|
|
||||||
func (v *stringsFlag) Set(s string) error {
|
func (v *stringsFlag) Set(s string) error {
|
||||||
|
|
@ -727,6 +739,15 @@ func hasString(strings []string, s string) bool {
|
||||||
|
|
||||||
// build is the action for building a single package or command.
|
// build is the action for building a single package or command.
|
||||||
func (b *builder) build(a *action) (err error) {
|
func (b *builder) build(a *action) (err error) {
|
||||||
|
// Return an error if the package has CXX files but it's not using
|
||||||
|
// cgo nor SWIG, since the CXX files can only be processed by cgo
|
||||||
|
// and SWIG (it's possible to have packages with C files without
|
||||||
|
// using cgo, they will get compiled with the plan9 C compiler and
|
||||||
|
// linked with the rest of the package).
|
||||||
|
if len(a.p.CXXFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
|
||||||
|
return fmt.Errorf("can't build package %s because it contains C++ files (%s) but it's not using cgo nor SWIG",
|
||||||
|
a.p.ImportPath, strings.Join(a.p.CXXFiles, ","))
|
||||||
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil && err != errPrintedOutput {
|
if err != nil && err != errPrintedOutput {
|
||||||
err = fmt.Errorf("go build %s: %v", a.p.ImportPath, err)
|
err = fmt.Errorf("go build %s: %v", a.p.ImportPath, err)
|
||||||
|
|
@ -770,8 +791,8 @@ func (b *builder) build(a *action) (err error) {
|
||||||
sfiles = append(sfiles, a.p.SFiles...)
|
sfiles = append(sfiles, a.p.SFiles...)
|
||||||
|
|
||||||
// Run cgo.
|
// Run cgo.
|
||||||
if len(a.p.CgoFiles) > 0 {
|
if a.p.usesCgo() {
|
||||||
// In a package using cgo, cgo compiles the C and assembly files with gcc.
|
// In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
|
||||||
// There is one exception: runtime/cgo's job is to bridge the
|
// There is one exception: runtime/cgo's job is to bridge the
|
||||||
// cgo and non-cgo worlds, so it necessarily has files in both.
|
// cgo and non-cgo worlds, so it necessarily has files in both.
|
||||||
// In that case gcc only gets the gcc_* files.
|
// In that case gcc only gets the gcc_* files.
|
||||||
|
|
@ -799,7 +820,7 @@ func (b *builder) build(a *action) (err error) {
|
||||||
if a.cgo != nil && a.cgo.target != "" {
|
if a.cgo != nil && a.cgo.target != "" {
|
||||||
cgoExe = a.cgo.target
|
cgoExe = a.cgo.target
|
||||||
}
|
}
|
||||||
outGo, outObj, err := b.cgo(a.p, cgoExe, obj, gccfiles)
|
outGo, outObj, err := b.cgo(a.p, cgoExe, obj, gccfiles, a.p.CXXFiles)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -814,6 +835,7 @@ func (b *builder) build(a *action) (err error) {
|
||||||
gccfiles := append(cfiles, sfiles...)
|
gccfiles := append(cfiles, sfiles...)
|
||||||
cfiles = nil
|
cfiles = nil
|
||||||
sfiles = nil
|
sfiles = nil
|
||||||
|
// TODO(hierro): Handle C++ files with SWIG
|
||||||
outGo, outObj, err := b.swig(a.p, obj, gccfiles)
|
outGo, outObj, err := b.swig(a.p, obj, gccfiles)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -843,23 +865,24 @@ func (b *builder) build(a *action) (err error) {
|
||||||
// Copy .h files named for goos or goarch or goos_goarch
|
// Copy .h files named for goos or goarch or goos_goarch
|
||||||
// to names using GOOS and GOARCH.
|
// to names using GOOS and GOARCH.
|
||||||
// For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
|
// For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
|
||||||
_goos_goarch := "_" + goos + "_" + goarch + ".h"
|
_goos_goarch := "_" + goos + "_" + goarch
|
||||||
_goos := "_" + goos + ".h"
|
_goos := "_" + goos
|
||||||
_goarch := "_" + goarch + ".h"
|
_goarch := "_" + goarch
|
||||||
for _, file := range a.p.HFiles {
|
for _, file := range a.p.HFiles {
|
||||||
|
name, ext := fileExtSplit(file)
|
||||||
switch {
|
switch {
|
||||||
case strings.HasSuffix(file, _goos_goarch):
|
case strings.HasSuffix(name, _goos_goarch):
|
||||||
targ := file[:len(file)-len(_goos_goarch)] + "_GOOS_GOARCH.h"
|
targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext
|
||||||
if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
|
if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case strings.HasSuffix(file, _goarch):
|
case strings.HasSuffix(name, _goarch):
|
||||||
targ := file[:len(file)-len(_goarch)] + "_GOARCH.h"
|
targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext
|
||||||
if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
|
if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case strings.HasSuffix(file, _goos):
|
case strings.HasSuffix(name, _goos):
|
||||||
targ := file[:len(file)-len(_goos)] + "_GOOS.h"
|
targ := file[:len(name)-len(_goos)] + "_GOOS." + ext
|
||||||
if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
|
if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -1454,7 +1477,7 @@ func (gcToolchain) gc(b *builder, p *Package, obj string, importArgs []string, g
|
||||||
// so that it can give good error messages about forward declarations.
|
// so that it can give good error messages about forward declarations.
|
||||||
// Exceptions: a few standard packages have forward declarations for
|
// Exceptions: a few standard packages have forward declarations for
|
||||||
// pieces supplied behind-the-scenes by package runtime.
|
// pieces supplied behind-the-scenes by package runtime.
|
||||||
extFiles := len(p.CgoFiles) + len(p.CFiles) + len(p.SFiles) + len(p.SysoFiles) + len(p.SwigFiles) + len(p.SwigCXXFiles)
|
extFiles := len(p.CgoFiles) + len(p.CFiles) + len(p.CXXFiles) + len(p.SFiles) + len(p.SysoFiles) + len(p.SwigFiles) + len(p.SwigCXXFiles)
|
||||||
if p.Standard {
|
if p.Standard {
|
||||||
switch p.ImportPath {
|
switch p.ImportPath {
|
||||||
case "os", "runtime/pprof", "sync", "time":
|
case "os", "runtime/pprof", "sync", "time":
|
||||||
|
|
@ -1689,26 +1712,53 @@ func (b *builder) libgcc(p *Package) (string, error) {
|
||||||
|
|
||||||
// gcc runs the gcc C compiler to create an object from a single C file.
|
// gcc runs the gcc C compiler to create an object from a single C file.
|
||||||
func (b *builder) gcc(p *Package, out string, flags []string, cfile string) error {
|
func (b *builder) gcc(p *Package, out string, flags []string, cfile string) error {
|
||||||
cfile = mkAbs(p.Dir, cfile)
|
return b.ccompile(p, out, flags, cfile, b.gccCmd(p.Dir))
|
||||||
return b.run(p.Dir, p.ImportPath, nil, b.gccCmd(p.Dir), flags, "-o", out, "-c", cfile)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// gccld runs the gcc linker to create an executable from a set of object files
|
// gxx runs the g++ C++ compiler to create an object from a single C++ file.
|
||||||
|
func (b *builder) gxx(p *Package, out string, flags []string, cxxfile string) error {
|
||||||
|
return b.ccompile(p, out, flags, cxxfile, b.gxxCmd(p.Dir))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ccompile runs the given C or C++ compiler and creates an object from a single source file.
|
||||||
|
func (b *builder) ccompile(p *Package, out string, flags []string, file string, compiler []string) error {
|
||||||
|
file = mkAbs(p.Dir, file)
|
||||||
|
return b.run(p.Dir, p.ImportPath, nil, compiler, flags, "-o", out, "-c", file)
|
||||||
|
}
|
||||||
|
|
||||||
|
// gccld runs the gcc linker to create an executable from a set of object files.
|
||||||
func (b *builder) gccld(p *Package, out string, flags []string, obj []string) error {
|
func (b *builder) gccld(p *Package, out string, flags []string, obj []string) error {
|
||||||
return b.run(p.Dir, p.ImportPath, nil, b.gccCmd(p.Dir), "-o", out, obj, flags)
|
var cmd []string
|
||||||
|
if len(p.CXXFiles) > 0 {
|
||||||
|
cmd = b.gxxCmd(p.Dir)
|
||||||
|
} else {
|
||||||
|
cmd = b.gccCmd(p.Dir)
|
||||||
|
}
|
||||||
|
return b.run(p.Dir, p.ImportPath, nil, cmd, "-o", out, obj, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
// gccCmd returns a gcc command line prefix
|
// gccCmd returns a gcc command line prefix
|
||||||
func (b *builder) gccCmd(objdir string) []string {
|
func (b *builder) gccCmd(objdir string) []string {
|
||||||
|
return b.ccompilerCmd("CC", "gcc", objdir)
|
||||||
|
}
|
||||||
|
|
||||||
|
// gxxCmd returns a g++ command line prefix
|
||||||
|
func (b *builder) gxxCmd(objdir string) []string {
|
||||||
|
return b.ccompilerCmd("CXX", "g++", objdir)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ccompilerCmd returns a command line prefix for the given environment
|
||||||
|
// variable and using the default command when the variable is empty
|
||||||
|
func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
|
||||||
// NOTE: env.go's mkEnv knows that the first three
|
// NOTE: env.go's mkEnv knows that the first three
|
||||||
// strings returned are "gcc", "-I", objdir (and cuts them off).
|
// strings returned are "gcc", "-I", objdir (and cuts them off).
|
||||||
|
|
||||||
gcc := strings.Fields(os.Getenv("CC"))
|
compiler := strings.Fields(os.Getenv(envvar))
|
||||||
if len(gcc) == 0 {
|
if len(compiler) == 0 {
|
||||||
gcc = append(gcc, "gcc")
|
compiler = append(compiler, defcmd)
|
||||||
}
|
}
|
||||||
a := []string{gcc[0], "-I", objdir, "-g", "-O2"}
|
a := []string{compiler[0], "-I", objdir, "-g", "-O2"}
|
||||||
a = append(a, gcc[1:]...)
|
a = append(a, compiler[1:]...)
|
||||||
|
|
||||||
// Definitely want -fPIC but on Windows gcc complains
|
// Definitely want -fPIC but on Windows gcc complains
|
||||||
// "-fPIC ignored for target (all code is position independent)"
|
// "-fPIC ignored for target (all code is position independent)"
|
||||||
|
|
@ -1767,12 +1817,14 @@ var (
|
||||||
cgoLibGccFileOnce sync.Once
|
cgoLibGccFileOnce sync.Once
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo, outObj []string, err error) {
|
func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string, gxxfiles []string) (outGo, outObj []string, err error) {
|
||||||
if goos != toolGOOS {
|
if goos != toolGOOS {
|
||||||
return nil, nil, errors.New("cannot use cgo when compiling for a different operating system")
|
return nil, nil, errors.New("cannot use cgo when compiling for a different operating system")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cgoCPPFLAGS := stringList(envList("CGO_CPPFLAGS"), p.CgoCPPFLAGS)
|
||||||
cgoCFLAGS := stringList(envList("CGO_CFLAGS"), p.CgoCFLAGS)
|
cgoCFLAGS := stringList(envList("CGO_CFLAGS"), p.CgoCFLAGS)
|
||||||
|
cgoCXXFLAGS := stringList(envList("CGO_CXXFLAGS"), p.CgoCXXFLAGS)
|
||||||
cgoLDFLAGS := stringList(envList("CGO_LDFLAGS"), p.CgoLDFLAGS)
|
cgoLDFLAGS := stringList(envList("CGO_LDFLAGS"), p.CgoLDFLAGS)
|
||||||
|
|
||||||
if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
|
if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
|
||||||
|
|
@ -1783,7 +1835,7 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo,
|
||||||
return nil, nil, errPrintedOutput
|
return nil, nil, errPrintedOutput
|
||||||
}
|
}
|
||||||
if len(out) > 0 {
|
if len(out) > 0 {
|
||||||
cgoCFLAGS = append(cgoCFLAGS, strings.Fields(string(out))...)
|
cgoCPPFLAGS = append(cgoCPPFLAGS, strings.Fields(string(out))...)
|
||||||
}
|
}
|
||||||
out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--libs", pkgs)
|
out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--libs", pkgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -1797,7 +1849,7 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allows including _cgo_export.h from .[ch] files in the package.
|
// Allows including _cgo_export.h from .[ch] files in the package.
|
||||||
cgoCFLAGS = append(cgoCFLAGS, "-I", obj)
|
cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", obj)
|
||||||
|
|
||||||
// cgo
|
// cgo
|
||||||
// TODO: CGOPKGPATH, CGO_FLAGS?
|
// TODO: CGOPKGPATH, CGO_FLAGS?
|
||||||
|
|
@ -1839,7 +1891,7 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo,
|
||||||
}
|
}
|
||||||
objExt = "o"
|
objExt = "o"
|
||||||
}
|
}
|
||||||
if err := b.run(p.Dir, p.ImportPath, cgoenv, cgoExe, "-objdir", obj, cgoflags, "--", cgoCFLAGS, p.CgoFiles); err != nil {
|
if err := b.run(p.Dir, p.ImportPath, cgoenv, cgoExe, "-objdir", obj, cgoflags, "--", cgoCPPFLAGS, cgoCFLAGS, p.CgoFiles); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
outGo = append(outGo, gofiles...)
|
outGo = append(outGo, gofiles...)
|
||||||
|
|
@ -1893,9 +1945,10 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo,
|
||||||
staticLibs = append(staticLibs, cgoLibGccFile)
|
staticLibs = append(staticLibs, cgoLibGccFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
|
||||||
for _, cfile := range cfiles {
|
for _, cfile := range cfiles {
|
||||||
ofile := obj + cfile[:len(cfile)-1] + "o"
|
ofile := obj + cfile[:len(cfile)-1] + "o"
|
||||||
if err := b.gcc(p, ofile, cgoCFLAGS, obj+cfile); err != nil {
|
if err := b.gcc(p, ofile, cflags, obj+cfile); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
linkobj = append(linkobj, ofile)
|
linkobj = append(linkobj, ofile)
|
||||||
|
|
@ -1903,14 +1956,27 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo,
|
||||||
outObj = append(outObj, ofile)
|
outObj = append(outObj, ofile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, file := range gccfiles {
|
for _, file := range gccfiles {
|
||||||
ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
|
ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
|
||||||
if err := b.gcc(p, ofile, cgoCFLAGS, file); err != nil {
|
if err := b.gcc(p, ofile, cflags, file); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
linkobj = append(linkobj, ofile)
|
linkobj = append(linkobj, ofile)
|
||||||
outObj = append(outObj, ofile)
|
outObj = append(outObj, ofile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
|
||||||
|
for _, file := range gxxfiles {
|
||||||
|
// Append .o to the file, just in case the pkg has file.c and file.cpp
|
||||||
|
ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
|
||||||
|
if err := b.gxx(p, ofile, cxxflags, file); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
linkobj = append(linkobj, ofile)
|
||||||
|
outObj = append(outObj, ofile)
|
||||||
|
}
|
||||||
|
|
||||||
linkobj = append(linkobj, p.SysoFiles...)
|
linkobj = append(linkobj, p.SysoFiles...)
|
||||||
dynobj := obj + "_cgo_.o"
|
dynobj := obj + "_cgo_.o"
|
||||||
if goarch == "arm" && goos == "linux" { // we need to use -pie for Linux/ARM to get accurate imported sym
|
if goarch == "arm" && goos == "linux" { // we need to use -pie for Linux/ARM to get accurate imported sym
|
||||||
|
|
|
||||||
|
|
@ -318,14 +318,17 @@ which calls strings.Join. The struct being passed to the template is:
|
||||||
CgoFiles []string // .go sources files that import "C"
|
CgoFiles []string // .go sources files that import "C"
|
||||||
IgnoredGoFiles []string // .go sources ignored due to build constraints
|
IgnoredGoFiles []string // .go sources ignored due to build constraints
|
||||||
CFiles []string // .c source files
|
CFiles []string // .c source files
|
||||||
HFiles []string // .h source files
|
CXXFiles []string // .cc, .cxx and .cpp source files
|
||||||
|
HFiles []string // .h, .hh, .hpp and .hxx source files
|
||||||
SFiles []string // .s source files
|
SFiles []string // .s source files
|
||||||
SysoFiles []string // .syso object files to add to archive
|
SysoFiles []string // .syso object files to add to archive
|
||||||
SwigFiles []string // .swig files
|
SwigFiles []string // .swig files
|
||||||
SwigCXXFiles []string // .swigcxx files
|
SwigCXXFiles []string // .swigcxx files
|
||||||
|
|
||||||
// Cgo directives
|
// Cgo directives
|
||||||
|
CgoCPPFLAGS []string // cgo: flags for C preprocessor
|
||||||
CgoCFLAGS []string // cgo: flags for C compiler
|
CgoCFLAGS []string // cgo: flags for C compiler
|
||||||
|
CgoCXXFLAGS []string // cgo: flags for C++ compiler
|
||||||
CgoLDFLAGS []string // cgo: flags for linker
|
CgoLDFLAGS []string // cgo: flags for linker
|
||||||
CgoPkgConfig []string // cgo: pkg-config names
|
CgoPkgConfig []string // cgo: pkg-config names
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,14 +46,17 @@ which calls strings.Join. The struct being passed to the template is:
|
||||||
CgoFiles []string // .go sources files that import "C"
|
CgoFiles []string // .go sources files that import "C"
|
||||||
IgnoredGoFiles []string // .go sources ignored due to build constraints
|
IgnoredGoFiles []string // .go sources ignored due to build constraints
|
||||||
CFiles []string // .c source files
|
CFiles []string // .c source files
|
||||||
HFiles []string // .h source files
|
CXXFiles []string // .cc, .cxx and .cpp source files
|
||||||
|
HFiles []string // .h, .hh, .hpp and .hxx source files
|
||||||
SFiles []string // .s source files
|
SFiles []string // .s source files
|
||||||
SysoFiles []string // .syso object files to add to archive
|
SysoFiles []string // .syso object files to add to archive
|
||||||
SwigFiles []string // .swig files
|
SwigFiles []string // .swig files
|
||||||
SwigCXXFiles []string // .swigcxx files
|
SwigCXXFiles []string // .swigcxx files
|
||||||
|
|
||||||
// Cgo directives
|
// Cgo directives
|
||||||
|
CgoCPPFLAGS []string // cgo: flags for C preprocessor
|
||||||
CgoCFLAGS []string // cgo: flags for C compiler
|
CgoCFLAGS []string // cgo: flags for C compiler
|
||||||
|
CgoCXXFLAGS []string // cgo: flags for C++ compiler
|
||||||
CgoLDFLAGS []string // cgo: flags for linker
|
CgoLDFLAGS []string // cgo: flags for linker
|
||||||
CgoPkgConfig []string // cgo: pkg-config names
|
CgoPkgConfig []string // cgo: pkg-config names
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,14 +40,17 @@ type Package struct {
|
||||||
CgoFiles []string `json:",omitempty"` // .go sources files that import "C"
|
CgoFiles []string `json:",omitempty"` // .go sources files that import "C"
|
||||||
IgnoredGoFiles []string `json:",omitempty"` // .go sources ignored due to build constraints
|
IgnoredGoFiles []string `json:",omitempty"` // .go sources ignored due to build constraints
|
||||||
CFiles []string `json:",omitempty"` // .c source files
|
CFiles []string `json:",omitempty"` // .c source files
|
||||||
HFiles []string `json:",omitempty"` // .h source files
|
CXXFiles []string `json:",omitempty"` // .cc, .cpp and .cxx source files
|
||||||
|
HFiles []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files
|
||||||
SFiles []string `json:",omitempty"` // .s source files
|
SFiles []string `json:",omitempty"` // .s source files
|
||||||
SysoFiles []string `json:",omitempty"` // .syso system object files added to package
|
SysoFiles []string `json:",omitempty"` // .syso system object files added to package
|
||||||
SwigFiles []string `json:",omitempty"` // .swig files
|
SwigFiles []string `json:",omitempty"` // .swig files
|
||||||
SwigCXXFiles []string `json:",omitempty"` // .swigcxx files
|
SwigCXXFiles []string `json:",omitempty"` // .swigcxx files
|
||||||
|
|
||||||
// Cgo directives
|
// Cgo directives
|
||||||
|
CgoCPPFLAGS []string `json:",omitempty"` // cgo: flags for C preprocessor
|
||||||
CgoCFLAGS []string `json:",omitempty"` // cgo: flags for C compiler
|
CgoCFLAGS []string `json:",omitempty"` // cgo: flags for C compiler
|
||||||
|
CgoCXXFLAGS []string `json:",omitempty"` // cgo: flags for C++ compiler
|
||||||
CgoLDFLAGS []string `json:",omitempty"` // cgo: flags for linker
|
CgoLDFLAGS []string `json:",omitempty"` // cgo: flags for linker
|
||||||
CgoPkgConfig []string `json:",omitempty"` // cgo: pkg-config names
|
CgoPkgConfig []string `json:",omitempty"` // cgo: pkg-config names
|
||||||
|
|
||||||
|
|
@ -98,12 +101,15 @@ func (p *Package) copyBuild(pp *build.Package) {
|
||||||
p.CgoFiles = pp.CgoFiles
|
p.CgoFiles = pp.CgoFiles
|
||||||
p.IgnoredGoFiles = pp.IgnoredGoFiles
|
p.IgnoredGoFiles = pp.IgnoredGoFiles
|
||||||
p.CFiles = pp.CFiles
|
p.CFiles = pp.CFiles
|
||||||
|
p.CXXFiles = pp.CXXFiles
|
||||||
p.HFiles = pp.HFiles
|
p.HFiles = pp.HFiles
|
||||||
p.SFiles = pp.SFiles
|
p.SFiles = pp.SFiles
|
||||||
p.SysoFiles = pp.SysoFiles
|
p.SysoFiles = pp.SysoFiles
|
||||||
p.SwigFiles = pp.SwigFiles
|
p.SwigFiles = pp.SwigFiles
|
||||||
p.SwigCXXFiles = pp.SwigCXXFiles
|
p.SwigCXXFiles = pp.SwigCXXFiles
|
||||||
|
p.CgoCPPFLAGS = pp.CgoCPPFLAGS
|
||||||
p.CgoCFLAGS = pp.CgoCFLAGS
|
p.CgoCFLAGS = pp.CgoCFLAGS
|
||||||
|
p.CgoCXXFLAGS = pp.CgoCXXFLAGS
|
||||||
p.CgoLDFLAGS = pp.CgoLDFLAGS
|
p.CgoLDFLAGS = pp.CgoLDFLAGS
|
||||||
p.CgoPkgConfig = pp.CgoPkgConfig
|
p.CgoPkgConfig = pp.CgoPkgConfig
|
||||||
p.Imports = pp.Imports
|
p.Imports = pp.Imports
|
||||||
|
|
@ -389,6 +395,7 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
|
||||||
p.CgoFiles,
|
p.CgoFiles,
|
||||||
p.IgnoredGoFiles,
|
p.IgnoredGoFiles,
|
||||||
p.CFiles,
|
p.CFiles,
|
||||||
|
p.CXXFiles,
|
||||||
p.HFiles,
|
p.HFiles,
|
||||||
p.SFiles,
|
p.SFiles,
|
||||||
p.SysoFiles,
|
p.SysoFiles,
|
||||||
|
|
@ -481,6 +488,11 @@ func (p *Package) usesSwig() bool {
|
||||||
return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 0
|
return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// usesCgo returns whether the package needs to run cgo
|
||||||
|
func (p *Package) usesCgo() bool {
|
||||||
|
return len(p.CgoFiles) > 0
|
||||||
|
}
|
||||||
|
|
||||||
// swigSoname returns the name of the shared library we create for a
|
// swigSoname returns the name of the shared library we create for a
|
||||||
// SWIG input file.
|
// SWIG input file.
|
||||||
func (p *Package) swigSoname(file string) string {
|
func (p *Package) swigSoname(file string) string {
|
||||||
|
|
@ -611,7 +623,7 @@ func isStale(p *Package, topRoot map[string]bool) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
srcs := stringList(p.GoFiles, p.CFiles, p.HFiles, p.SFiles, p.CgoFiles, p.SysoFiles)
|
srcs := stringList(p.GoFiles, p.CFiles, p.CXXFiles, p.HFiles, p.SFiles, p.CgoFiles, p.SysoFiles)
|
||||||
for _, src := range srcs {
|
for _, src := range srcs {
|
||||||
if olderThan(filepath.Join(p.Dir, src)) {
|
if olderThan(filepath.Join(p.Dir, src)) {
|
||||||
return true
|
return true
|
||||||
|
|
|
||||||
|
|
@ -657,10 +657,16 @@ func (x *Indexer) addFile(filename string, goFile bool) (file *token.File, ast *
|
||||||
var whitelisted = map[string]bool{
|
var whitelisted = map[string]bool{
|
||||||
".bash": true,
|
".bash": true,
|
||||||
".c": true,
|
".c": true,
|
||||||
|
".cc": true,
|
||||||
|
".cpp": true,
|
||||||
|
".cxx": true,
|
||||||
".css": true,
|
".css": true,
|
||||||
".go": true,
|
".go": true,
|
||||||
".goc": true,
|
".goc": true,
|
||||||
".h": true,
|
".h": true,
|
||||||
|
".hh": true,
|
||||||
|
".hpp": true,
|
||||||
|
".hxx": true,
|
||||||
".html": true,
|
".html": true,
|
||||||
".js": true,
|
".js": true,
|
||||||
".out": true,
|
".out": true,
|
||||||
|
|
|
||||||
|
|
@ -353,16 +353,19 @@ type Package struct {
|
||||||
CgoFiles []string // .go source files that import "C"
|
CgoFiles []string // .go source files that import "C"
|
||||||
IgnoredGoFiles []string // .go source files ignored for this build
|
IgnoredGoFiles []string // .go source files ignored for this build
|
||||||
CFiles []string // .c source files
|
CFiles []string // .c source files
|
||||||
HFiles []string // .h source files
|
CXXFiles []string // .cc, .cpp and .cxx source files
|
||||||
|
HFiles []string // .h, .hh, .hpp and .hxx source files
|
||||||
SFiles []string // .s source files
|
SFiles []string // .s source files
|
||||||
SysoFiles []string // .syso system object files to add to archive
|
SysoFiles []string // .syso system object files to add to archive
|
||||||
SwigFiles []string // .swig files
|
SwigFiles []string // .swig files
|
||||||
SwigCXXFiles []string // .swigcxx files
|
SwigCXXFiles []string // .swigcxx files
|
||||||
|
|
||||||
// Cgo directives
|
// Cgo directives
|
||||||
CgoPkgConfig []string // Cgo pkg-config directives
|
CgoCPPFLAGS []string // Cgo CPPFLAGS directives
|
||||||
CgoCFLAGS []string // Cgo CFLAGS directives
|
CgoCFLAGS []string // Cgo CFLAGS directives
|
||||||
|
CgoCXXFLAGS []string // Cgo CXXFLAGS directives
|
||||||
CgoLDFLAGS []string // Cgo LDFLAGS directives
|
CgoLDFLAGS []string // Cgo LDFLAGS directives
|
||||||
|
CgoPkgConfig []string // Cgo pkg-config directives
|
||||||
|
|
||||||
// Dependency information
|
// Dependency information
|
||||||
Imports []string // imports from GoFiles, CgoFiles
|
Imports []string // imports from GoFiles, CgoFiles
|
||||||
|
|
@ -600,7 +603,7 @@ Found:
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ext {
|
switch ext {
|
||||||
case ".go", ".c", ".s", ".h", ".S", ".swig", ".swigcxx":
|
case ".go", ".c", ".cc", ".cxx", ".cpp", ".s", ".h", ".hh", ".hpp", ".hxx", ".S", ".swig", ".swigcxx":
|
||||||
// tentatively okay - read to make sure
|
// tentatively okay - read to make sure
|
||||||
case ".syso":
|
case ".syso":
|
||||||
// binary objects to add to package archive
|
// binary objects to add to package archive
|
||||||
|
|
@ -643,7 +646,10 @@ Found:
|
||||||
case ".c":
|
case ".c":
|
||||||
p.CFiles = append(p.CFiles, name)
|
p.CFiles = append(p.CFiles, name)
|
||||||
continue
|
continue
|
||||||
case ".h":
|
case ".cc", ".cpp", ".cxx":
|
||||||
|
p.CXXFiles = append(p.CXXFiles, name)
|
||||||
|
continue
|
||||||
|
case ".h", ".hh", ".hpp", ".hxx":
|
||||||
p.HFiles = append(p.HFiles, name)
|
p.HFiles = append(p.HFiles, name)
|
||||||
continue
|
continue
|
||||||
case ".s":
|
case ".s":
|
||||||
|
|
@ -851,8 +857,8 @@ func (ctxt *Context) shouldBuild(content []byte) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// saveCgo saves the information from the #cgo lines in the import "C" comment.
|
// saveCgo saves the information from the #cgo lines in the import "C" comment.
|
||||||
// These lines set CFLAGS and LDFLAGS and pkg-config directives that affect
|
// These lines set CPPCFLAGS, CFLAGS, CXXFLAGS and LDFLAGS and pkg-config directives
|
||||||
// the way cgo's C code is built.
|
// that affect the way cgo's C code is built.
|
||||||
//
|
//
|
||||||
// TODO(rsc): This duplicates code in cgo.
|
// TODO(rsc): This duplicates code in cgo.
|
||||||
// Once the dust settles, remove this code from cgo.
|
// Once the dust settles, remove this code from cgo.
|
||||||
|
|
@ -910,6 +916,10 @@ func (ctxt *Context) saveCgo(filename string, di *Package, cg *ast.CommentGroup)
|
||||||
switch verb {
|
switch verb {
|
||||||
case "CFLAGS":
|
case "CFLAGS":
|
||||||
di.CgoCFLAGS = append(di.CgoCFLAGS, args...)
|
di.CgoCFLAGS = append(di.CgoCFLAGS, args...)
|
||||||
|
case "CPPFLAGS":
|
||||||
|
di.CgoCPPFLAGS = append(di.CgoCPPFLAGS, args...)
|
||||||
|
case "CXXFLAGS":
|
||||||
|
di.CgoCXXFLAGS = append(di.CgoCXXFLAGS, args...)
|
||||||
case "LDFLAGS":
|
case "LDFLAGS":
|
||||||
di.CgoLDFLAGS = append(di.CgoLDFLAGS, args...)
|
di.CgoLDFLAGS = append(di.CgoLDFLAGS, args...)
|
||||||
case "pkg-config":
|
case "pkg-config":
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue