Skip to content

Commit 95dbea8

Browse files
xnorpxjmvalin
authored andcommitted
Script to build Autotools, CMake and Meson
Signed-off-by: Jean-Marc Valin <jmvalin@jmvalin.ca>
1 parent fa9c1e7 commit 95dbea8

File tree

1 file changed

+220
-0
lines changed

1 file changed

+220
-0
lines changed

scripts/local_build.py

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
#!/usr/bin/python3
2+
3+
"""
4+
This script tries to build a project with CMake, Meson, and Autotools.
5+
It checks if CMake, Meson, and Autotools are installed, and performs
6+
the configure, build, and optionally test steps for each build system.
7+
"""
8+
9+
import multiprocessing
10+
import os
11+
import random
12+
import string
13+
import subprocess
14+
import sys
15+
import shutil
16+
17+
18+
if sys.platform == "win32":
19+
REPO_DIR = "\\".join(os.path.abspath(__file__).split("\\")[:-2])
20+
else:
21+
REPO_DIR = "/".join(os.path.abspath(__file__).split("/")[:-2])
22+
23+
24+
def main():
25+
import argparse
26+
parser = argparse.ArgumentParser()
27+
parser.add_argument("--test", action="store_true", help="Run tests")
28+
parser.add_argument("--cmake", action="store_true", help="Only run CMake")
29+
parser.add_argument("--meson", action="store_true", help="Only run Meson")
30+
if sys.platform != "win32":
31+
parser.add_argument("--autotools", action="store_true", help="Only run Autotools")
32+
args = parser.parse_args()
33+
34+
test = args.test
35+
cmake_only = args.cmake
36+
meson_only = args.meson
37+
if sys.platform != "win32":
38+
autotools_only = args.autotools
39+
autotools_only = False
40+
41+
result = []
42+
os.chdir(REPO_DIR)
43+
44+
# download model
45+
if sys.platform == "win32":
46+
run_command("autogen.bat")
47+
else:
48+
run_command("./autogen.sh")
49+
50+
if sys.platform != "win32" and not cmake_only and not meson_only:
51+
result += autotools_build(test)
52+
53+
if not autotools_only and not meson_only:
54+
result += cmake_build(test)
55+
result += cmake_build(test, extra_options="-DOPUS_NEURAL_FEC=ON")
56+
57+
if not autotools_only and not cmake_only:
58+
result += meson_build(test)
59+
60+
print_result(result, test)
61+
62+
def print_result(result, test=False):
63+
if len(result) == 0:
64+
print("No results available")
65+
return
66+
67+
headers = ["Name", "Build Passed"]
68+
if test:
69+
headers.append("Test Passed")
70+
71+
# Calculate the maximum width for each column
72+
column_widths = [max(len(str(row[i])) for row in result) for i in range(len(headers))]
73+
74+
# Print the headers
75+
header_row = " | ".join(f"{header: <{column_widths[i]}}" for i, header in enumerate(headers))
76+
print(header_row)
77+
print("-" * len(header_row))
78+
79+
# Print the data rows
80+
for row in result:
81+
row_values = [str(value) for value in row[:len(headers)]] # Include values up to the last column to be printed
82+
row_string = " | ".join(f"{row_values[i]: <{column_widths[i]}}" for i in range(len(headers)))
83+
print(row_string)
84+
85+
def autotools_build(test=False):
86+
build = "Autotools"
87+
autotools_build_succeeded = False
88+
autotools_test_succeeded = False
89+
90+
if not check_tool_installed("autoreconf") or not check_tool_installed("automake") or not check_tool_installed("autoconf"):
91+
print("Autotools dependencies are not installed. Aborting.")
92+
print("Install with: sudo apt-get install git autoconf automake libtool gcc make")
93+
return [(build, autotools_build_succeeded, autotools_test_succeeded)]
94+
95+
run_command("./configure")
96+
if run_command("make -j {}".format(get_cpu_core_count())) == 0:
97+
autotools_build_succeeded = True
98+
if test:
99+
if run_command("make check -j {}".format(get_cpu_core_count())) == 0:
100+
autotools_test_succeeded = True
101+
102+
return [(build, autotools_build_succeeded, autotools_test_succeeded)]
103+
104+
105+
def cmake_build(test=False, extra_options=""):
106+
cmake_build_succeeded = False
107+
cmake_test_succeeded = False
108+
build = "CMake"
109+
110+
if not check_tool_installed("cmake"):
111+
print("CMake is not installed. Aborting.")
112+
if sys.platform != "win32":
113+
print("Install with: sudo apt install cmake")
114+
else:
115+
print("Download and install from: https://cmake.org/download/")
116+
return [(build, cmake_build_succeeded, cmake_test_succeeded)]
117+
118+
if not check_tool_installed("ninja"):
119+
print("Ninja is not installed. Aborting.")
120+
if sys.platform != "win32":
121+
print("Install with: sudo apt ninja-build ")
122+
else:
123+
print("Download and install from: https://ninja-build.org/")
124+
return [(build, cmake_build_succeeded, cmake_test_succeeded)]
125+
126+
cmake_build_dir = create_dir_with_random_postfix("cmake-build")
127+
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"]
128+
cmake_cfg_cmd += [option for option in extra_options.split(" ")]
129+
run_command(" ".join(cmake_cfg_cmd))
130+
cmake_build_cmd = ["cmake", "--build", cmake_build_dir, "-j", "{}".format(get_cpu_core_count())]
131+
cmake_test_cmd = ["ctest", "-j", "{}".format(get_cpu_core_count())]
132+
if sys.platform == "win32":
133+
cmake_build_cmd += ["--config", "Release"]
134+
cmake_test_cmd += ["-C", "Release"]
135+
136+
if run_command(" ".join(cmake_build_cmd)) == 0:
137+
cmake_build_succeeded = True
138+
139+
if test:
140+
os.chdir(cmake_build_dir)
141+
if run_command(" ".join(cmake_test_cmd)) == 0:
142+
cmake_test_succeeded = True
143+
os.chdir(REPO_DIR)
144+
145+
shutil.rmtree(cmake_build_dir)
146+
147+
if extra_options != "":
148+
build += " with options: "
149+
build += extra_options.replace("-D", "")
150+
return [(build, cmake_build_succeeded, cmake_test_succeeded)]
151+
152+
def meson_build(test=False, extra_options=""):
153+
build = "Meson"
154+
meson_build_succeeded = False
155+
meson_test_succeeded = False
156+
157+
if not check_tool_installed("meson"):
158+
print("Meson is not installed. Aborting.")
159+
print("Install with: pip install meson")
160+
return [(build, meson_build_succeeded, meson_test_succeeded)]
161+
162+
if not check_tool_installed("ninja"):
163+
print("Ninja is not installed. Aborting.")
164+
if sys.platform != "win32":
165+
print("Install with: sudo apt ninja-build ")
166+
else:
167+
print("Download and install from: https://ninja-build.org/")
168+
return [(build, meson_build_succeeded, meson_test_succeeded)]
169+
170+
meson_build_dir = create_dir_with_random_postfix("meson-build")
171+
meson_cfg_cmd = ["meson", "setup", meson_build_dir]
172+
meson_cfg_cmd += [option for option in extra_options.split(" ")]
173+
run_command(" ".join(meson_cfg_cmd))
174+
meson_build_cmd = ["meson", "compile", "-C", meson_build_dir]
175+
meson_test_cmd = ["meson", "test", "-C", meson_build_dir]
176+
177+
if run_command(" ".join(meson_build_cmd)) == 0:
178+
meson_build_succeeded = True
179+
180+
if test:
181+
os.chdir(meson_build_dir)
182+
if run_command(" ".join(meson_test_cmd)) == 0:
183+
meson_test_succeeded = True
184+
os.chdir(REPO_DIR)
185+
186+
shutil.rmtree(meson_build_dir)
187+
188+
if extra_options != "":
189+
build += " with options: "
190+
build += extra_options.replace("-D", "")
191+
return [(build, meson_build_succeeded, meson_test_succeeded)]
192+
193+
def create_dir_with_random_postfix(dir):
194+
random_chars = "".join(random.choices(string.ascii_letters, k=3))
195+
dir = dir + "-" + random_chars
196+
dir = os.path.join(os.getcwd(), dir)
197+
os.makedirs(dir)
198+
return dir
199+
200+
def check_tool_installed(tool):
201+
if sys.platform == "win32":
202+
try:
203+
# Use the "where" command to search for the executable
204+
subprocess.check_output(["where", tool], shell=True)
205+
return True
206+
except subprocess.CalledProcessError:
207+
return False
208+
else:
209+
return run_command(f"command -v {tool}") == 0
210+
211+
def run_command(command):
212+
process = subprocess.Popen(command, shell=True)
213+
process.communicate()
214+
return process.returncode
215+
216+
def get_cpu_core_count():
217+
return int(max(multiprocessing.cpu_count(), 1))
218+
219+
if __name__ == "__main__":
220+
main()

0 commit comments

Comments
 (0)