diff --git a/hpvm/scripts/hpvm_installer.py b/hpvm/scripts/hpvm_installer.py
index 215db6e2a43103e893639ee5fdb96af80c33f426..db28e92a513516da3a476af02809b722259ee46c 100755
--- a/hpvm/scripts/hpvm_installer.py
+++ b/hpvm/scripts/hpvm_installer.py
@@ -1,9 +1,9 @@
 #!/usr/bin/env python3
-from argparse import ArgumentParser, Namespace
+from argparse import ArgumentParser
 from os import chdir, environ, makedirs
 from pathlib import Path
 from subprocess import CalledProcessError, check_call
-from typing import List
+from typing import List, Union
 
 VERSION = "9.0.0"
 URL = "http://releases.llvm.org"
@@ -79,6 +79,11 @@ def parse_args(args=None):
         "Supported targets: AArch64, AMDGPU, ARM, BPF, Hexagon, Mips, MSP430, NVPTX, PowerPC, "
         "Sparc, SystemZ, X86, XCore.",
     )
+    parser.add_argument(
+        "--ninja",
+        action="store_true",
+        help="Use Ninja to build HPVM. Uses 'make' otherwise.",
+    )
     parser.add_argument(
         "-r", "--run-tests", action="store_true", help="Build and run test cases"
     )
@@ -165,6 +170,8 @@ def print_args(args):
     print("Running with the following options:")
     print(f"  Automated build: {not args.no_build}")
     print(f"  Build directory: {args.build_dir}")
+    build_sys = "ninja" if args.ninja else "make"
+    print(f"  Build system: {build_sys}")
     print(f"  Threads: {args.parallel}")
     print(f"  Targets: {args.targets}")
     print(f"  Download DNN weights: {not args.no_params}")
@@ -255,7 +262,7 @@ def build(
     build_dir: Path,
     nthreads: int,
     targets: str,
-    build_test_targets: bool,
+    use_ninja: bool,
     cmake_additional_args: List[str],
 ):
     print("Now building...")
@@ -271,13 +278,17 @@ def build(
         f"-DLLVM_TARGETS_TO_BUILD={targets}",
         *cmake_additional_args,
     ]
+    if use_ninja:
+        cmake_args.append("-GNinja")
     print(f"CMake: {' '.join(cmake_args)}")
     print(f"=============================")
     check_call(cmake_args)
-    make_args = ["make", f"-j{nthreads}", *MAKE_TARGETS]
-    print(f"Make: {' '.join(make_args)}")
+
+    build_sys = "ninja" if use_ninja else "make"
+    build_args = [build_sys, f"-j{nthreads}", *MAKE_TARGETS]
+    print(f"Build system ({build_sys}): {' '.join(build_args)}")
     print(f"=============================")
-    check_call(make_args)
+    check_call(build_args)
     chdir(ROOT_DIR)
 
 
@@ -291,12 +302,13 @@ def install_py_packages():
         check_call([sys.executable, "-m", "pip", "install", str(package_home)])
 
 
-def run_tests(build_dir: Path, nthreads: int):
+def run_tests(build_dir: Path, use_ninja: bool, nthreads: int):
     chdir(build_dir)
-    make_args = ["make", f"-j{nthreads}", *MAKE_TEST_TARGETS]
-    print(f"Tests: {' '.join(make_args)}")
+    build_sys = "ninja" if use_ninja else "make"
+    build_args = [build_sys, f"-j{nthreads}", *MAKE_TARGETS]
+    print(f"Tests: {' '.join(build_args)}")
     print(f"=============================")
-    check_call(make_args)
+    check_call(build_args)
     chdir(ROOT_DIR)
 
 
@@ -310,8 +322,8 @@ def input_with_check(prompt: str, parse, prompt_when_invalid: str):
     return value
 
 
-def download(link: str, output: Path):
-    check_call(["curl", "-L", link, "-o", output])
+def download(link: str, output: Union[Path, str]):
+    check_call(["curl", "-L", link, "-o", str(output)])
 
 
 def main():
@@ -338,15 +350,9 @@ For more details refer to README.md.
         )
         return
     else:
-        build(
-            args.build_dir,
-            args.parallel,
-            args.targets,
-            args.run_tests,
-            args.cmake_args,
-        )
+        build(args.build_dir, args.parallel, args.targets, args.ninja, args.cmake_args)
     if args.run_tests:
-        run_tests(args.build_dir, args.parallel)
+        run_tests(args.build_dir, args.ninja, args.parallel)
     else:
         print("Skipping tests.")