diff --git a/cmd/bpf2go/gen/compile.go b/cmd/bpf2go/gen/compile.go index efd05fb6d..954c81d00 100644 --- a/cmd/bpf2go/gen/compile.go +++ b/cmd/bpf2go/gen/compile.go @@ -7,6 +7,7 @@ import ( "os" "os/exec" "path/filepath" + "strings" ) type CompileArgs struct { @@ -14,7 +15,7 @@ type CompileArgs struct { CC string // Command used to strip DWARF from the ELF. Strip string - // Flags to pass to the compiler. + // Flags to pass to the compiler. This may contain positional arguments as well. Flags []string // Absolute working directory Workdir string @@ -27,9 +28,8 @@ type CompileArgs struct { DisableStripping bool } -// Compile C to a BPF ELF file. -func Compile(args CompileArgs) error { - // Default cflags that can be overridden by args.cFlags +func insertDefaultFlags(flags []string) []string { + // Default cflags that can be overridden by the user. overrideFlags := []string{ // Code needs to be optimized, otherwise the verifier will often fail // to understand it. @@ -40,7 +40,26 @@ func Compile(args CompileArgs) error { "-mcpu=v1", } - cmd := exec.Command(args.CC, append(overrideFlags, args.Flags...)...) + insert := 0 + + // Find the first non-positional argument to support CC commands with + // multiple components. E.g.: BPF2GO_CC="ccache clang" ... + for ; insert < len(flags); insert++ { + if strings.HasPrefix(flags[insert], "-") { + break + } + } + + result := append([]string(nil), flags[:insert]...) + result = append(result, overrideFlags...) + result = append(result, flags[insert:]...) + + return result +} + +// Compile C to a BPF ELF file. +func Compile(args CompileArgs) error { + cmd := exec.Command(args.CC, insertDefaultFlags(args.Flags)...) cmd.Stderr = os.Stderr inputDir := filepath.Dir(args.Source) diff --git a/cmd/bpf2go/main.go b/cmd/bpf2go/main.go index b8e8deebb..a0da0838e 100644 --- a/cmd/bpf2go/main.go +++ b/cmd/bpf2go/main.go @@ -155,9 +155,12 @@ func newB2G(stdout io.Writer, args []string) (*bpf2go, error) { return nil, errors.New("missing package, you should either set the go-package flag or the GOPACKAGE env") } - if b2g.cc == "" { + // Allow CC like "ccache clang" to work. + ccParts := strings.Fields(b2g.cc) + if len(ccParts) == 0 { return nil, errors.New("no compiler specified") } + b2g.cc = ccParts[0] args, cFlags := splitCFlagsFromArgs(fs.Args()) @@ -178,7 +181,7 @@ func newB2G(stdout io.Writer, args []string) (*bpf2go, error) { } } - b2g.cFlags = cFlags[:len(cFlags):len(cFlags)] + b2g.cFlags = append(ccParts[1:], cFlags[:len(cFlags):len(cFlags)]...) if len(args) < 2 { return nil, errors.New("expected at least two arguments")