From 6cacafb8dc0351c2204cefedcd83864df6591d3d Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Fri, 30 Nov 2018 13:01:20 +0100 Subject: [PATCH] cgo: add package directory to header include paths --- compiler/compiler.go | 4 +++- loader/cgo.go | 4 ++-- loader/libclang.go | 14 ++++++++++++-- loader/loader.go | 3 ++- main.go | 1 + testdata/cgo/main.c | 2 ++ testdata/cgo/main.go | 3 +-- testdata/cgo/main.h | 2 ++ 8 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 testdata/cgo/main.h diff --git a/compiler/compiler.go b/compiler/compiler.go index 8b5adab6..2d621249 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -32,6 +32,7 @@ func init() { type Config struct { Triple string // LLVM target triple, e.g. x86_64-unknown-linux-gnu (empty string means default) GC string // garbage collection strategy + CFlags []string // flags to pass to cgo DumpSSA bool // dump Go SSA, for compiler debugging Debug bool // add debug symbols for gdb RootDir string // GOROOT for TinyGo @@ -208,7 +209,8 @@ func (c *Compiler) Compile(mainPath string) error { MaxAlign: int64(c.targetData.PrefTypeAlignment(c.i8ptrType)), }, }, - Dir: wd, + Dir: wd, + CFlags: c.CFlags, } if strings.HasSuffix(mainPath, ".go") { _, err = lprogram.ImportFile(mainPath) diff --git a/loader/cgo.go b/loader/cgo.go index 3678526c..f95e578b 100644 --- a/loader/cgo.go +++ b/loader/cgo.go @@ -73,7 +73,7 @@ typedef unsigned long long _Cgo_ulonglong; // processCgo extracts the `import "C"` statement from the AST, parses the // comment with libclang, and modifies the AST to use this information. -func (p *Package) processCgo(filename string, f *ast.File) error { +func (p *Package) processCgo(filename string, f *ast.File, cflags []string) error { info := &fileInfo{ File: f, filename: filename, @@ -106,7 +106,7 @@ func (p *Package) processCgo(filename string, f *ast.File) error { // source location. info.importCPos = spec.Path.ValuePos - err = info.parseFragment(cgoComment + cgoTypes) + err = info.parseFragment(cgoComment+cgoTypes, cflags) if err != nil { return err } diff --git a/loader/libclang.go b/loader/libclang.go index 9f3b444d..ae3ae8ab 100644 --- a/loader/libclang.go +++ b/loader/libclang.go @@ -20,7 +20,7 @@ import "C" var globalFileInfo *fileInfo -func (info *fileInfo) parseFragment(fragment string) error { +func (info *fileInfo) parseFragment(fragment string, cflags []string) error { index := C.clang_createIndex(0, 1) defer C.clang_disposeIndex(index) @@ -36,11 +36,21 @@ func (info *fileInfo) parseFragment(fragment string) error { Contents: fragmentC, } + // convert Go slice of strings to C array of strings. + cmdargsC := C.malloc(C.size_t(len(cflags)) * C.size_t(unsafe.Sizeof(uintptr(0)))) + defer C.free(cmdargsC) + cmdargs := (*[1<<30 - 1]*C.char)(cmdargsC) + for i, cflag := range cflags { + s := C.CString(cflag) + cmdargs[i] = s + defer C.free(unsafe.Pointer(s)) + } + var unit C.CXTranslationUnit errCode := C.clang_parseTranslationUnit2( index, filenameC, - (**C.char)(unsafe.Pointer(uintptr(0))), 0, // command line args + (**C.char)(cmdargsC), C.int(len(cflags)), // command line args &unsavedFile, 1, // unsaved files C.CXTranslationUnit_None, &unit) diff --git a/loader/loader.go b/loader/loader.go index c67ad39e..7c888757 100644 --- a/loader/loader.go +++ b/loader/loader.go @@ -20,6 +20,7 @@ type Program struct { fset *token.FileSet TypeChecker types.Config Dir string // current working directory (for error reporting) + CFlags []string } // Package holds a loaded package, its imports, and its parsed files. @@ -290,7 +291,7 @@ func (p *Package) parseFiles() ([]*ast.File, error) { fileErrs = append(fileErrs, err) continue } - err = p.processCgo(path, f) + err = p.processCgo(path, f, append(p.CFlags, "-I"+p.Package.Dir)) if err != nil { fileErrs = append(fileErrs, err) continue diff --git a/main.go b/main.go index 1bcd01c4..c1a311f2 100644 --- a/main.go +++ b/main.go @@ -44,6 +44,7 @@ func Compile(pkgName, outpath string, spec *TargetSpec, config *BuildConfig, act compilerConfig := compiler.Config{ Triple: spec.Triple, GC: config.gc, + CFlags: spec.CFlags, Debug: config.debug, DumpSSA: config.dumpSSA, RootDir: sourceDir(), diff --git a/testdata/cgo/main.c b/testdata/cgo/main.c index ecee9317..b0d4ba56 100644 --- a/testdata/cgo/main.c +++ b/testdata/cgo/main.c @@ -1,3 +1,5 @@ +#include "main.h" + int fortytwo() { return 42; } diff --git a/testdata/cgo/main.go b/testdata/cgo/main.go index f4a5d4d8..b8903a7d 100644 --- a/testdata/cgo/main.go +++ b/testdata/cgo/main.go @@ -2,8 +2,7 @@ package main /* int fortytwo(void); -typedef short myint; -int add(int a, int b); +#include "main.h" */ import "C" diff --git a/testdata/cgo/main.h b/testdata/cgo/main.h new file mode 100644 index 00000000..f41711f4 --- /dev/null +++ b/testdata/cgo/main.h @@ -0,0 +1,2 @@ +typedef short myint; +int add(int a, int b);