]> xenbits.xensource.com Git - people/gdunlap/xsatool.git/commitdiff
Allow config-specified build sequences
authorGeorge Dunlap <george.dunlap@citrix.com>
Wed, 11 Dec 2019 15:55:32 +0000 (15:55 +0000)
committerGeorge Dunlap <george.dunlap@citrix.com>
Wed, 11 Dec 2019 15:55:32 +0000 (15:55 +0000)
At the moment, the sequence of steps used to to a build test of XSA
recipes is hardcoded to `./configure` followed by `make -j 8`.
Sometimes you may want to run other sequences of commands; for
instance to decrease build times or required dependencies.

Add the concept of a "build sequence" to the config file.  This is a
series of commands which will be run.

Add BuildSequences and DefaultBuildSequence to the config file.

Refactor test() to be able to handle either "-buildsequence" or "-bs"
arguments mixed in with the version numbers.  If this isn't set, use
the value from the config file (which may be empty).

If the final value is non-empty, use the sequence of commands defined
in the config file (returning an error if it's not present); if it's
empty, use the existing built-in sequences.

Modify `xsatool repo init` to contain a standard set of pre-defined
build sequences.

Document all this in README.md.

While here do a number of other minor clean-ups instigated by `go fmt`
and delete-trailing-whitespace.

Signed-off-by: George Dunlap <george.dunlap@citrix.com>
README.md
meta.go
recipe.go
repo.go
test.go

index b056741cfe6fed2b443caab9104a8f6c99f4431d..fd031de787b69b539018c8e6f845ccec1c308467 100644 (file)
--- a/README.md
+++ b/README.md
@@ -187,6 +187,9 @@ rerere.enabled true`.)
 The `--mirrordir` or `--git-proxy` arguments can be used to specify a
 cache used for git clones *during build*.
 
+- Finally, it will set up some useful "build sequences" (series of
+pre-set commands used to do the builds), and set the default.
+
 ## Creating the initial global metadata
 
 `xsatool global update`
@@ -423,18 +426,49 @@ supplied, it defaults to `all`.)
 
 Individual versions can be specified as well: `xsatool 213 test-apply 4.6 4.5`
 
-`xsatool 213 test-build [<versionlist>]`
+`xsatool 213 test-build [-buildsequence <buildsequence> | <versionlist>]`
 
 For each version in `<versionlist>`, it will attempt to check out a
 tree based on `test/213/$v` and do a build.  If the branch does not
 exist it will throw an error.  (If no `<versionlist>` is supplied, it
 defaults to `all`.)  Output will be redirected to `build.log`.
 
-`xsatool 213 test [<versionlist>]`
+`xsatool 213 test [-buildsequence <buildsequence> | <versionlist>]`
 
 Do both `test-apply` and `test-build` (i.e., a full test) for each
 version.
 
+## Build sequences
+
+When `xsatool` tests a build, it executes a sequence of commands.  The
+default sequence is: `./configure`, then `make -j 8`.
+
+Other sequences can be defined in the `.xsatool` file.  Alternate build sequences
+can be specified by name; for example:
+
+    xsatool 213 test master -buildsequence xen
+
+Will attempt to apply the XSA-213 recipe to master, and then run the
+`xen` build sequence as defined in the `.xsatool` config file.
+
+You might do this in order to speed up testing (if all the changes are
+in Xen and you want to do a quick sanity-check rather than full
+builds), or to avoid having to install extraneous dependencies (for
+instance, if your build fails due to missing newlib dependencies which
+have nothing to do with the patch you're trying to test).
+
+`xen repo init` will pre-define several recipes:
+
+* `simple`: "Plain vanilla" upstream build, with nothing disabled.
+
+* `xen`: Build only the hypervisor.  Does not execute `./configure`.
+
+* `xentools`: Attempt to build only the hypervisor and in-tree tools.
+Disable all out-of-tree builds, as well as stubdoms, but *don't*
+disable the pvshim.
+
+The default is set to `simple`.
+
 ## Viewing patches that another developer has created
 
 Suppose instead you want to review another developer's series; or
diff --git a/meta.go b/meta.go
index 5ac63fe99f48fc3d9009074e959a62bcebb2457c..315d4aaa8ac54c131b402b55127de2b22a00af16 100644 (file)
--- a/meta.go
+++ b/meta.go
@@ -17,7 +17,7 @@ const (
        TreeQemuT = "qemut"
        TreeXSA   = "xsa"
        // FIXME: This isn't really a tree...
-       TreeWork  = "worktree"
+       TreeWork = "worktree"
 )
 
 var TreeListAll = []Tree{TreeXen, TreeQemuU, TreeQemuT, TreeXSA}
@@ -82,9 +82,11 @@ type ToolConfig struct {
                MirrorDir string
                ProxyURL  string
        }
+       BuildSequences       map[string]BuildSequence
+       DefaultBuildSequence string
        // Not saved
        rootDir string
-       loaded bool
+       loaded  bool
 }
 
 const ConfigFileName = ".xsatool"
@@ -133,7 +135,7 @@ func (tc *ToolConfig) Load() (err error) {
        if err == nil {
                tc.loaded = true
        }
-       
+
        return
 }
 
@@ -295,7 +297,7 @@ func (m *XSAMeta) NewRecipe(v XenVersion) *Recipe {
 
 // Return 'true' if there's a recipe (even empty)
 func (m *XSAMeta) HasRecipe(v XenVersion) bool {
-       return m.GetRecipe(v) != nil 
+       return m.GetRecipe(v) != nil
 }
 
 // Return 'true' if:
index e017332dfa69a4a461c3e6c7ad975c2012dbce18..bccfb0104ae8a79e63b1cc2721c40de5347e2158 100644 (file)
--- a/recipe.go
+++ b/recipe.go
@@ -8,6 +8,7 @@ import (
        "path"
        "path/filepath"
        "strconv"
+       "strings"
 )
 
 type TreeRecipe struct {
@@ -24,7 +25,7 @@ type Recipe struct {
        Recipes map[Tree]*TreeRecipe
        // Data not exported to JSON.  Must be re-constructed on load.
        XenVersion `json:"-"`
-       xsa     int
+       xsa        int
 }
 
 const FPPath = "/tmp/xsatool-formatpatch"
@@ -114,7 +115,7 @@ func (r *Recipe) HasPatches() (has bool) {
 }
 
 // Return 'true' if all repo branches are valid, and contain patches
-func (r *Recipe) RepoHasPatches(prefix string) (bool) {
+func (r *Recipe) RepoHasPatches(prefix string) bool {
        _, baseline, branch := r.branchName(prefix)
 
        err := r.ForEachTree(func(tree Tree) error {
@@ -140,7 +141,7 @@ func (r *Recipe) RepoHasPatches(prefix string) (bool) {
 
                return nil
        })
-       
+
        return err == nil
 }
 
@@ -419,7 +420,7 @@ func (r *Recipe) ApplyPatches(prefix string) (err error) {
                                return fmt.Errorf("Appling am %s: %v\n", glob, err)
                        }
                }
-               
+
                return
        }
 
@@ -546,7 +547,23 @@ func (r *Recipe) Backport(prefix string, to XenVersion) (err error) {
        return
 }
 
-func (r *Recipe) Build(prefix string) (err error) {
+type BuildSequence []string
+
+var defaultBuildSequence = BuildSequence{
+       "./configure",
+       "make -j 8",
+}
+
+func (r *Recipe) Build(prefix string, bsName string) (err error) {
+       bs := defaultBuildSequence
+
+       if bsName != "" {
+               var prs bool
+               if bs, prs = G.config.Tool.BuildSequences[bsName]; !prs {
+                       return fmt.Errorf("No such buildsequence: %s", bsName)
+               }
+       }
+
        _, _, branch := r.branchName(prefix)
 
        repo := G.repos.GetRepoNC(TreeXen).Repo
@@ -559,7 +576,7 @@ func (r *Recipe) Build(prefix string) (err error) {
        }
 
        var wt *Worktree
-       
+
        /* Always check out a temporary branch for xen */
        tmpBranch := "xsa/tmp"
 
@@ -567,7 +584,7 @@ func (r *Recipe) Build(prefix string) (err error) {
        if wtPath != "" {
                // build-NNN-VV
                name := fmt.Sprintf("build-%d-%v", r.xsa, r.XenVersion)
-               
+
                wt, err = repo.WorktreeAdd(wtPath, name, wtbranch)
                if err != nil {
                        return
@@ -624,21 +641,17 @@ func (r *Recipe) Build(prefix string) (err error) {
        }
        defer logfile.Close()
 
-       cmd := exec.Command("./configure")
-       cmd.Stdout = logfile
-       cmd.Stderr = logfile
-       err = cmd.Run()
-       if err != nil {
-               return fmt.Errorf("Configuring xen: %v\n", err)
-       }
-
-       // Build
-       cmd = exec.Command("make", "-j", "8")
-       cmd.Stdout = logfile
-       cmd.Stderr = logfile
-       err = cmd.Run()
-       if err != nil {
-               return fmt.Errorf("Building: %v\n", err)
+       for i := range bs {
+               fmt.Println("[" + bs[i] + "]")
+               s := strings.Split(bs[i], " ")
+               cmd := exec.Command(s[0], s[1:]...)
+               cmd.Stdout = logfile
+               cmd.Stderr = logfile
+               err = cmd.Run()
+               if err != nil {
+                       return fmt.Errorf("BuildSequence[%d] %s: %v\n",
+                               i, bs[i], err)
+               }
        }
 
        if wt != nil {
diff --git a/repo.go b/repo.go
index 2a8b717f8c9f62c519fc7ada4f36e59eb9d25d83..1e7802f8142c1f001c4921fcb9ea456c154ca5b8 100644 (file)
--- a/repo.go
+++ b/repo.go
@@ -25,7 +25,6 @@ func MainRepoInit(unused *XSAMeta, args []string) (ret int) {
        proxyURL := flags.String("gitproxy", EmptyString,
                "Git proxy prefix, used for building")
 
-       
        if err := flags.Parse(args); err != nil {
                if err != flag.ErrHelp {
                        fmt.Printf("Error parsing args: %v\n", err)
@@ -137,6 +136,16 @@ func MainRepoInit(unused *XSAMeta, args []string) (ret int) {
                return 1
        }
 
+       G.config.Tool.BuildSequences = map[string]BuildSequence{
+               "simple": {"./configure", "make -j 8"},
+               "xen":    {"make -j 8 xen"},
+               "xentools": {"./configure --disable-stubdom --disable-qemu-traditional" +
+                       "--with-system-qemu=/bin/false --with-system-seabios=/bin/false" +
+                       "--disable-ovmf",
+                       "make -j 8"},
+       }
+       G.config.Tool.DefaultBuildSequence = "simple"
+
        err = G.config.Tool.Save()
        if err != nil {
                fmt.Printf("Trying to save config: %v\n", err)
@@ -194,7 +203,7 @@ func MainRepoInfo(unused *XSAMeta, args []string) (ret int) {
 
 func MainRepoX(unused *XSAMeta, args []string) (ret int) {
        var versions []XenVersionFull
-       
+
        xr, err := G.repos.GetRepo(TreeXen)
 
        if err == nil {
diff --git a/test.go b/test.go
index a912452cf74ca71e81532f37846208fd60c6616f..1821b16039176295b44c9385d69ccf6dbe572dfc 100644 (file)
--- a/test.go
+++ b/test.go
@@ -6,15 +6,35 @@ import (
 
 func test(xsa *XSAMeta, args []string, apply bool, build bool) (ret int) {
        vers := xsa.SupportedVersions
-       if len(args) > 0 {
+
+       var bs string
+
+       for i := 0; i < len(args); i++ {
+               // Does it look like an extra argument?
+               switch args[i] {
+               case "-buildsequence":
+               case "-bs":
+                       if len(args) == i {
+                               fmt.Printf("Not enough arguments to buildsequence")
+                               return 1
+                       }
+                       i++
+                       bs = args[i]
+                       continue
+               }
+
                var err error
-               vers, err = VersionsFromString(args[0], xsa.SupportedVersions, nil)
+               vers, err = VersionsFromString(args[i], xsa.SupportedVersions, nil)
                if err != nil {
                        fmt.Printf("Error parsing versions: %v", err)
-                       return
+                       return 1
                }
        }
 
+       if bs == "" {
+               bs = G.config.Tool.DefaultBuildSequence
+       }
+
        for _, v := range vers {
                prefix := "xsa/test"
                r := xsa.GetRecipe(v)
@@ -47,7 +67,7 @@ func test(xsa *XSAMeta, args []string, apply bool, build bool) (ret int) {
                }
 
                if build {
-                       err := r.Build(prefix)
+                       err := r.Build(prefix, bs)
                        if err != nil {
                                fmt.Printf("Building recipe: %v\n", err)
                                fmt.Printf("FAILED: %v\n", r.XenVersion)