Skip to content

Commit

Permalink
Support specifying output directory and package name
Browse files Browse the repository at this point in the history
Signed-off-by: tc <[email protected]>
  • Loading branch information
chent1996 authored and lmb committed Feb 2, 2024
1 parent 4d3b55d commit a8894b2
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 40 deletions.
45 changes: 28 additions & 17 deletions cmd/bpf2go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ var targetByGoArch = map[goarch]target{
"s390x": {"bpfeb", "s390"},
}

func run(stdout io.Writer, pkg, outputDir string, args []string) (err error) {
b2g, err := newB2G(stdout, pkg, outputDir, args)
func run(stdout io.Writer, args []string) (err error) {
b2g, err := newB2G(stdout, args)
switch {
case err == nil:
return b2g.convertAll()
Expand Down Expand Up @@ -111,11 +111,9 @@ type bpf2go struct {
makeBase string
}

func newB2G(stdout io.Writer, pkg, outputDir string, args []string) (*bpf2go, error) {
func newB2G(stdout io.Writer, args []string) (*bpf2go, error) {
b2g := &bpf2go{
stdout: stdout,
pkg: pkg,
outputDir: outputDir,
stdout: stdout,
}

fs := flag.NewFlagSet("bpf2go", flag.ContinueOnError)
Expand All @@ -133,7 +131,8 @@ func newB2G(stdout io.Writer, pkg, outputDir string, args []string) (*bpf2go, er
fs.Var(&b2g.cTypes, "type", "`Name` of a type to generate a Go declaration for, may be repeated")
fs.BoolVar(&b2g.skipGlobalTypes, "no-global-types", false, "Skip generating types for map keys and values, etc.")
fs.StringVar(&b2g.outputStem, "output-stem", "", "alternative stem for names of generated files (defaults to ident)")

outDir := fs.String("output-dir", "", "target directory of generated files (defaults to current directory)")
outPkg := fs.String("go-package", "", "package for output go file (default as ENV GOPACKAGE)")
fs.SetOutput(b2g.stdout)
fs.Usage = func() {
fmt.Fprintf(fs.Output(), helpText, fs.Name())
Expand All @@ -145,8 +144,21 @@ func newB2G(stdout io.Writer, pkg, outputDir string, args []string) (*bpf2go, er
return nil, err
}

if *outDir == "" {
var err error
if *outDir, err = os.Getwd(); err != nil {
return nil, err
}
}
b2g.outputDir = *outDir

if *outPkg == "" {
*outPkg = os.Getenv(gopackageEnv)
}
b2g.pkg = *outPkg

if b2g.pkg == "" {
return nil, errors.New("missing package, have you set GOPACKAGE?")
return nil, errors.New("missing package, you should either set the go-package flag or the GOPACKAGE env")
}

if b2g.cc == "" {
Expand Down Expand Up @@ -320,7 +332,12 @@ func (b2g *bpf2go) convert(tgt target, goarches []goarch) (err error) {
stem = fmt.Sprintf("%s_%s_%s", outputStem, tgt.linux, tgt.clang)
}

objFileName := filepath.Join(b2g.outputDir, stem+".o")
absOutPath, err := filepath.Abs(b2g.outputDir)
if err != nil {
return err
}

objFileName := filepath.Join(absOutPath, stem+".o")

cwd, err := os.Getwd()
if err != nil {
Expand Down Expand Up @@ -379,7 +396,7 @@ func (b2g *bpf2go) convert(tgt target, goarches []goarch) (err error) {
}

// Write out generated go
goFileName := filepath.Join(b2g.outputDir, stem+".go")
goFileName := filepath.Join(absOutPath, stem+".go")
goFile, err := os.Create(goFileName)
if err != nil {
return err
Expand Down Expand Up @@ -527,13 +544,7 @@ func collectTargets(targets []string) (map[target][]goarch, error) {
const gopackageEnv = "GOPACKAGE"

func main() {
outputDir, err := os.Getwd()
if err != nil {
fmt.Fprintln(os.Stderr, "Error:", err)
os.Exit(1)
}

if err := run(os.Stdout, os.Getenv(gopackageEnv), outputDir, os.Args[1:]); err != nil {
if err := run(os.Stdout, os.Args[1:]); err != nil {
fmt.Fprintln(os.Stderr, "Error:", err)
os.Exit(1)
}
Expand Down
83 changes: 60 additions & 23 deletions cmd/bpf2go/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ func TestRun(t *testing.T) {
"s390x", // big-endian
}

err = run(io.Discard, "main", modDir, []string{
err = run(io.Discard, []string{
"-go-package", "main",
"-output-dir", modDir,
"-cc", clangBin,
"-target", strings.Join(goarches, ","),
"bar",
Expand Down Expand Up @@ -102,7 +104,7 @@ func main() {

func TestHelp(t *testing.T) {
var stdout bytes.Buffer
err := run(&stdout, "", "", []string{"-help"})
err := run(&stdout, []string{"-help"})
if err != nil {
t.Fatal("Can't execute -help")
}
Expand All @@ -113,15 +115,17 @@ func TestHelp(t *testing.T) {
}

func TestErrorMentionsEnvVar(t *testing.T) {
err := run(io.Discard, "", "", nil)
err := run(io.Discard, nil)
qt.Assert(t, qt.StringContains(err.Error(), gopackageEnv), qt.Commentf("Error should include name of environment variable"))
}

func TestDisableStripping(t *testing.T) {
dir := t.TempDir()
mustWriteFile(t, dir, "test.c", minimalSocketFilter)

err := run(io.Discard, "foo", dir, []string{
err := run(io.Discard, []string{
"-go-package", "foo",
"-output-dir", dir,
"-cc", clangBin(t),
"-strip", "binary-that-certainly-doesnt-exist",
"-no-strip",
Expand Down Expand Up @@ -299,144 +303,177 @@ func TestParseArgs(t *testing.T) {
csource = "testdata/minimal.c"
stem = "a"
)

t.Run("makebase", func(t *testing.T) {
t.Setenv(gopackageEnv, pkg)
basePath, _ := filepath.Abs("barfoo")
args := []string{"-makebase", basePath, stem, csource}
b2g, err := newB2G(&bytes.Buffer{}, pkg, outputDir, args)
b2g, err := newB2G(&bytes.Buffer{}, args)
qt.Assert(t, qt.IsNil(err))
qt.Assert(t, qt.Equals(b2g.makeBase, basePath))
})

t.Run("makebase from env", func(t *testing.T) {
t.Setenv(gopackageEnv, pkg)
basePath, _ := filepath.Abs("barfoo")
args := []string{stem, csource}
t.Setenv("BPF2GO_MAKEBASE", basePath)
b2g, err := newB2G(&bytes.Buffer{}, pkg, outputDir, args)
b2g, err := newB2G(&bytes.Buffer{}, args)
qt.Assert(t, qt.IsNil(err))
qt.Assert(t, qt.Equals(b2g.makeBase, basePath))
})

t.Run("makebase flag overrides env", func(t *testing.T) {
t.Setenv(gopackageEnv, pkg)
basePathFlag, _ := filepath.Abs("barfoo")
basePathEnv, _ := filepath.Abs("foobar")
args := []string{"-makebase", basePathFlag, stem, csource}
t.Setenv("BPF2GO_MAKEBASE", basePathEnv)
b2g, err := newB2G(&bytes.Buffer{}, pkg, outputDir, args)
b2g, err := newB2G(&bytes.Buffer{}, args)
qt.Assert(t, qt.IsNil(err))
qt.Assert(t, qt.Equals(b2g.makeBase, basePathFlag))
})

t.Run("cc defaults to clang", func(t *testing.T) {
t.Setenv(gopackageEnv, pkg)
args := []string{stem, csource}
b2g, err := newB2G(&bytes.Buffer{}, pkg, outputDir, args)
b2g, err := newB2G(&bytes.Buffer{}, args)
qt.Assert(t, qt.IsNil(err))
qt.Assert(t, qt.Equals(b2g.cc, "clang"))
})

t.Run("cc", func(t *testing.T) {
t.Setenv(gopackageEnv, pkg)
args := []string{"-cc", "barfoo", stem, csource}
b2g, err := newB2G(&bytes.Buffer{}, pkg, outputDir, args)
b2g, err := newB2G(&bytes.Buffer{}, args)
qt.Assert(t, qt.IsNil(err))
qt.Assert(t, qt.Equals(b2g.cc, "barfoo"))
})

t.Run("cc from env", func(t *testing.T) {
t.Setenv(gopackageEnv, pkg)
args := []string{stem, csource}
t.Setenv("BPF2GO_CC", "barfoo")
b2g, err := newB2G(&bytes.Buffer{}, pkg, outputDir, args)
b2g, err := newB2G(&bytes.Buffer{}, args)
qt.Assert(t, qt.IsNil(err))
qt.Assert(t, qt.Equals(b2g.cc, "barfoo"))
})

t.Run("cc flag overrides env", func(t *testing.T) {
t.Setenv(gopackageEnv, pkg)
args := []string{"-cc", "barfoo", stem, csource}
t.Setenv("BPF2GO_CC", "foobar")
b2g, err := newB2G(&bytes.Buffer{}, pkg, outputDir, args)
b2g, err := newB2G(&bytes.Buffer{}, args)
qt.Assert(t, qt.IsNil(err))
qt.Assert(t, qt.Equals(b2g.cc, "barfoo"))
})

t.Run("strip defaults to llvm-strip", func(t *testing.T) {
t.Setenv(gopackageEnv, pkg)
args := []string{stem, csource}
b2g, err := newB2G(&bytes.Buffer{}, pkg, outputDir, args)
b2g, err := newB2G(&bytes.Buffer{}, args)
qt.Assert(t, qt.IsNil(err))
qt.Assert(t, qt.Equals(b2g.strip, "llvm-strip"))
})

t.Run("strip", func(t *testing.T) {
t.Setenv(gopackageEnv, pkg)
args := []string{"-strip", "barfoo", stem, csource}
b2g, err := newB2G(&bytes.Buffer{}, pkg, outputDir, args)
b2g, err := newB2G(&bytes.Buffer{}, args)
qt.Assert(t, qt.IsNil(err))
qt.Assert(t, qt.Equals(b2g.strip, "barfoo"))
})

t.Run("strip from env", func(t *testing.T) {
t.Setenv(gopackageEnv, pkg)
args := []string{stem, csource}
t.Setenv("BPF2GO_STRIP", "barfoo")
b2g, err := newB2G(&bytes.Buffer{}, pkg, outputDir, args)
b2g, err := newB2G(&bytes.Buffer{}, args)
qt.Assert(t, qt.IsNil(err))
qt.Assert(t, qt.Equals(b2g.strip, "barfoo"))
})

t.Run("strip flag overrides env", func(t *testing.T) {
t.Setenv(gopackageEnv, pkg)
args := []string{"-strip", "barfoo", stem, csource}
t.Setenv("BPF2GO_STRIP", "foobar")
b2g, err := newB2G(&bytes.Buffer{}, pkg, outputDir, args)
b2g, err := newB2G(&bytes.Buffer{}, args)
qt.Assert(t, qt.IsNil(err))
qt.Assert(t, qt.Equals(b2g.strip, "barfoo"))
})

t.Run("no strip defaults to false", func(t *testing.T) {
t.Setenv(gopackageEnv, pkg)
args := []string{stem, csource}
b2g, err := newB2G(&bytes.Buffer{}, pkg, outputDir, args)
b2g, err := newB2G(&bytes.Buffer{}, args)
qt.Assert(t, qt.IsNil(err))
qt.Assert(t, qt.IsFalse(b2g.disableStripping))
})

t.Run("no strip", func(t *testing.T) {
t.Setenv(gopackageEnv, pkg)
args := []string{"-no-strip", stem, csource}
b2g, err := newB2G(&bytes.Buffer{}, pkg, outputDir, args)
b2g, err := newB2G(&bytes.Buffer{}, args)
qt.Assert(t, qt.IsNil(err))
qt.Assert(t, qt.IsTrue(b2g.disableStripping))
})

t.Run("cflags flag", func(t *testing.T) {
t.Setenv(gopackageEnv, pkg)
args := []string{"-cflags", "x y z", stem, csource}
b2g, err := newB2G(&bytes.Buffer{}, pkg, outputDir, args)
b2g, err := newB2G(&bytes.Buffer{}, args)
qt.Assert(t, qt.IsNil(err))
qt.Assert(t, qt.DeepEquals(b2g.cFlags, []string{"x", "y", "z"}))
})

t.Run("cflags multi flag", func(t *testing.T) {
t.Setenv(gopackageEnv, pkg)
args := []string{"-cflags", "x y z", "-cflags", "u v", stem, csource}
b2g, err := newB2G(&bytes.Buffer{}, pkg, outputDir, args)
b2g, err := newB2G(&bytes.Buffer{}, args)
qt.Assert(t, qt.IsNil(err))
qt.Assert(t, qt.DeepEquals(b2g.cFlags, []string{"u", "v"}))
})

t.Run("cflags flag and args", func(t *testing.T) {
t.Setenv(gopackageEnv, pkg)
args := []string{"-cflags", "x y z", "stem", csource, "--", "u", "v"}
b2g, err := newB2G(&bytes.Buffer{}, pkg, outputDir, args)
b2g, err := newB2G(&bytes.Buffer{}, args)
qt.Assert(t, qt.IsNil(err))
qt.Assert(t, qt.DeepEquals(b2g.cFlags, []string{"x", "y", "z", "u", "v"}))
})

t.Run("cflags from env", func(t *testing.T) {
t.Setenv(gopackageEnv, pkg)
args := []string{stem, csource}
t.Setenv("BPF2GO_CFLAGS", "x y z")
b2g, err := newB2G(&bytes.Buffer{}, pkg, outputDir, args)
b2g, err := newB2G(&bytes.Buffer{}, args)
qt.Assert(t, qt.IsNil(err))
qt.Assert(t, qt.DeepEquals(b2g.cFlags, []string{"x", "y", "z"}))
})

t.Run("cflags flag overrides env", func(t *testing.T) {
t.Setenv(gopackageEnv, pkg)
args := []string{"-cflags", "u v", stem, csource}
t.Setenv("BPF2GO_CFLAGS", "x y z")
b2g, err := newB2G(&bytes.Buffer{}, pkg, outputDir, args)
b2g, err := newB2G(&bytes.Buffer{}, args)
qt.Assert(t, qt.IsNil(err))
qt.Assert(t, qt.DeepEquals(b2g.cFlags, []string{"u", "v"}))
})

t.Run("go package overrides env", func(t *testing.T) {
t.Setenv(gopackageEnv, pkg)
args := []string{"-go-package", "aaa", stem, csource}
b2g, err := newB2G(&bytes.Buffer{}, args)
qt.Assert(t, qt.IsNil(err))
qt.Assert(t, qt.Equals(b2g.pkg, "aaa"))
})

t.Run("output dir", func(t *testing.T) {
t.Setenv(gopackageEnv, pkg)
args := []string{"-output-dir", outputDir, stem, csource}
b2g, err := newB2G(&bytes.Buffer{}, args)
qt.Assert(t, qt.IsNil(err))
qt.Assert(t, qt.Equals(b2g.outputDir, outputDir))
})
}

func TestGoarches(t *testing.T) {
Expand Down

0 comments on commit a8894b2

Please sign in to comment.