github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/uroot/builder/bb.go (about)

     1  // Copyright 2015-2017 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package builder
     6  
     7  import (
     8  	"fmt"
     9  	"path"
    10  	"path/filepath"
    11  
    12  	"github.com/u-root/u-root/pkg/bb"
    13  	"github.com/u-root/u-root/pkg/cpio"
    14  	"github.com/u-root/u-root/pkg/uroot/initramfs"
    15  )
    16  
    17  // Commands to skip building in bb mode.
    18  var skip = map[string]struct{}{
    19  	"bb": {},
    20  }
    21  
    22  // BBBuilder is an implementation of Builder that compiles many Go commands
    23  // into one busybox-style binary.
    24  //
    25  // BBBuilder will also include symlinks for each command to the busybox binary.
    26  //
    27  // BBBuilder does all this by rewriting the source files of the packages given
    28  // to create one busybox-like binary containing all commands.
    29  //
    30  // The compiled binary uses argv[0] to decide which Go command to run.
    31  //
    32  // See bb/README.md for a detailed explanation of the implementation of busybox
    33  // mode.
    34  type BBBuilder struct{}
    35  
    36  // DefaultBinaryDir implements Builder.DefaultBinaryDir.
    37  //
    38  // The default initramfs binary dir is bbin for busybox binaries.
    39  func (BBBuilder) DefaultBinaryDir() string {
    40  	return "bbin"
    41  }
    42  
    43  // Build is an implementation of Builder.Build for a busybox-like initramfs.
    44  func (BBBuilder) Build(af *initramfs.Files, opts Opts) error {
    45  	// Build the busybox binary.
    46  	bbPath := filepath.Join(opts.TempDir, "bb")
    47  	if err := bb.BuildBusybox(opts.Env, opts.Packages, opts.NoStrip, bbPath); err != nil {
    48  		return err
    49  	}
    50  
    51  	if len(opts.BinaryDir) == 0 {
    52  		return fmt.Errorf("must specify binary directory")
    53  	}
    54  
    55  	if err := af.AddFile(bbPath, path.Join(opts.BinaryDir, "bb")); err != nil {
    56  		return err
    57  	}
    58  
    59  	// Add symlinks for included commands to initramfs.
    60  	for _, pkg := range opts.Packages {
    61  		if _, ok := skip[path.Base(pkg)]; ok {
    62  			continue
    63  		}
    64  
    65  		// Add a symlink /bbin/{cmd} -> /bbin/bb to our initramfs.
    66  		if err := af.AddRecord(cpio.Symlink(filepath.Join(opts.BinaryDir, path.Base(pkg)), "bb")); err != nil {
    67  			return err
    68  		}
    69  	}
    70  	return nil
    71  }