Skip to content

Commit

Permalink
Find embedsrcs built in different configurations
Browse files Browse the repository at this point in the history
Previously, embedsrcs under configuration roots different from that of
the Go target itself or its source files weren't found.

This is fixed by considering all combinations of roots of embedsrcs and
root-relative paths of source files and compilation outputs.
  • Loading branch information
fmeum committed Apr 11, 2022
1 parent 451f267 commit 6f21523
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 18 deletions.
23 changes: 23 additions & 0 deletions go/private/actions/compilepkg.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ def _archive(v):
v.data.export_file.path if v.data.export_file else v.data.file.path,
)

def _embedroot_arg(src):
return src.root.path

def _embedlookupdir_arg(src):
root_relative = src.dirname[len(src.root.path):]
if root_relative.startswith("/"):
root_relative = root_relative[len("/"):]
return root_relative

def emit_compilepkg(
go,
sources = None,
Expand Down Expand Up @@ -66,6 +75,20 @@ def emit_compilepkg(
args = go.builder_args(go, "compilepkg")
args.add_all(sources, before_each = "-src")
args.add_all(embedsrcs, before_each = "-embedsrc", expand_directories = False)
args.add_all(
embedsrcs,
map_each = _embedroot_arg,
before_each = "-embedroot",
uniquify = True,
expand_directories = False,
)
args.add_all(
sources + [out_lib],
map_each = _embedlookupdir_arg,
before_each = "-embedlookupdir",
uniquify = True,
expand_directories = False,
)
if cover and go.coverdata:
inputs.append(go.coverdata.data.export_file)
args.add("-arc", _archive(go.coverdata))
Expand Down
42 changes: 24 additions & 18 deletions go/tools/builders/compilepkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func compilePkg(args []string) error {

fs := flag.NewFlagSet("GoCompilePkg", flag.ExitOnError)
goenv := envFlags(fs)
var unfilteredSrcs, coverSrcs, embedSrcs multiFlag
var unfilteredSrcs, coverSrcs, embedSrcs, embedLookupDirs, embedRoots multiFlag
var deps archiveMultiFlag
var importPath, packagePath, nogoPath, packageListPath, coverMode string
var outPath, outFactsPath, cgoExportHPath string
Expand All @@ -49,6 +49,8 @@ func compilePkg(args []string) error {
fs.Var(&unfilteredSrcs, "src", ".go, .c, .cc, .m, .mm, .s, or .S file to be filtered and compiled")
fs.Var(&coverSrcs, "cover", ".go file that should be instrumented for coverage (must also be a -src)")
fs.Var(&embedSrcs, "embedsrc", "file that may be compiled into the package with a //go:embed directive")
fs.Var(&embedLookupDirs, "embedlookupdir", "Root-relative paths to directories relative to which //go:embed directives are resolved")
fs.Var(&embedRoots, "embedroot", "Bazel output root under which a file passed via -embedsrc resides")
fs.Var(&deps, "arc", "Import path, package path, and file name of a direct dependency, separated by '='")
fs.StringVar(&importPath, "importpath", "", "The import path of the package being compiled. Not passed to the compiler, but may be displayed in debug data.")
fs.StringVar(&packagePath, "p", "", "The package path (importmap) of the package being compiled")
Expand Down Expand Up @@ -129,6 +131,8 @@ func compilePkg(args []string) error {
coverMode,
coverSrcs,
embedSrcs,
embedLookupDirs,
embedRoots,
cgoEnabled,
cc,
gcFlags,
Expand All @@ -155,6 +159,8 @@ func compileArchive(
coverMode string,
coverSrcs []string,
embedSrcs []string,
embedLookupDirs []string,
embedRoots []string,
cgoEnabled bool,
cc string,
gcFlags []string,
Expand Down Expand Up @@ -334,24 +340,24 @@ func compileArchive(
// Embed patterns are relative to any one of a list of root directories
// that may contain embeddable files. Source files containing embed patterns
// must be in one of these root directories so the pattern appears to be
// relative to the source file. Usually, there are two roots: the source
// directory, and the output directory (so that generated files are
// embeddable). There may be additional roots if sources are in multiple
// directories (like if there are are generated source files).
var srcDirs []string
srcDirs = append(srcDirs, filepath.Dir(outPath))
for _, src := range srcs.goSrcs {
srcDirs = append(srcDirs, filepath.Dir(src.filename))
}
sort.Strings(srcDirs) // group duplicates to uniq them below.
embedRootDirs := srcDirs[:1]
for _, dir := range srcDirs {
prev := embedRootDirs[len(embedRootDirs)-1]
if dir == prev || strings.HasPrefix(dir, prev+string(filepath.Separator)) {
// Skip duplicates.
continue
// relative to the source file. Due to transitions, source files can reside
// under Bazel roots different from both those of the go srcs and those of
// the compilation output. Thus, we have to consider all combinations of
// Bazel roots embedsrcs and root-relative paths of source files and the
// output binary.
var embedRootDirs []string
for _, root := range embedRoots {
for _, lookupDir := range embedLookupDirs {
embedRootDir := abs(filepath.Join(root, lookupDir))
// Since we are iterating over all combinations of roots and
// root-relative paths, some resulting paths may not exist and
// should be filtered out before being passed to buildEmbedcfgFile.
// Since Bazel uniquified both the roots and the root-relative
// paths, the combinations are automatically unique.
if _, err := os.Stat(embedRootDir); err == nil {
embedRootDirs = append(embedRootDirs, embedRootDir)
}
}
embedRootDirs = append(embedRootDirs, dir)
}
embedcfgPath, err := buildEmbedcfgFile(srcs.goSrcs, embedSrcs, embedRootDirs, workDir)
if err != nil {
Expand Down
9 changes: 9 additions & 0 deletions tests/core/go_library/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ go_test(
"embedsrcs_test.go",
],
embedsrcs = [
":embedsrcs_transitioned",
":embedsrcs_dynamic",
"embedsrcs_test.go",
] + glob(["embedsrcs_static/**"]),
Expand All @@ -130,6 +131,14 @@ embedsrcs_files(
],
)

go_binary(
name = "embedsrcs_transitioned",
srcs = ["empty_main.go"],
out = "embedsrcs_transitioned",
# Causes a transition on the incoming dependency edge.
race = "on",
)

go_binary(
name = "gen_embedsrcs_files",
srcs = ["gen_embedsrcs_files.go"],
Expand Down
12 changes: 12 additions & 0 deletions tests/core/go_library/embedsrcs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ var static embed.FS
//go:embed embedsrcs_dynamic/file embedsrcs_dynamic/dir embedsrcs_dynamic/glob/*
var dynamic embed.FS

//go:embed embedsrcs_transitioned
var transitioned embed.FS

//go:embed *
var star embed.FS

Expand Down Expand Up @@ -84,6 +87,14 @@ func TestFiles(t *testing.T) {
"embedsrcs_dynamic/glob/f",
},
},
{
desc: "transitioned",
fsys: transitioned,
want: []string{
".",
"embedsrcs_transitioned",
},
},
{
desc: "star",
fsys: star,
Expand All @@ -105,6 +116,7 @@ func TestFiles(t *testing.T) {
"embedsrcs_static/glob/f",
"embedsrcs_static/no",
"embedsrcs_test.go",
"embedsrcs_transitioned",
},
},
} {
Expand Down
3 changes: 3 additions & 0 deletions tests/core/go_library/empty_main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package main

func main() {}

0 comments on commit 6f21523

Please sign in to comment.