cgo: make -I and -L paths absolute
This is very useful for (conditionally) adding extra include paths relative to the package path.
Этот коммит содержится в:
родитель
9cef23c318
коммит
a8da601672
4 изменённых файлов: 45 добавлений и 0 удалений
39
cgo/cgo.go
39
cgo/cgo.go
|
@ -14,7 +14,9 @@ package cgo
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
|
"go/scanner"
|
||||||
"go/token"
|
"go/token"
|
||||||
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -173,6 +175,18 @@ func Process(files []*ast.File, dir string, fset *token.FileSet, cflags []string
|
||||||
generatedTokenPos.SetLines([]int{0})
|
generatedTokenPos.SetLines([]int{0})
|
||||||
p.generatedPos = generatedTokenPos.Pos(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.
|
// Construct a new in-memory AST for CGo declarations of this package.
|
||||||
unsafeImport := &ast.ImportSpec{
|
unsafeImport := &ast.ImportSpec{
|
||||||
Path: &ast.BasicLit{
|
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())
|
p.addErrorAfter(comment.Slash, comment.Text[:lineStart+colon+1], err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
makePathsAbsolute(flags, packagePath)
|
||||||
cflags = append(cflags, flags...)
|
cflags = append(cflags, flags...)
|
||||||
default:
|
default:
|
||||||
startPos := strings.LastIndex(line[4:colon], name) + 4
|
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
|
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
|
// addFuncDecls adds the C function declarations found by libclang in the
|
||||||
// comment above the `import "C"` statement.
|
// comment above the `import "C"` statement.
|
||||||
func (p *cgoPackage) addFuncDecls() {
|
func (p *cgoPackage) addFuncDecls() {
|
||||||
|
|
4
cgo/testdata/flags.go
предоставленный
4
cgo/testdata/flags.go
предоставленный
|
@ -9,6 +9,9 @@ package main
|
||||||
|
|
||||||
#cgo CFLAGS: -DFOO
|
#cgo CFLAGS: -DFOO
|
||||||
|
|
||||||
|
#cgo CFLAGS: -Iinclude
|
||||||
|
#include "foo.h"
|
||||||
|
|
||||||
#if defined(FOO)
|
#if defined(FOO)
|
||||||
#define BAR 3
|
#define BAR 3
|
||||||
#else
|
#else
|
||||||
|
@ -23,4 +26,5 @@ import "C"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_ = C.BAR
|
_ = C.BAR
|
||||||
|
_ = C.FOO_H
|
||||||
)
|
)
|
||||||
|
|
1
cgo/testdata/flags.out.go
предоставленный
1
cgo/testdata/flags.out.go
предоставленный
|
@ -9,6 +9,7 @@ import "unsafe"
|
||||||
var _ unsafe.Pointer
|
var _ unsafe.Pointer
|
||||||
|
|
||||||
const C.BAR = 3
|
const C.BAR = 3
|
||||||
|
const C.FOO_H = 1
|
||||||
|
|
||||||
type C.int16_t = int16
|
type C.int16_t = int16
|
||||||
type C.int32_t = int32
|
type C.int32_t = int32
|
||||||
|
|
1
cgo/testdata/include/foo.h
предоставленный
Обычный файл
1
cgo/testdata/include/foo.h
предоставленный
Обычный файл
|
@ -0,0 +1 @@
|
||||||
|
#define FOO_H 1
|
Загрузка…
Создание таблицы
Сослаться в новой задаче