samples: zephyr: Add separate compilation
Create a program that separately compiles the tests and assembles them
into a zip file. This will help when the build environment and the test
environment are not the same machine.
Signed-off-by: David Brown <david.brown@linaro.org>
diff --git a/samples/zephyr/test-compile.go b/samples/zephyr/test-compile.go
new file mode 100644
index 0000000..fba613f
--- /dev/null
+++ b/samples/zephyr/test-compile.go
@@ -0,0 +1,156 @@
+// +build ignore
+//
+// Build all of the tests.
+//
+// Run as:
+//
+// go run test-compile.go -out name.tar
+
+package main
+
+import (
+ "archive/zip"
+ "flag"
+ "fmt"
+ "io"
+ "log"
+ "os"
+ "os/exec"
+ "path"
+
+ "github.com/JuulLabs-OSS/mcuboot/samples/zephyr/mcutests"
+)
+
+var outFile = flag.String("out", "test-images.zip", "Name of zip file to put built tests into")
+
+func main() {
+ err := run()
+ if err != nil {
+ log.Fatal(err)
+ }
+}
+
+func run() error {
+ flag.Parse()
+
+ zipper, err := NewBuilds()
+ if err != nil {
+ return err
+ }
+ defer zipper.Close()
+
+ for _, group := range mcutests.Tests {
+ fmt.Printf("Compiling %q\n", group.ShortName)
+ c := exec.Command("make",
+ fmt.Sprintf("test-%s", group.ShortName))
+ // TODO: Should capture the output and show it if
+ // there is an error.
+ err = c.Run()
+ if err != nil {
+ return err
+ }
+
+ err = zipper.Capture(group.ShortName)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// A Builds create a zipfile of the contents of various builds. The
+// names will be constructed.
+type Builds struct {
+ // The file being written to.
+ file *os.File
+
+ // The zip writer writing the data.
+ zip *zip.Writer
+}
+
+func NewBuilds() (*Builds, error) {
+ name := *outFile
+ file, err := os.OpenFile(name, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0644)
+ if err != nil {
+ return nil, err
+ }
+
+ z := zip.NewWriter(file)
+
+ return &Builds{
+ file: file,
+ zip: z,
+ }, nil
+}
+
+func (b *Builds) Close() error {
+ return b.zip.Close()
+}
+
+func (b *Builds) Capture(testName string) error {
+ // Collect stat information from the test directory, which
+ // should be close enough to make the zip file meaningful.
+ info, err := os.Stat(".")
+ if err != nil {
+ return err
+ }
+
+ header, err := zip.FileInfoHeader(info)
+ if err != nil {
+ return err
+ }
+
+ header.Name = testName + "/"
+
+ _, err = b.zip.CreateHeader(header)
+ if err != nil {
+ return err
+ }
+
+ for _, name := range []string{
+ "mcuboot.bin",
+ "signed-hello1.bin",
+ "signed-hello2.bin",
+ } {
+ err = b.add(testName, name, name)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (b *Builds) add(baseName, zipName, fileName string) error {
+ inp, err := os.Open(fileName)
+ if err != nil {
+ return err
+ }
+ defer inp.Close()
+
+ info, err := inp.Stat()
+ if err != nil {
+ return err
+ }
+
+ header, err := zip.FileInfoHeader(info)
+ if err != nil {
+ return err
+ }
+
+ header.Name = path.Join(baseName, zipName)
+ header.Method = zip.Deflate
+
+ wr, err := b.zip.CreateHeader(header)
+ if err != nil {
+ return err
+ }
+
+ _, err = io.Copy(wr, inp)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}