Skip to content

Commit

Permalink
Add external/... prefix to ${SRCDIR} in external repos (#1850)
Browse files Browse the repository at this point in the history
Also update `.bazelversion` to work around failures to fetch external repos.
  • Loading branch information
fmeum committed Aug 1, 2024
1 parent 226b5ab commit bcacc73
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 9 deletions.
3 changes: 3 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# This file contains options passed to Bazel when running tests.
# They are used by Travis CI and by non-Bazel test scripts.

# TODO: Make all tests work with Bzlmod.
common --noenable_bzlmod

build:ci --verbose_failures
build:ci --sandbox_debug
build:ci --spawn_strategy=standalone
Expand Down
2 changes: 1 addition & 1 deletion .bazelversion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7.1.1
7.2.1
94 changes: 94 additions & 0 deletions cmd/gazelle/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4751,3 +4751,97 @@ require (
t.Fatalf("got %s ; want %s; diff %s", string(got), want, cmp.Diff(string(got), want))
}
}

func TestCgoFlagsHaveExternalPrefix(t *testing.T) {
files := []testtools.FileSpec{
{
Path: "external/com_example_foo_v2/go.mod",
Content: "module example.com/foo/v2",
}, {
Path: "external/com_example_foo_v2/cgo_static.go",
Content: `
package duckdb
/*
#cgo LDFLAGS: -lstdc++ -lm -ldl -L${SRCDIR}/deps
*/
import "C"
`,
},
}
dir, cleanup := testtools.CreateFiles(t, files)
defer cleanup()

repoRoot := filepath.Join(dir, "external", "com_example_foo_v2")

args := []string{"update", "-repo_root", repoRoot, "-go_prefix", "example.com/foo/v2", "-go_repository_mode", "-go_repository_module_mode"}
if err := runGazelle(repoRoot, args); err != nil {
t.Fatal(err)
}

testtools.CheckFiles(t, repoRoot, []testtools.FileSpec{
{
Path: "BUILD.bazel",
Content: `
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "foo",
srcs = ["cgo_static.go"],
cgo = True,
clinkopts = ["-lstdc++ -lm -ldl -Lexternal/com_example_foo_v2/deps"],
importpath = "example.com/foo/v2",
importpath_aliases = ["example.com/foo"],
visibility = ["//visibility:public"],
)
`,
},
})
}

func TestCgoFlagsHaveDotDotPrefixWithSiblingRepositoryLayout(t *testing.T) {
files := []testtools.FileSpec{
{
Path: "execroot/com_example_foo_v2/go.mod",
Content: "module example.com/foo/v2",
}, {
Path: "execroot/com_example_foo_v2/cgo_static.go",
Content: `
package duckdb
/*
#cgo LDFLAGS: -lstdc++ -lm -ldl -L${SRCDIR}/deps
*/
import "C"
`,
},
}
dir, cleanup := testtools.CreateFiles(t, files)
defer cleanup()

repoRoot := filepath.Join(dir, "execroot", "com_example_foo_v2")

args := []string{"update", "-repo_root", repoRoot, "-go_prefix", "example.com/foo/v2", "-go_repository_mode", "-go_repository_module_mode"}
if err := runGazelle(repoRoot, args); err != nil {
t.Fatal(err)
}

testtools.CheckFiles(t, repoRoot, []testtools.FileSpec{
{
Path: "BUILD.bazel",
Content: `
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "foo",
srcs = ["cgo_static.go"],
cgo = True,
clinkopts = ["-lstdc++ -lm -ldl -L../com_example_foo_v2/deps"],
importpath = "example.com/foo/v2",
importpath_aliases = ["example.com/foo"],
visibility = ["//visibility:public"],
)
`,
},
})
}
12 changes: 7 additions & 5 deletions language/go/fileinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ func otherFileInfo(path string) fileInfo {
// will be returned.
// This function is intended to match go/build.Context.Import.
// TODD(#53): extract canonical import path
func goFileInfo(path, rel string) fileInfo {
func goFileInfo(path, srcdir string) fileInfo {
info := fileNameInfo(path)
fset := token.NewFileSet()
pf, err := parser.ParseFile(fset, info.path, nil, parser.ImportsOnly|parser.ParseComments)
Expand Down Expand Up @@ -254,7 +254,7 @@ func goFileInfo(path, rel string) fileInfo {
cg = d.Doc
}
if cg != nil {
if err := saveCgo(&info, rel, cg); err != nil {
if err := saveCgo(&info, srcdir, cg); err != nil {
log.Printf("%s: error reading go file: %v", info.path, err)
}
}
Expand Down Expand Up @@ -317,7 +317,7 @@ func goFileInfo(path, rel string) fileInfo {
// saveCgo extracts CFLAGS, CPPFLAGS, CXXFLAGS, and LDFLAGS directives
// from a comment above a "C" import. This is intended to match logic in
// go/build.Context.saveCgo.
func saveCgo(info *fileInfo, rel string, cg *ast.CommentGroup) error {
func saveCgo(info *fileInfo, srcdir string, cg *ast.CommentGroup) error {
text := cg.Text()
for _, line := range strings.Split(text, "\n") {
orig := line
Expand Down Expand Up @@ -355,7 +355,7 @@ func saveCgo(info *fileInfo, rel string, cg *ast.CommentGroup) error {
}

for i, opt := range opts {
if opt, ok = expandSrcDir(opt, rel); !ok {
if opt, ok = expandSrcDir(opt, srcdir); !ok {
return fmt.Errorf("%s: malformed #cgo argument: %s", info.path, orig)
}
opts[i] = opt
Expand Down Expand Up @@ -478,8 +478,10 @@ func expandSrcDir(str string, srcdir string) (string, bool) {
// See golang.org/issue/6038.
// The @ is for OS X. See golang.org/issue/13720.
// The % is for Jenkins. See golang.org/issue/16959.
// The ~ is for Bzlmod as it is used as a separator in repository names. It is special in shells (which we don't pass
// it to) and on Windows (where it can still be part of legitimate short paths).
const (
safeString = "+-.,/0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz:$@%"
safeString = "+-.,/0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz:$@%~"
safeSpaces = " "
)

Expand Down
19 changes: 18 additions & 1 deletion language/go/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func (gl *goLang) GenerateRules(args language.GenerateArgs) language.GenerateRes
// Extract information about proto files. We need this to exclude .pb.go
// files and generate go_proto_library rules.
c := args.Config
gc := getGoConfig(c)
pcMode := getProtoMode(c)

// This is a collection of proto_library rule names that have a corresponding
Expand Down Expand Up @@ -117,11 +118,27 @@ func (gl *goLang) GenerateRules(args language.GenerateArgs) language.GenerateRes
}

// Build a set of packages from files in this directory.
srcdir := args.Rel
if gc.goRepositoryMode {
// cgo opts such as '-L${SRCDIR}/libs' should become
// '-Lexternal/my_repo~/libs' in an external repo.
// We obtain the path from the repo root to support both cases of
// --experimental_sibling_repository_layout.
slashPath := filepath.ToSlash(c.RepoRoot)
segments := strings.Split(slashPath, "/")
repoName := segments[len(segments)-1]
previousSegment := segments[len(segments)-2]
if previousSegment == "external" {
srcdir = path.Join("external", repoName, srcdir)
} else {
srcdir = path.Join("..", repoName, srcdir)
}
}
goFileInfos := make([]fileInfo, len(goFiles))
var er *embedResolver
for i, name := range goFiles {
path := filepath.Join(args.Dir, name)
goFileInfos[i] = goFileInfo(path, args.Rel)
goFileInfos[i] = goFileInfo(path, srcdir)
if len(goFileInfos[i].embeds) > 0 && er == nil {
er = newEmbedResolver(args.Dir, args.Rel, c.ValidBuildFileNames, gl.goPkgRels, args.Subdirs, args.RegularFiles, args.GenFiles)
}
Expand Down
2 changes: 1 addition & 1 deletion tests/bcr/go_mod/.bazelversion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7.1.1
7.2.1
2 changes: 1 addition & 1 deletion tests/bcr/go_work/.bazelversion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7.0.2
7.2.1

0 comments on commit bcacc73

Please sign in to comment.