scripts/sanitycheck: Add --cmake-only option

Add an option that only invokes the cmake phase of sanitycheck.  This
can be useful for any testing that only needs to initial generation
phase of cmake, for example device tree.  Also useful if we want to
just generate compile_commands.json files from cmake via:

./sanitycheck -xCMAKE_EXPORT_COMPILE_COMMANDS=1 --cmake-only

Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
diff --git a/scripts/sanitycheck b/scripts/sanitycheck
index 8012c0a..d55bf02 100755
--- a/scripts/sanitycheck
+++ b/scripts/sanitycheck
@@ -1107,7 +1107,7 @@
 {goal}:
 """
 
-    MAKE_RULE_TMPL = """\t@echo sanity_test_{phase} {goal} >&2
+    MAKE_RULE_TMPL_CMAKE = """\t@echo sanity_test_{phase} {goal} >&2
 \tcmake  \\
 \t\t-G"{generator}"\\
 \t\t-H{directory}\\
@@ -1117,7 +1117,8 @@
 \t\t-DEXTRA_LDFLAGS="{ldflags}"\\
 \t\t{args}\\
 \t\t>{logfile} 2>&1
-\t{generator_cmd} -C {outdir}\\
+"""
+    MAKE_RULE_TMPL_BLD = """\t{generator_cmd} -C {outdir}\\
 \t\t{verb} {make_args}\\
 \t\t>>{logfile} 2>&1
 """
@@ -1186,21 +1187,31 @@
                 make_args=make_args
             )
         else:
-            return MakeGenerator.MAKE_RULE_TMPL.format(
+            cmake_rule = MakeGenerator.MAKE_RULE_TMPL_CMAKE.format(
                 generator=generator,
-                generator_cmd=generator_cmd,
                 phase=phase,
                 goal=name,
                 outdir=outdir,
                 cflags=cflags,
                 ldflags=ldflags,
                 directory=workdir,
-                verb=verb,
                 args=args,
                 logfile=logfile,
-                make_args=make_args
             )
 
+            if options.cmake_only:
+                build_rule = ""
+            else:
+                build_rule = MakeGenerator.MAKE_RULE_TMPL_BLD.format(
+                    generator_cmd=generator_cmd,
+                    outdir=outdir,
+                    verb=verb,
+                    make_args=make_args,
+                    logfile=logfile,
+                )
+
+            return cmake_rule + build_rule
+
     def _get_rule_footer(self, name):
         return MakeGenerator.GOAL_FOOTER_TMPL.format(goal=name)
 
@@ -1322,7 +1333,7 @@
         args.extend(extra_args)
 
         do_build_only = ti.build_only or options.build_only
-        do_run = not do_build_only
+        do_run = not do_build_only and not options.cmake_only
         skip_slow = ti.test.slow and not options.enable_slow
 
         # FIXME: Need refactoring and cleanup
@@ -1407,7 +1418,7 @@
                     goal.make_state = state
 
                     if state == "finished":
-                        if goal.handler:
+                        if goal.handler and not options.cmake_only:
                             if hasattr(goal.handler, "handle"):
                                 goal.handler.handle()
                                 goal.handler_log = goal.handler.log
@@ -1843,7 +1854,7 @@
         self.outdir = os.path.join(base_outdir, platform.name, test.name)
 
         self.build_only = options.build_only or test.build_only \
-                or self.check_dependency()
+                or self.check_dependency() or options.cmake_only
         self.results = {}
 
     def __lt__(self, other):
@@ -2408,7 +2419,7 @@
             mg.add_test_instance(i, options.extra_args)
         self.goals = mg.execute(cb, cb_context)
 
-        if not options.disable_size_report:
+        if not options.disable_size_report and not options.cmake_only:
             # Parallelize size calculation
             executor = concurrent.futures.ThreadPoolExecutor(JOBS)
             futures = [executor.submit(calc_one_elf_size, name, goal)
@@ -2418,6 +2429,7 @@
             for goal in self.goals.values():
                 goal.metrics["ram_size"] = 0
                 goal.metrics["rom_size"] = 0
+                goal.metrics["handler_time"] = 0
                 goal.metrics["unrecognized"] = []
 
         return self.goals
@@ -2883,6 +2895,11 @@
         help="""Only run device tests with current artifacts, do not build
              the code""")
     parser.add_argument(
+        "--cmake-only", action="store_true",
+        help="Test on device directly. Specify the serial device to "
+             "use with the --device-serial option.")
+
+    parser.add_argument(
         "-j", "--jobs", type=int,
         help="Number of jobs for building, defaults to number of CPU threads "
         "overcommited by factor 2")