Skip to content

Commit c0f0f66

Browse files
committed
runtime: null: check if compiler exists on host
tuxmake -p with the null runtime showed all combinations as supported even when the cross-compiler was not installed. Check if the compiler binary exists in PATH before reporting a combination as supported. Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
1 parent aab01a5 commit c0f0f66

File tree

6 files changed

+41
-4
lines changed

6 files changed

+41
-4
lines changed

docs/runtimes.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,14 @@ The following runtimes are available:
1616

1717
## null
1818

19-
The default runtime. Assumes you have any necessary toolchain installed on your
20-
system. If you request a build that requires a (cross) toolchain you don't have
21-
installed locally, the build will just fail.
19+
The default runtime. Uses toolchains installed on your system. You need to
20+
install any required (cross) compilers yourself. For example, to cross-compile
21+
for arm64 on Debian you would need to install `gcc-aarch64-linux-gnu`.
22+
23+
If a required compiler is not installed, the build will fail.
24+
25+
The support matrix (`tuxmake -p`) checks which compilers are available in your
26+
`$PATH` and only reports combinations as supported when the compiler is found.
2227

2328
## docker
2429

test/conftest.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ def fake_cross_compilers(tmpdir_factory):
6363
binary = arch.makevars["CROSS_COMPILE"] + tool
6464
if not shutil.which(binary):
6565
missing[binary] = tool
66+
if not shutil.which("clang"):
67+
missing["clang"] = "true"
6668
if missing:
6769
testbin = tmpdir_factory.mktemp("bin")
6870
for p, real in missing.items():

test/integration/fakelinux

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ test_dtbs() {
132132
}
133133

134134
test_dtbs_armv5() {
135+
skip_if not program_installed arm-linux-gnueabi-gcc
135136
run tuxmake --target-arch=armv5 dtbs
136137
assertTrue "build dtbs on armv5" "grep 'dtbs: PASS' stderr"
137138
}

test/test_build.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,7 @@ def test_errors(self, build):
889889

890890
class TestUnsupportedToolchainArchitectureCombination:
891891
def test_exception(self, linux, mocker):
892-
mocker.patch("tuxmake.runtime.Runtime.is_supported", return_value=False)
892+
mocker.patch("tuxmake.runtime.NullRuntime.is_supported", return_value=False)
893893
with pytest.raises(
894894
tuxmake.exceptions.UnsupportedArchitectureToolchainCombination
895895
):

test/test_runtime.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import subprocess
33
import pytest
44

5+
from tuxmake.arch import Architecture
56
from tuxmake.build import Build
67
from tuxmake.exceptions import InvalidRuntimeError
78
from tuxmake.exceptions import RuntimePreparationFailed
@@ -13,6 +14,7 @@
1314
from tuxmake.runtime import PodmanRuntime
1415
from tuxmake.runtime import PodmanLocalRuntime
1516
from tuxmake.runtime import Terminated
17+
from tuxmake.toolchain import Toolchain
1618

1719

1820
@pytest.fixture
@@ -81,6 +83,14 @@ def test_create_output_directory_on_prepare_already_exists(self, tmp_path):
8183
assert runtime.output_dir.exists()
8284

8385

86+
class TestRuntimeIsSupported:
87+
def test_base_class_returns_true(self):
88+
runtime = Runtime.get("docker")
89+
arch = Architecture("x86_64")
90+
toolchain = Toolchain("gcc")
91+
assert Runtime.is_supported(runtime, arch, toolchain) is True
92+
93+
8494
class TestNullRuntime:
8595
def test_get_command_line(self, build):
8696
assert NullRuntime().get_command_line(
@@ -91,6 +101,20 @@ def test_toolchains(self):
91101
runtime = NullRuntime()
92102
assert "gcc" in runtime.toolchains
93103

104+
def test_is_supported_compiler_found(self, mocker):
105+
mocker.patch("shutil.which", return_value="/usr/bin/gcc")
106+
runtime = NullRuntime()
107+
arch = Architecture("x86_64")
108+
toolchain = Toolchain("gcc")
109+
assert runtime.is_supported(arch, toolchain) is True
110+
111+
def test_is_supported_compiler_not_found(self, mocker):
112+
mocker.patch("shutil.which", return_value=None)
113+
runtime = NullRuntime()
114+
arch = Architecture("x86_64")
115+
toolchain = Toolchain("gcc")
116+
assert runtime.is_supported(arch, toolchain) is False
117+
94118

95119
@pytest.fixture
96120
def container_id():

tuxmake/runtime.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import re
33
import json
44
import shlex
5+
import shutil
56
import subprocess
67
import sys
78
import time
@@ -361,6 +362,10 @@ def run_cmd(
361362
class NullRuntime(Runtime):
362363
name = "null"
363364

365+
def is_supported(self, arch, toolchain):
366+
compiler = toolchain.compiler(arch)
367+
return shutil.which(compiler) is not None
368+
364369

365370
class Image:
366371
def __init__(

0 commit comments

Comments
 (0)