mirror of
https://github.com/golang/go
synced 2024-11-19 06:54:39 -07:00
go/build: add variable expansion to cgo lines
When go parses #cgo lines, expand ${SRCDIR} into the path to the source directory. This allows options to be passed to the compiler and linker that involve file paths relative to the source code directory. Without the expansion the paths would be invalid when the current working directory changes. Fixes #7891 Fixes #5428 Change-Id: I343a145a9771a5ccbaa958e4a1ecd1716fcae52d Reviewed-on: https://go-review.googlesource.com/1756 Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
108dbd0dc7
commit
131758183f
@ -60,6 +60,18 @@ concatenated and used at link time. All the pkg-config directives are
|
|||||||
concatenated and sent to pkg-config simultaneously to add to each appropriate
|
concatenated and sent to pkg-config simultaneously to add to each appropriate
|
||||||
set of command-line flags.
|
set of command-line flags.
|
||||||
|
|
||||||
|
When the cgo directives are parsed, any occurrence of the string ${SRCDIR}
|
||||||
|
will be replaced by the absolute path to the directory containing the source
|
||||||
|
file. This allows pre-compiled static libraries to be included in the package
|
||||||
|
directory and linked properly.
|
||||||
|
For example if package foo is in the directory /go/src/foo:
|
||||||
|
|
||||||
|
// #cgo LDFLAGS: -L${SRCDIR}/libs -lfoo
|
||||||
|
|
||||||
|
Will be expanded to:
|
||||||
|
|
||||||
|
// #cgo LDFLAGS: -L/go/src/foo/libs -lfoo
|
||||||
|
|
||||||
When the Go tool sees that one or more Go files use the special import
|
When the Go tool sees that one or more Go files use the special import
|
||||||
"C", it will look for other non-Go files in the directory and compile
|
"C", it will look for other non-Go files in the directory and compile
|
||||||
them as part of the Go package. Any .c, .s, or .S files will be
|
them as part of the Go package. Any .c, .s, or .S files will be
|
||||||
|
@ -1120,10 +1120,12 @@ func (ctxt *Context) saveCgo(filename string, di *Package, cg *ast.CommentGroup)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
|
return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
|
||||||
}
|
}
|
||||||
for _, arg := range args {
|
for i, arg := range args {
|
||||||
|
arg = expandSrcDir(arg, di.Dir)
|
||||||
if !safeCgoName(arg) {
|
if !safeCgoName(arg) {
|
||||||
return fmt.Errorf("%s: malformed #cgo argument: %s", filename, arg)
|
return fmt.Errorf("%s: malformed #cgo argument: %s", filename, arg)
|
||||||
}
|
}
|
||||||
|
args[i] = arg
|
||||||
}
|
}
|
||||||
|
|
||||||
switch verb {
|
switch verb {
|
||||||
@ -1144,6 +1146,14 @@ func (ctxt *Context) saveCgo(filename string, di *Package, cg *ast.CommentGroup)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func expandSrcDir(str string, srcdir string) string {
|
||||||
|
// "\" delimited paths cause safeCgoName to fail
|
||||||
|
// so convert native paths with a different delimeter
|
||||||
|
// to "/" before starting (eg: on windows)
|
||||||
|
srcdir = filepath.ToSlash(srcdir)
|
||||||
|
return strings.Replace(str, "${SRCDIR}", srcdir, -1)
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: $ is not safe for the shell, but it is allowed here because of linker options like -Wl,$ORIGIN.
|
// NOTE: $ is not safe for the shell, but it is allowed here because of linker options like -Wl,$ORIGIN.
|
||||||
// We never pass these arguments to a shell (just to programs we construct argv for), so this should be okay.
|
// We never pass these arguments to a shell (just to programs we construct argv for), so this should be okay.
|
||||||
// See golang.org/issue/6038.
|
// See golang.org/issue/6038.
|
||||||
|
@ -231,3 +231,33 @@ func TestImportCmd(t *testing.T) {
|
|||||||
t.Fatalf("Import cmd/internal/objfile returned Dir=%q, want %q", filepath.ToSlash(p.Dir), ".../src/cmd/internal/objfile")
|
t.Fatalf("Import cmd/internal/objfile returned Dir=%q, want %q", filepath.ToSlash(p.Dir), ".../src/cmd/internal/objfile")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
expandSrcDirPath = filepath.Join(string(filepath.Separator)+"projects", "src", "add")
|
||||||
|
)
|
||||||
|
|
||||||
|
var expandSrcDirTests = []struct {
|
||||||
|
input, expected string
|
||||||
|
}{
|
||||||
|
{"-L ${SRCDIR}/libs -ladd", "-L /projects/src/add/libs -ladd"},
|
||||||
|
{"${SRCDIR}/add_linux_386.a -pthread -lstdc++", "/projects/src/add/add_linux_386.a -pthread -lstdc++"},
|
||||||
|
{"Nothing to expand here!", "Nothing to expand here!"},
|
||||||
|
{"$", "$"},
|
||||||
|
{"$$", "$$"},
|
||||||
|
{"${", "${"},
|
||||||
|
{"$}", "$}"},
|
||||||
|
{"$FOO ${BAR}", "$FOO ${BAR}"},
|
||||||
|
{"Find me the $SRCDIRECTORY.", "Find me the $SRCDIRECTORY."},
|
||||||
|
{"$SRCDIR is missing braces", "$SRCDIR is missing braces"},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExpandSrcDir(t *testing.T) {
|
||||||
|
for _, test := range expandSrcDirTests {
|
||||||
|
output := expandSrcDir(test.input, expandSrcDirPath)
|
||||||
|
if output != test.expected {
|
||||||
|
t.Errorf("%q expands to %q with SRCDIR=%q when %q is expected", test.input, output, expandSrcDirPath, test.expected)
|
||||||
|
} else {
|
||||||
|
t.Logf("%q expands to %q with SRCDIR=%q", test.input, output, expandSrcDirPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user