github.com/cilium/ebpf@v0.16.0/cmd/bpf2go/gen/compile.go (about)

     1  package gen
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"os/exec"
     7  	"path/filepath"
     8  )
     9  
    10  type CompileArgs struct {
    11  	// Which compiler to use.
    12  	CC string
    13  	// Command used to strip DWARF from the ELF.
    14  	Strip string
    15  	// Flags to pass to the compiler.
    16  	Flags []string
    17  	// Absolute working directory
    18  	Workdir string
    19  	// Absolute input file name
    20  	Source string
    21  	// Absolute output file name
    22  	Dest string
    23  	// Target to compile for, defaults to compiling generic BPF in host endianness.
    24  	Target           Target
    25  	DisableStripping bool
    26  }
    27  
    28  // Compile C to a BPF ELF file.
    29  func Compile(args CompileArgs) error {
    30  	// Default cflags that can be overridden by args.cFlags
    31  	overrideFlags := []string{
    32  		// Code needs to be optimized, otherwise the verifier will often fail
    33  		// to understand it.
    34  		"-O2",
    35  		// Clang defaults to mcpu=probe which checks the kernel that we are
    36  		// compiling on. This isn't appropriate for ahead of time
    37  		// compiled code so force the most compatible version.
    38  		"-mcpu=v1",
    39  	}
    40  
    41  	cmd := exec.Command(args.CC, append(overrideFlags, args.Flags...)...)
    42  	cmd.Stderr = os.Stderr
    43  
    44  	inputDir := filepath.Dir(args.Source)
    45  	relInputDir, err := filepath.Rel(args.Workdir, inputDir)
    46  	if err != nil {
    47  		return err
    48  	}
    49  
    50  	target := args.Target
    51  	if target == (Target{}) {
    52  		target.clang = "bpf"
    53  	}
    54  
    55  	// C flags that can't be overridden.
    56  	if linux := target.linux; linux != "" {
    57  		cmd.Args = append(cmd.Args, "-D__TARGET_ARCH_"+linux)
    58  	}
    59  
    60  	cmd.Args = append(cmd.Args,
    61  		"-Wunused-command-line-argument",
    62  		"-target", target.clang,
    63  		"-c", args.Source,
    64  		"-o", args.Dest,
    65  		// Don't include clang version
    66  		"-fno-ident",
    67  		// Don't output inputDir into debug info
    68  		"-fdebug-prefix-map="+inputDir+"="+relInputDir,
    69  		"-fdebug-compilation-dir", ".",
    70  		// We always want BTF to be generated, so enforce debug symbols
    71  		"-g",
    72  		fmt.Sprintf("-D__BPF_TARGET_MISSING=%q", "GCC error \"The eBPF is using target specific macros, please provide -target that is not bpf, bpfel or bpfeb\""),
    73  	)
    74  	cmd.Dir = args.Workdir
    75  
    76  	if err := cmd.Run(); err != nil {
    77  		return err
    78  	}
    79  
    80  	if args.DisableStripping {
    81  		return nil
    82  	}
    83  
    84  	cmd = exec.Command(args.Strip, "-g", args.Dest)
    85  	cmd.Stderr = os.Stderr
    86  	if err := cmd.Run(); err != nil {
    87  		return fmt.Errorf("strip %s: %w", args.Dest, err)
    88  	}
    89  
    90  	return nil
    91  }