shithub: opus

Download patch

ref: 95dbea83486b90256785aa3c75dd2827f591a34c
parent: fa9c1e715e6edd0576ec3d4e5c3c29499b3b1db9
author: Marcus Asteborg <maastebo@microsoft.com>
date: Thu Jun 22 12:46:50 EDT 2023

Script to build Autotools, CMake and Meson

Signed-off-by: Jean-Marc Valin <jmvalin@jmvalin.ca>

--- /dev/null
+++ b/scripts/local_build.py
@@ -1,0 +1,220 @@
+#!/usr/bin/python3
+
+"""
+This script tries to build a project with CMake, Meson, and Autotools.
+It checks if CMake, Meson, and Autotools are installed, and performs
+the configure, build, and optionally test steps for each build system.
+"""
+
+import multiprocessing
+import os
+import random
+import string
+import subprocess
+import sys
+import shutil
+
+
+if sys.platform == "win32":
+    REPO_DIR = "\\".join(os.path.abspath(__file__).split("\\")[:-2])
+else:
+    REPO_DIR = "/".join(os.path.abspath(__file__).split("/")[:-2])
+
+
+def main():
+    import argparse
+    parser = argparse.ArgumentParser()
+    parser.add_argument("--test", action="store_true", help="Run tests")
+    parser.add_argument("--cmake", action="store_true", help="Only run CMake")
+    parser.add_argument("--meson", action="store_true", help="Only run Meson")
+    if sys.platform != "win32":
+        parser.add_argument("--autotools", action="store_true", help="Only run Autotools")
+    args = parser.parse_args()
+
+    test = args.test
+    cmake_only = args.cmake
+    meson_only = args.meson
+    if sys.platform != "win32":
+        autotools_only = args.autotools
+    autotools_only = False
+
+    result = []
+    os.chdir(REPO_DIR)
+
+    # download model
+    if sys.platform == "win32":
+        run_command("autogen.bat")
+    else:
+        run_command("./autogen.sh")
+
+    if sys.platform != "win32" and not cmake_only and not meson_only:
+        result += autotools_build(test)
+
+    if not autotools_only and not meson_only:
+        result += cmake_build(test)
+        result += cmake_build(test, extra_options="-DOPUS_NEURAL_FEC=ON")
+
+    if not autotools_only and not cmake_only:
+        result += meson_build(test)
+
+    print_result(result, test)
+
+def print_result(result, test=False):
+    if len(result) == 0:
+        print("No results available")
+        return
+
+    headers = ["Name", "Build Passed"]
+    if test:
+        headers.append("Test Passed")
+
+    # Calculate the maximum width for each column
+    column_widths = [max(len(str(row[i])) for row in result) for i in range(len(headers))]
+
+    # Print the headers
+    header_row = " | ".join(f"{header: <{column_widths[i]}}" for i, header in enumerate(headers))
+    print(header_row)
+    print("-" * len(header_row))
+
+    # Print the data rows
+    for row in result:
+        row_values = [str(value) for value in row[:len(headers)]]  # Include values up to the last column to be printed
+        row_string = " | ".join(f"{row_values[i]: <{column_widths[i]}}" for i in range(len(headers)))
+        print(row_string)
+
+def autotools_build(test=False):
+    build = "Autotools"
+    autotools_build_succeeded = False
+    autotools_test_succeeded = False
+
+    if not check_tool_installed("autoreconf") or not check_tool_installed("automake") or not check_tool_installed("autoconf"):
+        print("Autotools dependencies are not installed. Aborting.")
+        print("Install with: sudo apt-get install git autoconf automake libtool gcc make")
+        return [(build, autotools_build_succeeded, autotools_test_succeeded)]
+
+    run_command("./configure")
+    if run_command("make -j {}".format(get_cpu_core_count())) == 0:
+        autotools_build_succeeded = True
+    if test:
+        if run_command("make check -j {}".format(get_cpu_core_count())) == 0:
+            autotools_test_succeeded = True
+
+    return [(build, autotools_build_succeeded, autotools_test_succeeded)]
+
+
+def cmake_build(test=False, extra_options=""):
+    cmake_build_succeeded = False
+    cmake_test_succeeded = False
+    build = "CMake"
+
+    if not check_tool_installed("cmake"):
+        print("CMake is not installed. Aborting.")
+        if sys.platform != "win32":
+            print("Install with: sudo apt install cmake")
+        else:
+            print("Download and install from: https://cmake.org/download/")
+        return [(build, cmake_build_succeeded, cmake_test_succeeded)]
+
+    if not check_tool_installed("ninja"):
+        print("Ninja is not installed. Aborting.")
+        if sys.platform != "win32":
+            print("Install with: sudo apt ninja-build ")
+        else:
+            print("Download and install from: https://ninja-build.org/")
+        return [(build, cmake_build_succeeded, cmake_test_succeeded)]
+
+    cmake_build_dir = create_dir_with_random_postfix("cmake-build")
+    cmake_cfg_cmd = ["cmake", "-S" ".", "-B", cmake_build_dir, "-G", '"Ninja"', "-DCMAKE_BUILD_TYPE=Release", "-DOPUS_BUILD_TESTING=ON", "-DOPUS_BUILD_PROGRAMS=ON", "-DOPUS_FAST_MATH=ON", "-DOPUS_FLOAT_APPROX=ON"]
+    cmake_cfg_cmd += [option for option in extra_options.split(" ")]
+    run_command(" ".join(cmake_cfg_cmd))
+    cmake_build_cmd = ["cmake", "--build", cmake_build_dir, "-j", "{}".format(get_cpu_core_count())]
+    cmake_test_cmd = ["ctest", "-j", "{}".format(get_cpu_core_count())]
+    if sys.platform == "win32":
+        cmake_build_cmd += ["--config", "Release"]
+        cmake_test_cmd += ["-C", "Release"]
+
+    if run_command(" ".join(cmake_build_cmd)) == 0:
+        cmake_build_succeeded = True
+
+    if test:
+        os.chdir(cmake_build_dir)
+        if run_command(" ".join(cmake_test_cmd)) == 0:
+            cmake_test_succeeded = True
+        os.chdir(REPO_DIR)
+
+    shutil.rmtree(cmake_build_dir)
+
+    if extra_options != "":
+        build += " with options: "
+        build += extra_options.replace("-D", "")
+    return [(build, cmake_build_succeeded, cmake_test_succeeded)]
+
+def meson_build(test=False, extra_options=""):
+    build = "Meson"
+    meson_build_succeeded = False
+    meson_test_succeeded = False
+
+    if not check_tool_installed("meson"):
+        print("Meson is not installed. Aborting.")
+        print("Install with: pip install meson")
+        return [(build, meson_build_succeeded, meson_test_succeeded)]
+
+    if not check_tool_installed("ninja"):
+        print("Ninja is not installed. Aborting.")
+        if sys.platform != "win32":
+            print("Install with: sudo apt ninja-build ")
+        else:
+            print("Download and install from: https://ninja-build.org/")
+        return [(build, meson_build_succeeded, meson_test_succeeded)]
+
+    meson_build_dir = create_dir_with_random_postfix("meson-build")
+    meson_cfg_cmd = ["meson", "setup", meson_build_dir]
+    meson_cfg_cmd += [option for option in extra_options.split(" ")]
+    run_command(" ".join(meson_cfg_cmd))
+    meson_build_cmd = ["meson", "compile", "-C", meson_build_dir]
+    meson_test_cmd = ["meson", "test", "-C", meson_build_dir]
+
+    if run_command(" ".join(meson_build_cmd)) == 0:
+        meson_build_succeeded = True
+
+    if test:
+        os.chdir(meson_build_dir)
+        if run_command(" ".join(meson_test_cmd)) == 0:
+            meson_test_succeeded = True
+        os.chdir(REPO_DIR)
+
+    shutil.rmtree(meson_build_dir)
+
+    if extra_options != "":
+        build += " with options: "
+        build += extra_options.replace("-D", "")
+    return [(build, meson_build_succeeded, meson_test_succeeded)]
+
+def create_dir_with_random_postfix(dir):
+    random_chars = "".join(random.choices(string.ascii_letters, k=3))
+    dir = dir + "-" + random_chars
+    dir = os.path.join(os.getcwd(), dir)
+    os.makedirs(dir)
+    return dir
+
+def check_tool_installed(tool):
+    if sys.platform == "win32":
+        try:
+            # Use the "where" command to search for the executable
+            subprocess.check_output(["where", tool], shell=True)
+            return True
+        except subprocess.CalledProcessError:
+            return False
+    else:
+        return run_command(f"command -v {tool}") == 0
+
+def run_command(command):
+    process = subprocess.Popen(command, shell=True)
+    process.communicate()
+    return process.returncode
+
+def get_cpu_core_count():
+    return int(max(multiprocessing.cpu_count(), 1))
+
+if __name__ == "__main__":
+    main()
--