Skip to content

Commit

Permalink
cgo: make -I and -L paths absolute
Browse files Browse the repository at this point in the history
This is very useful for (conditionally) adding extra include paths
relative to the package path.
  • Loading branch information
aykevl authored and deadprogram committed Mar 17, 2020
1 parent 9cef23c commit a8da601
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 0 deletions.
39 changes: 39 additions & 0 deletions cgo/cgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ package cgo
import (
"fmt"
"go/ast"
"go/scanner"
"go/token"
"path/filepath"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -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{
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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() {
Expand Down
4 changes: 4 additions & 0 deletions cgo/testdata/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ package main
#cgo CFLAGS: -DFOO
#cgo CFLAGS: -Iinclude
#include "foo.h"
#if defined(FOO)
#define BAR 3
#else
Expand All @@ -23,4 +26,5 @@ import "C"

var (
_ = C.BAR
_ = C.FOO_H
)
1 change: 1 addition & 0 deletions cgo/testdata/flags.out.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions cgo/testdata/include/foo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#define FOO_H 1

0 comments on commit a8da601

Please sign in to comment.