| #!/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() |