-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Script to build Autotools, CMake and Meson
Signed-off-by: Jean-Marc Valin <[email protected]>
- Loading branch information
Showing
1 changed file
with
220 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,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() |