Commit 4891a3b6 authored by Russ Cox's avatar Russ Cox

cmd/internal/objabi: expand -trimpath syntax

This CL affects the low-level -trimpath flag provided
by both cmd/asm and cmd/compile. Previously, the flag
took the name of a single directory that would be trimmed
from recorded paths in the resulting object file.
This CL makes the flag take a semicolon-separated list of paths.
Further, each path can now end in an optional "=>replacement"
to specify what to replace that leading path prefix with,
instead of only dropping it.

A followup CL will add a mode to cmd/go that uses this
richer -trimpath to build binaries that do not contain any
local path names.

For #16860.

Change-Id: I246811750f37607c7f7a8fbecd56c5475ebe1ea5
Reviewed-on: https://go-review.googlesource.com/c/go/+/173344
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarJay Conrod <jayconrod@google.com>
parent 97dfbc54
...@@ -7,6 +7,7 @@ package objabi ...@@ -7,6 +7,7 @@ package objabi
import ( import (
"os" "os"
"path/filepath" "path/filepath"
"strings"
) )
// WorkingDir returns the current working directory // WorkingDir returns the current working directory
...@@ -21,32 +22,63 @@ func WorkingDir() string { ...@@ -21,32 +22,63 @@ func WorkingDir() string {
return filepath.ToSlash(path) return filepath.ToSlash(path)
} }
// AbsFile returns the absolute filename for file in the given directory. // AbsFile returns the absolute filename for file in the given directory,
// It also removes a leading pathPrefix, or else rewrites a leading $GOROOT // as rewritten by the rewrites argument.
// prefix to the literal "$GOROOT". // For unrewritten paths, AbsFile rewrites a leading $GOROOT prefix to the literal "$GOROOT".
// If the resulting path is the empty string, the result is "??". // If the resulting path is the empty string, the result is "??".
func AbsFile(dir, file, pathPrefix string) string { //
// The rewrites argument is a ;-separated list of rewrites.
// Each rewrite is of the form "prefix" or "prefix=>replace",
// where prefix must match a leading sequence of path elements
// and is either removed entirely or replaced by the replacement.
func AbsFile(dir, file, rewrites string) string {
abs := file abs := file
if dir != "" && !filepath.IsAbs(file) { if dir != "" && !filepath.IsAbs(file) {
abs = filepath.Join(dir, file) abs = filepath.Join(dir, file)
} }
if pathPrefix != "" && hasPathPrefix(abs, pathPrefix) { start := 0
if abs == pathPrefix { for i := 0; i <= len(rewrites); i++ {
abs = "" if i == len(rewrites) || rewrites[i] == ';' {
} else { if new, ok := applyRewrite(abs, rewrites[start:i]); ok {
abs = abs[len(pathPrefix)+1:] abs = new
goto Rewritten
} }
} else if hasPathPrefix(abs, GOROOT) { start = i + 1
}
}
if hasPathPrefix(abs, GOROOT) {
abs = "$GOROOT" + abs[len(GOROOT):] abs = "$GOROOT" + abs[len(GOROOT):]
} }
Rewritten:
if abs == "" { if abs == "" {
abs = "??" abs = "??"
} }
return abs return abs
} }
// applyRewrite applies the rewrite to the path,
// returning the rewritten path and a boolean
// indicating whether the rewrite applied at all.
func applyRewrite(path, rewrite string) (string, bool) {
prefix, replace := rewrite, ""
if j := strings.LastIndex(rewrite, "=>"); j >= 0 {
prefix, replace = rewrite[:j], rewrite[j+len("=>"):]
}
if prefix == "" || !hasPathPrefix(path, prefix) {
return path, false
}
if len(path) == len(prefix) {
return replace, true
}
if replace == "" {
return path[len(prefix)+1:], true
}
return replace + path[len(prefix):], true
}
// Does s have t as a path prefix? // Does s have t as a path prefix?
// That is, does s == t or does s begin with t followed by a slash? // That is, does s == t or does s begin with t followed by a slash?
// For portability, we allow ASCII case folding, so that hasPathPrefix("a/b/c", "A/B") is true. // For portability, we allow ASCII case folding, so that hasPathPrefix("a/b/c", "A/B") is true.
......
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package objabi
import (
"path/filepath"
"runtime"
"testing"
)
// On Windows, "/foo" is reported as a relative path
// (it is relative to the current drive letter),
// so we need add a drive letter to test absolute path cases.
func drive() string {
if runtime.GOOS == "windows" {
return "c:"
}
return ""
}
var absFileTests = []struct {
dir string
file string
rewrites string
abs string
}{
{"/d", "f", "", "/d/f"},
{"/d", drive() + "/f", "", drive() + "/f"},
{"/d", "f/g", "", "/d/f/g"},
{"/d", drive() + "/f/g", "", drive() + "/f/g"},
{"/d", "f", "/d/f", "??"},
{"/d", "f/g", "/d/f", "g"},
{"/d", "f/g", "/d/f=>h", "h/g"},
{"/d", "f/g", "/d/f=>/h", "/h/g"},
{"/d", "f/g", "/d/f=>/h;/d/e=>/i", "/h/g"},
{"/d", "e/f", "/d/f=>/h;/d/e=>/i", "/i/f"},
}
func TestAbsFile(t *testing.T) {
for _, tt := range absFileTests {
abs := filepath.FromSlash(AbsFile(filepath.FromSlash(tt.dir), filepath.FromSlash(tt.file), tt.rewrites))
want := filepath.FromSlash(tt.abs)
if abs != want {
t.Errorf("AbsFile(%q, %q, %q) = %q, want %q", tt.dir, tt.file, tt.rewrites, abs, want)
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment