-
Notifications
You must be signed in to change notification settings - Fork 17.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cmd/go: fix -gcflags, -ldflags not applying to current directory
A flag setting like -gcflags=-e applies only to the packages named on the command line, not to their dependencies. The way we used to implement this was to remember the command line arguments, reinterpret them as pattern matches instead of package argument generators (globs), and apply them during package load. The reason for this complexity was to address a command-line like: go build -gcflags=-e fmt runtime The load of fmt will load dependencies, including runtime, and the load of runtime will reuse the result of the earlier load. Because we were computing the effective -gcflags for each package during the load, we had to have a way to tell, when encountering runtime during the load of fmt, that runtime had been named on the command line, even though we hadn't gotten that far. That would be easy if the only possible arguments were import paths, but we also need to handle go build -gcflags=-e fmt runt... go build -gcflags=-e fmt $GOROOT/src/runtime go build -gcflags=-e fmt $GOROOT/src/runt... and so on. The match predicates usually did their job well, but not always. In particular, thanks to symlinks and case-insensitive file systems and unusual ways to spell file paths, it's always been possible in various corner cases to give an argument that evalutes to the runtime package during loading but failed to match it when reused to determine "was this package named on the command line?" CL 109235 fixed one instance of this problem by making a directory pattern match case-insensitive on Windows, but that is incorrect in some other cases and doesn't address the root problem, namely that there will probably always be odd corner cases where pattern matching and pattern globbing are not exactly aligned. This CL eliminates the assumption that pattern matching and pattern globbing are always completely in agreement, by simply marking the packages named on the command line after the package load returns them. This means delaying the computation of tool flags until after the load too, for a few different ways packages are loaded. The different load entry points add some complexity, which is why the original approach seemed more attractive, but the original approach had complexity that we simply didn't recognize at the time. This CL then rolls back the CL 109235 pattern-matching change, but it keeps the test introduced in that CL. That test still passes. In addition to fixing ambiguity due to case-sensitive file systems, this new approach also very likely fixes various ambiguities that might arise from abuse of symbolic links. Fixes #24232. Fixes #24456. Fixes #24750. Fixes #25046. Fixes #25878. Change-Id: I0b09825785dfb5112fb11494cff8527ebf57966f Reviewed-on: https://go-review.googlesource.com/129059 Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Alan Donovan <adonovan@google.com>
- Loading branch information
Showing
6 changed files
with
128 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
[!gc] skip 'using -gcflags and -ldflags' | ||
|
||
# -gcflags=-e applies to named packages, not dependencies | ||
go build -n -v -gcflags=-e z1 z2 | ||
stderr 'compile.* -e .*-p z1' | ||
stderr 'compile.* -e .*-p z2' | ||
stderr 'compile.* -p y' | ||
! stderr 'compile.* -e .*-p [^z]' | ||
|
||
# -gcflags can specify package=flags, and can be repeated; last match wins | ||
go build -n -v -gcflags=-e -gcflags=z1=-N z1 z2 | ||
stderr 'compile.* -N .*-p z1' | ||
! stderr 'compile.* -e .*-p z1' | ||
! stderr 'compile.* -N .*-p z2' | ||
stderr 'compile.* -e .*-p z2' | ||
stderr 'compile.* -p y' | ||
! stderr 'compile.* -e .*-p [^z]' | ||
! stderr 'compile.* -N .*-p [^z]' | ||
|
||
# -gcflags can have arbitrary spaces around the flags | ||
go build -n -v -gcflags=' z1 = -e ' z1 | ||
stderr 'compile.* -e .*-p z1' | ||
|
||
# -ldflags for implicit test package applies to test binary | ||
go test -c -n -gcflags=-N -ldflags=-X=x.y=z z1 | ||
stderr 'compile.* -N .*z_test.go' | ||
stderr 'link.* -X=x.y=z' | ||
|
||
# -ldflags for explicit test package applies to test binary | ||
go test -c -n -gcflags=z1=-N -ldflags=z1=-X=x.y=z z1 | ||
stderr 'compile.* -N .*z_test.go' | ||
stderr 'link.* -X=x.y=z' | ||
|
||
# -ldflags applies to link of command | ||
go build -n -ldflags=-X=math.pi=3 my/cmd/prog | ||
stderr 'link.* -X=math.pi=3' | ||
|
||
# -ldflags applies to link of command even with strange directory name | ||
go build -n -ldflags=-X=math.pi=3 my/cmd/prog/ | ||
stderr 'link.* -X=math.pi=3' | ||
|
||
# -ldflags applies to current directory | ||
cd my/cmd/prog | ||
go build -n -ldflags=-X=math.pi=3 | ||
stderr 'link.* -X=math.pi=3' | ||
|
||
# -ldflags applies to current directory even if GOPATH is funny | ||
[windows] cd $WORK/GoPath/src/my/cmd/prog | ||
[darwin] cd $WORK/GoPath/src/my/cmd/prog | ||
go build -n -ldflags=-X=math.pi=3 | ||
stderr 'link.* -X=math.pi=3' | ||
|
||
-- z1/z.go -- | ||
package z1 | ||
import _ "y" | ||
import _ "z2" | ||
|
||
-- z1/z_test.go -- | ||
package z1_test | ||
import "testing" | ||
func Test(t *testing.T) {} | ||
|
||
-- z2/z.go -- | ||
package z2 | ||
|
||
-- y/y.go -- | ||
package y | ||
|
||
-- my/cmd/prog/prog.go -- | ||
package main | ||
func main() {} |