Open CI Scripts: Feature Update

    * build_helper: Added --install argument to execute cmake install
    * build_helper: Added the capability to parse axf files for
      code/data/bss sizes and capture it to report
    * build_helper: Added --relative-paths to calculate paths relative
      to the root of the workspace
    * build_helper_configs: Full restructure of config modules.
      Extra build commands and expected artefacts can be defined per
      platform basis
    * Checkpatch: Added directive to ignore --ignore SPDX_LICENSE_TAG
      and added the capability to run only on files changed in patch.
    * CppCheck adjusted suppression directories for new external
      libraries and code-base restructure
    * Added fastmodel dispatcher. It will wrap around fastmodels
      and test against a dynamically defined test_map. Fed with an
      input of the build summary fastmodel dispatcher will detect
      builds which have tests in the map and run them.
    * Added Fastmodel configs for AN519 and AN521 platforms
    * lava_helper. Added arguments for --override-jenkins-job/
      --override-jenkins-url
    * Adjusted JINJA2 template to include build number and
      enable the overrides.
    * Adjusted lava helper configs to support dual platform firmware
      and added CoreIPC config
    * Added report parser module to create/read/evaluate and
      modify reports. Bash scripts for cppcheck checkpatch summaries
      have been removed.
    * Adjusted run_cppcheck/run_checkpatch for new project libraries,
      new codebase structure and other tweaks.
    * Restructured build manager, decoupling it from the tf-m
      cmake requirements. Build manager can now dynamically build a
      configuration from combination of parameters or can just execute
      an array of build commands. Hardcoded tf-m assumptions have been
      removed and moved into the configuration space.
    * Build system can now produce MUSCA_A/ MUSCA_B1 binaries as well
      as intel HEX files.
    * Updated the utilities snippet collection in the tfm-ci-pylib.

Change-Id: Ifad7676e1cd47e3418e851b56dbb71963d85cd88
Signed-off-by: Minos Galanakis <minos.galanakis@linaro.org>
diff --git a/build_helper/build_helper.py b/build_helper/build_helper.py
index ea8e8f3..58957d7 100755
--- a/build_helper/build_helper.py
+++ b/build_helper/build_helper.py
@@ -20,17 +20,17 @@
 __email__ = "minos.galanakis@linaro.org"
 __project__ = "Trusted Firmware-M Open CI"
 __status__ = "stable"
-__version__ = "1.0"
+__version__ = "1.1"
 
 import os
 import sys
 import time
 import argparse
 import datetime
-from build_helper_configs import config_AN521
+from build_helper_configs import _builtin_configs
 
 try:
-    from tfm_ci_pylib.utils import get_cmd_args, load_json
+    from tfm_ci_pylib.utils import get_cmd_args
     from tfm_ci_pylib.tfm_build_manager import TFM_Build_Manager
 except ImportError:
     dir_path = os.path.dirname(os.path.realpath(__file__))
@@ -39,7 +39,15 @@
     from tfm_ci_pylib.tfm_build_manager import TFM_Build_Manager
 
 
-def build(tfm_dir, build_dir, buid_report_f, build_config):
+def build(tfm_dir,
+          build_dir,
+          buid_report_f,
+          build_config,
+          parallel_builds=3,
+          build_threads=3,
+          build_install=True,
+          image_sizes=False,
+          relative_paths=False):
     """ Instantiate a build manager class and build all configurations """
 
     start_time = time.time()
@@ -48,7 +56,11 @@
                            work_dir=build_dir,
                            cfg_dict=build_config,
                            report=buid_report_f,
-                           install=True)
+                           parallel_builds=parallel_builds,
+                           build_threads=build_threads,
+                           install=build_install,
+                           img_sizes=image_sizes,
+                           relative_paths=relative_paths)
     bm.start()
     bm.join()
     build_report = bm.get_report()
@@ -68,13 +80,27 @@
             print("Failed to load config %s. Exception: %s" % (build_config,
                                                                e.msg))
             sys.exit(1)
+    elif user_args.config:
+        if user_args.config in _builtin_configs.keys():
+            build_config = _builtin_configs[user_args.config.lower()]
+        else:
+            print("Configuration %s is not defined in built-in configs" %
+                  user_args.config)
+            sys.exit(1)
     else:
-        build_config = config_AN521
+        print("Error: Configuration not specificed")
+        sys.exit(1)
+
     # Build everything
     build_status, build_report = build(user_args.tfm_dir,
                                        user_args.build_dir,
                                        user_args.report,
-                                       build_config)
+                                       build_config,
+                                       user_args.parallel_builds,
+                                       user_args.thread_no,
+                                       user_args.install,
+                                       user_args.image_sizes,
+                                       user_args.relative_paths)
 
     if not build_report:
         print("Build Report Empty, check build status")
@@ -82,15 +108,16 @@
 
     if build_status:
         print("Build Failed")
-        sys.exit(1)
+        if user_args.eif:
+            sys.exit(1)
     # pprint(build_report)
-    print("Build Complete!")
+    print("Build Helper Quitting!")
     sys.exit(0)
 
 
 if __name__ == "__main__":
 
-    # Calcuate the workspace root directory relative to the script location
+    # Calculate the workspace root directory relative to the script location
     # Equivalent to realpath $(dirname ./build_helper/build_helper.py)/../../
     root_path = os.path.dirname(os.path.realpath(__file__))
     for i in range(2):
@@ -102,7 +129,17 @@
                         action="store",
                         default="./builds",
                         help="Where to generate the artifacts")
-    parser.add_argument("-c", "--config_file",
+    parser.add_argument("-c", "--config",
+                        dest="config",
+                        action="store",
+                        help="Which of the built-in configs to run."
+                             "(%s)" % "/ ".join(_builtin_configs.keys()))
+    parser.add_argument("-e", "--error_if_failed",
+                        dest="eif",
+                        action="store_true",
+                        help="If set will change the script exit code if one "
+                              "or more builds fail")
+    parser.add_argument("-f", "--config_file",
                         dest="config_f",
                         action="store",
                         help="Manual configuration override file (JSON)")
@@ -110,10 +147,36 @@
                         dest="report",
                         action="store",
                         help="JSON file containing build report")
+    parser.add_argument("-i", "--install",
+                        dest="install",
+                        action="store_true",
+                        help="Run make install after building config")
     parser.add_argument("-t", "--tfm_dir",
                         dest="tfm_dir",
                         action="store",
                         default=os.path.join(root_path, "tf-m"),
                         help="TFM directory")
-
+    parser.add_argument("-s", "--image-sizes",
+                        dest="image_sizes",
+                        action="store_true",
+                        help="Run arm-none-eabi-size to axf files "
+                             "generated by build")
+    parser.add_argument("-l", "--relative-paths",
+                        dest="relative_paths",
+                        action="store_true",
+                        help="When set paths stored in report will be stored"
+                             "in a relative path to the execution directory."
+                             "Recommended for Jenkins Builds.")
+    parser.add_argument("-p", "--parallel-builds",
+                        type=int,
+                        dest="parallel_builds",
+                        action="store",
+                        default=3,
+                        help="Number of builds jobs to run in parallel.")
+    parser.add_argument("-n", "--number-of-threads",
+                        type=int,
+                        dest="thread_no",
+                        action="store",
+                        default=3,
+                        help="Number of threads to use per build job.")
     main(get_cmd_args(parser=parser))