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)
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")
column_widths = [max(len(str(row[i])) for row in result) for i in range(len(headers))]
header_row = " | ".join(f"{header: <{column_widths[i]}}" for i, header in enumerate(headers))
print(header_row)
print("-" * len(header_row))
for row in result:
row_values = [str(value) for value in row[:len(headers)]] 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:
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()