diff options
author | Ayke van Laethem <[email protected]> | 2020-03-06 12:40:21 +0100 |
---|---|---|
committer | Ron Evans <[email protected]> | 2020-03-17 20:43:28 +0100 |
commit | a8da6016723ed83f5148bc2908f990de7ef79ed8 (patch) | |
tree | f922bc8e03453bc07f23364c7699b198d12e40d2 /cgo | |
parent | 9cef23c31817f24cadc6ea044123736541dcaa07 (diff) | |
download | tinygo-a8da6016723ed83f5148bc2908f990de7ef79ed8.tar.gz tinygo-a8da6016723ed83f5148bc2908f990de7ef79ed8.zip |
cgo: make -I and -L paths absolute
This is very useful for (conditionally) adding extra include paths
relative to the package path.
Diffstat (limited to 'cgo')
-rw-r--r-- | cgo/cgo.go | 39 | ||||
-rw-r--r-- | cgo/testdata/flags.go | 4 | ||||
-rw-r--r-- | cgo/testdata/flags.out.go | 1 | ||||
-rw-r--r-- | cgo/testdata/include/foo.h | 1 |
4 files changed, 45 insertions, 0 deletions
diff --git a/cgo/cgo.go b/cgo/cgo.go index 5799b4fa5..58aaed81c 100644 --- a/cgo/cgo.go +++ b/cgo/cgo.go @@ -14,7 +14,9 @@ package cgo import ( "fmt" "go/ast" + "go/scanner" "go/token" + "path/filepath" "sort" "strconv" "strings" @@ -173,6 +175,18 @@ func Process(files []*ast.File, dir string, fset *token.FileSet, cflags []string generatedTokenPos.SetLines([]int{0}) p.generatedPos = generatedTokenPos.Pos(0) + // Find the absolute path for this package. + packagePath, err := filepath.Abs(fset.File(files[0].Pos()).Name()) + if err != nil { + return nil, []error{ + scanner.Error{ + Pos: fset.Position(files[0].Pos()), + Msg: "cgo: cannot find absolute path: " + err.Error(), // TODO: wrap this error + }, + } + } + packagePath = filepath.Dir(packagePath) + // Construct a new in-memory AST for CGo declarations of this package. unsafeImport := &ast.ImportSpec{ Path: &ast.BasicLit{ @@ -338,6 +352,7 @@ func Process(files []*ast.File, dir string, fset *token.FileSet, cflags []string p.addErrorAfter(comment.Slash, comment.Text[:lineStart+colon+1], err.Error()) continue } + makePathsAbsolute(flags, packagePath) cflags = append(cflags, flags...) default: startPos := strings.LastIndex(line[4:colon], name) + 4 @@ -395,6 +410,30 @@ func Process(files []*ast.File, dir string, fset *token.FileSet, cflags []string return p.generated, p.errors } +// makePathsAbsolute converts some common path compiler flags (-I, -L) from +// relative flags into absolute flags, if they are relative. This is necessary +// because the C compiler is usually not invoked from the package path. +func makePathsAbsolute(args []string, packagePath string) { + nextIsPath := false + for i, arg := range args { + if nextIsPath { + if !filepath.IsAbs(arg) { + args[i] = filepath.Join(packagePath, arg) + } + } + if arg == "-I" || arg == "-L" { + nextIsPath = true + continue + } + if strings.HasPrefix(arg, "-I") || strings.HasPrefix(arg, "-L") { + path := arg[2:] + if !filepath.IsAbs(path) { + args[i] = arg[:2] + filepath.Join(packagePath, path) + } + } + } +} + // addFuncDecls adds the C function declarations found by libclang in the // comment above the `import "C"` statement. func (p *cgoPackage) addFuncDecls() { diff --git a/cgo/testdata/flags.go b/cgo/testdata/flags.go index bb518e554..d52bbc5b9 100644 --- a/cgo/testdata/flags.go +++ b/cgo/testdata/flags.go @@ -9,6 +9,9 @@ package main #cgo CFLAGS: -DFOO +#cgo CFLAGS: -Iinclude +#include "foo.h" + #if defined(FOO) #define BAR 3 #else @@ -23,4 +26,5 @@ import "C" var ( _ = C.BAR + _ = C.FOO_H ) diff --git a/cgo/testdata/flags.out.go b/cgo/testdata/flags.out.go index dba5d1fbe..0bcad0d5a 100644 --- a/cgo/testdata/flags.out.go +++ b/cgo/testdata/flags.out.go @@ -9,6 +9,7 @@ import "unsafe" var _ unsafe.Pointer const C.BAR = 3 +const C.FOO_H = 1 type C.int16_t = int16 type C.int32_t = int32 diff --git a/cgo/testdata/include/foo.h b/cgo/testdata/include/foo.h new file mode 100644 index 000000000..8fa2b1e18 --- /dev/null +++ b/cgo/testdata/include/foo.h @@ -0,0 +1 @@ +#define FOO_H 1 |