diff options
Diffstat (limited to 'zephyr')
30 files changed, 398 insertions, 128 deletions
diff --git a/zephyr/projects/asurada/hayato/zmake.yaml b/zephyr/projects/asurada/hayato/zmake.yaml index c1ec732c43..f4e821d582 100644 --- a/zephyr/projects/asurada/hayato/zmake.yaml +++ b/zephyr/projects/asurada/hayato/zmake.yaml @@ -8,7 +8,9 @@ dts-overlays: - gpio.dts - motionsense.dts - pwm.dts +supported-toolchains: + - coreboot-sdk + - zephyr supported-zephyr-versions: - v2.6 -toolchain: coreboot-sdk output-type: binman diff --git a/zephyr/projects/brya/brya/zmake.yaml b/zephyr/projects/brya/brya/zmake.yaml index 9340bdec53..71687e0f3e 100644 --- a/zephyr/projects/brya/brya/zmake.yaml +++ b/zephyr/projects/brya/brya/zmake.yaml @@ -5,7 +5,9 @@ board: brya dts-overlays: - gpio.dts +supported-toolchains: + - coreboot-sdk + - zephyr supported-zephyr-versions: - v2.6 -toolchain: coreboot-sdk output-type: npcx diff --git a/zephyr/projects/herobrine/herobrine_npcx9/zmake.yaml b/zephyr/projects/herobrine/herobrine_npcx9/zmake.yaml index 530278c5e7..775ab65ead 100644 --- a/zephyr/projects/herobrine/herobrine_npcx9/zmake.yaml +++ b/zephyr/projects/herobrine/herobrine_npcx9/zmake.yaml @@ -9,7 +9,9 @@ dts-overlays: - i2c.dts - motionsense.dts - switchcap.dts +supported-toolchains: + - coreboot-sdk + - zephyr supported-zephyr-versions: - v2.6 -toolchain: coreboot-sdk output-type: npcx diff --git a/zephyr/projects/it8xxx2_evb/zmake.yaml b/zephyr/projects/it8xxx2_evb/zmake.yaml index ba536537a5..d05a938500 100644 --- a/zephyr/projects/it8xxx2_evb/zmake.yaml +++ b/zephyr/projects/it8xxx2_evb/zmake.yaml @@ -3,7 +3,9 @@ # found in the LICENSE file. board: it8xxx2_evb +supported-toolchains: + - coreboot-sdk + - zephyr supported-zephyr-versions: - v2.6 -toolchain: coreboot-sdk output-type: raw diff --git a/zephyr/projects/kohaku/zmake.yaml b/zephyr/projects/kohaku/zmake.yaml index cf55fc5e13..99e4f135fb 100644 --- a/zephyr/projects/kohaku/zmake.yaml +++ b/zephyr/projects/kohaku/zmake.yaml @@ -3,7 +3,9 @@ # found in the LICENSE file. board: kohaku +supported-toolchains: + - coreboot-sdk + - zephyr supported-zephyr-versions: - v2.6 -toolchain: coreboot-sdk output-type: npcx diff --git a/zephyr/projects/npcx_evb/npcx7/zmake.yaml b/zephyr/projects/npcx_evb/npcx7/zmake.yaml index 79faa50656..e846e582e7 100644 --- a/zephyr/projects/npcx_evb/npcx7/zmake.yaml +++ b/zephyr/projects/npcx_evb/npcx7/zmake.yaml @@ -8,7 +8,9 @@ dts-overlays: - pwm.dts - fan.dts - keyboard.dts +supported-toolchains: + - coreboot-sdk + - zephyr supported-zephyr-versions: - v2.6 -toolchain: coreboot-sdk output-type: npcx diff --git a/zephyr/projects/npcx_evb/npcx9/zmake.yaml b/zephyr/projects/npcx_evb/npcx9/zmake.yaml index 95a2d3adf7..1d750cc813 100644 --- a/zephyr/projects/npcx_evb/npcx9/zmake.yaml +++ b/zephyr/projects/npcx_evb/npcx9/zmake.yaml @@ -8,7 +8,9 @@ dts-overlays: - pwm.dts - fan.dts - keyboard.dts +supported-toolchains: + - coreboot-sdk + - zephyr supported-zephyr-versions: - v2.6 -toolchain: coreboot-sdk output-type: npcx diff --git a/zephyr/projects/posix-ec/zmake.yaml b/zephyr/projects/posix-ec/zmake.yaml index 1001ea87ac..e06fd99183 100644 --- a/zephyr/projects/posix-ec/zmake.yaml +++ b/zephyr/projects/posix-ec/zmake.yaml @@ -1,5 +1,7 @@ board: native_posix +supported-toolchains: + - llvm + - host supported-zephyr-versions: - v2.6 output-type: elf -toolchain: llvm diff --git a/zephyr/projects/trogdor/herobrine_npcx7/zmake.yaml b/zephyr/projects/trogdor/herobrine_npcx7/zmake.yaml index 03ab9036aa..ef0e8a178e 100644 --- a/zephyr/projects/trogdor/herobrine_npcx7/zmake.yaml +++ b/zephyr/projects/trogdor/herobrine_npcx7/zmake.yaml @@ -7,7 +7,9 @@ dts-overlays: - gpio.dts - battery.dts - motionsense.dts +supported-toolchains: + - coreboot-sdk + - zephyr supported-zephyr-versions: - v2.6 -toolchain: coreboot-sdk output-type: npcx diff --git a/zephyr/projects/trogdor/lazor/zmake.yaml b/zephyr/projects/trogdor/lazor/zmake.yaml index 234d7dd416..c1c14d07d5 100644 --- a/zephyr/projects/trogdor/lazor/zmake.yaml +++ b/zephyr/projects/trogdor/lazor/zmake.yaml @@ -8,7 +8,9 @@ dts-overlays: - gpio.dts - keyboard.dts - motionsense.dts +supported-toolchains: + - coreboot-sdk + - zephyr supported-zephyr-versions: - v2.6 -toolchain: coreboot-sdk output-type: npcx diff --git a/zephyr/projects/trogdor/trogdor/zmake.yaml b/zephyr/projects/trogdor/trogdor/zmake.yaml index 03ab9036aa..ef0e8a178e 100644 --- a/zephyr/projects/trogdor/trogdor/zmake.yaml +++ b/zephyr/projects/trogdor/trogdor/zmake.yaml @@ -7,7 +7,9 @@ dts-overlays: - gpio.dts - battery.dts - motionsense.dts +supported-toolchains: + - coreboot-sdk + - zephyr supported-zephyr-versions: - v2.6 -toolchain: coreboot-sdk output-type: npcx diff --git a/zephyr/projects/volteer/delbin/zmake.yaml b/zephyr/projects/volteer/delbin/zmake.yaml index 92b19417ef..dc5217e042 100644 --- a/zephyr/projects/volteer/delbin/zmake.yaml +++ b/zephyr/projects/volteer/delbin/zmake.yaml @@ -6,7 +6,9 @@ board: volteer dts-overlays: - gpio.dts - motionsense.dts +supported-toolchains: + - coreboot-sdk + - zephyr supported-zephyr-versions: - v2.6 -toolchain: coreboot-sdk output-type: npcx diff --git a/zephyr/projects/volteer/volteer/zmake.yaml b/zephyr/projects/volteer/volteer/zmake.yaml index ef149f29b4..3f291ce671 100644 --- a/zephyr/projects/volteer/volteer/zmake.yaml +++ b/zephyr/projects/volteer/volteer/zmake.yaml @@ -11,7 +11,9 @@ dts-overlays: - keyboard.dts - motionsense.dts - pwm.dts +supported-toolchains: + - coreboot-sdk + - zephyr supported-zephyr-versions: - v2.6 -toolchain: coreboot-sdk output-type: npcx diff --git a/zephyr/test/accel_cal/zmake.yaml b/zephyr/test/accel_cal/zmake.yaml index 5bcd0d054c..decc749ae1 100644 --- a/zephyr/test/accel_cal/zmake.yaml +++ b/zephyr/test/accel_cal/zmake.yaml @@ -5,6 +5,8 @@ board: native_posix supported-zephyr-versions: - v2.6 -toolchain: llvm +supported-toolchains: + - llvm + - host output-type: elf is-test: true diff --git a/zephyr/test/base32/zmake.yaml b/zephyr/test/base32/zmake.yaml index 9158a292d7..6aa10c2661 100644 --- a/zephyr/test/base32/zmake.yaml +++ b/zephyr/test/base32/zmake.yaml @@ -5,6 +5,8 @@ board: native_posix supported-zephyr-versions: - v2.6 -toolchain: llvm +supported-toolchains: + - llvm + - host output-type: elf is-test: true diff --git a/zephyr/test/crc/zmake.yaml b/zephyr/test/crc/zmake.yaml index 9158a292d7..6aa10c2661 100644 --- a/zephyr/test/crc/zmake.yaml +++ b/zephyr/test/crc/zmake.yaml @@ -5,6 +5,8 @@ board: native_posix supported-zephyr-versions: - v2.6 -toolchain: llvm +supported-toolchains: + - llvm + - host output-type: elf is-test: true diff --git a/zephyr/test/drivers/zmake.yaml b/zephyr/test/drivers/zmake.yaml index 789ce8175d..31d8523e8e 100644 --- a/zephyr/test/drivers/zmake.yaml +++ b/zephyr/test/drivers/zmake.yaml @@ -5,7 +5,9 @@ board: native_posix supported-zephyr-versions: - v2.6 -toolchain: llvm +supported-toolchains: + - llvm + - host output-type: elf is-test: true dts-overlays: diff --git a/zephyr/test/ec_app/zmake.yaml b/zephyr/test/ec_app/zmake.yaml index 5bcd0d054c..decc749ae1 100644 --- a/zephyr/test/ec_app/zmake.yaml +++ b/zephyr/test/ec_app/zmake.yaml @@ -5,6 +5,8 @@ board: native_posix supported-zephyr-versions: - v2.6 -toolchain: llvm +supported-toolchains: + - llvm + - host output-type: elf is-test: true diff --git a/zephyr/test/hooks/zmake.yaml b/zephyr/test/hooks/zmake.yaml index 9158a292d7..6aa10c2661 100644 --- a/zephyr/test/hooks/zmake.yaml +++ b/zephyr/test/hooks/zmake.yaml @@ -5,6 +5,8 @@ board: native_posix supported-zephyr-versions: - v2.6 -toolchain: llvm +supported-toolchains: + - llvm + - host output-type: elf is-test: true diff --git a/zephyr/test/i2c/zmake.yaml b/zephyr/test/i2c/zmake.yaml index 81ded15ffc..f5e794c0f8 100644 --- a/zephyr/test/i2c/zmake.yaml +++ b/zephyr/test/i2c/zmake.yaml @@ -5,7 +5,9 @@ board: native_posix supported-zephyr-versions: - v2.6 -toolchain: llvm +supported-toolchains: + - llvm + - host output-type: elf is-test: true dts-overlays: diff --git a/zephyr/test/i2c_dts/zmake.yaml b/zephyr/test/i2c_dts/zmake.yaml index 5d6d9482f9..c3fca2272e 100644 --- a/zephyr/test/i2c_dts/zmake.yaml +++ b/zephyr/test/i2c_dts/zmake.yaml @@ -6,7 +6,9 @@ board: native_posix supported-zephyr-versions: - v2.6 output-type: elf -toolchain: llvm +supported-toolchains: + - llvm + - host is-test: true dts-overlays: - overlay.dts diff --git a/zephyr/test/system/zmake.yaml b/zephyr/test/system/zmake.yaml index 5d6d9482f9..c3fca2272e 100644 --- a/zephyr/test/system/zmake.yaml +++ b/zephyr/test/system/zmake.yaml @@ -6,7 +6,9 @@ board: native_posix supported-zephyr-versions: - v2.6 output-type: elf -toolchain: llvm +supported-toolchains: + - llvm + - host is-test: true dts-overlays: - overlay.dts diff --git a/zephyr/test/tasks/zmake.yaml b/zephyr/test/tasks/zmake.yaml index 9158a292d7..6aa10c2661 100644 --- a/zephyr/test/tasks/zmake.yaml +++ b/zephyr/test/tasks/zmake.yaml @@ -5,6 +5,8 @@ board: native_posix supported-zephyr-versions: - v2.6 -toolchain: llvm +supported-toolchains: + - llvm + - host output-type: elf is-test: true diff --git a/zephyr/zmake/tests/test_project.py b/zephyr/zmake/tests/test_project.py index dd57a5c9c9..2442ceedf6 100644 --- a/zephyr/zmake/tests/test_project.py +++ b/zephyr/zmake/tests/test_project.py @@ -70,8 +70,8 @@ def test_find_dts_overlays(modules): with TemporaryProject( { "board": board, - "toolchain": "foo", "output-type": "elf", + "supported-toolchains": ["llvm"], "supported-zephyr-versions": ["v2.6"], } ) as project: @@ -104,8 +104,8 @@ def test_prune_modules(modules): with TemporaryProject( { "board": "native_posix", - "toolchain": "coreboot-sdk", "output-type": "elf", + "supported-toolchains": ["coreboot-sdk"], "supported-zephyr-versions": ["v2.6"], "modules": modules, } @@ -125,8 +125,8 @@ def test_prune_modules_unavailable(): with TemporaryProject( { "board": "native_posix", - "toolchain": "coreboot-sdk", "output-type": "elf", + "supported-toolchains": ["coreboot-sdk"], "supported-zephyr-versions": ["v2.6"], "modules": ["hal_stm32", "cmsis"], } @@ -144,7 +144,8 @@ def test_find_projects_empty(tmp_path): YAML_FILE = """ supported-zephyr-versions: - v2.6 -toolchain: coreboot-sdk +supported-toolchains: + - coreboot-sdk output-type: npcx """ diff --git a/zephyr/zmake/tests/test_toolchains.py b/zephyr/zmake/tests/test_toolchains.py index 266013b0e0..515f54a112 100644 --- a/zephyr/zmake/tests/test_toolchains.py +++ b/zephyr/zmake/tests/test_toolchains.py @@ -2,34 +2,154 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import os import pathlib -import mock +import pytest +import zmake.project as project import zmake.toolchains as toolchains -def test_coreboot_sdk(): - config = toolchains.get_toolchain("coreboot-sdk", {"ec": pathlib.Path("/")}) - assert config.cmake_defs["ZEPHYR_TOOLCHAIN_VARIANT"] == "coreboot-sdk" - assert config.cmake_defs["TOOLCHAIN_ROOT"] == "/zephyr" +@pytest.fixture +def mockfs(monkeypatch, tmp_path): + """Setup a fake fs root for pathlib objects at tmp_path/mockfs.""" + mockfs_dir = pathlib.PosixPath(tmp_path / "mockfs") + mockfs_dir.mkdir() + class FakePath(pathlib.Path): + def __new__(cls, *args, **kwargs): + parts = pathlib.PosixPath(*args).relative_to("/").parts + # Make sure we don't double up our mocked directory. + mock_dir_parts = mockfs_dir.relative_to("/").parts + if parts[: len(mock_dir_parts)] == mock_dir_parts: + return pathlib.PosixPath(*args) + return pathlib.PosixPath("/", *mock_dir_parts, *parts) -def test_llvm(): - config = toolchains.get_toolchain("llvm", {"ec": pathlib.Path("/")}) - assert config.cmake_defs["ZEPHYR_TOOLCHAIN_VARIANT"] == "llvm" - assert config.cmake_defs["TOOLCHAIN_ROOT"] == "/zephyr" + monkeypatch.setattr(pathlib, "Path", FakePath) + return mockfs_dir -@mock.patch("zmake.toolchains.find_zephyr_sdk", return_value="/opt/zephyr-sdk") -def test_zephyr(find_zephyr_sdk): - config = toolchains.get_toolchain("zephyr", {}) - assert config.cmake_defs["ZEPHYR_TOOLCHAIN_VARIANT"] == "zephyr" - assert config.cmake_defs["ZEPHYR_SDK_INSTALL_DIR"] == "/opt/zephyr-sdk" - assert config.environ_defs["ZEPHYR_SDK_INSTALL_DIR"] == "/opt/zephyr-sdk" +@pytest.fixture +def coreboot_sdk_exists(mockfs): + coreboot_sdk_dir = mockfs / "opt" / "coreboot-sdk" + coreboot_sdk_dir.mkdir(parents=True) -def test_arm_none_eabi(): - config = toolchains.get_toolchain("arm-none-eabi", {}) - assert config.cmake_defs["ZEPHYR_TOOLCHAIN_VARIANT"] == "cross-compile" - assert config.cmake_defs["CROSS_COMPILE"] == "/usr/bin/arm-none-eabi-" +@pytest.fixture +def llvm_exists(mockfs): + llvm_file = mockfs / "usr" / "bin" / "x86_64-pc-linux-gnu-clang" + llvm_file.parent.mkdir(parents=True) + llvm_file.write_text("") + + +@pytest.fixture +def host_toolchain_exists(mockfs, monkeypatch): + monkeypatch.setattr(os, "environ", {}) + + gcc_file = mockfs / "usr" / "bin" / "gcc" + gcc_file.parent.mkdir(parents=True) + gcc_file.write_text("") + + +@pytest.fixture +def zephyr_exists(mockfs): + zephyr_sdk_version_file = mockfs / "opt" / "zephyr-sdk" / "sdk_version" + zephyr_sdk_version_file.parent.mkdir(parents=True) + zephyr_sdk_version_file.write_text("") + + +@pytest.fixture +def fake_project(tmp_path): + return project.Project( + tmp_path, + config_dict={ + "board": "foo", + "supported-zephyr-versions": ["v2.6"], + "supported-toolchains": [ + "coreboot-sdk", + "host", + "llvm", + "zephyr", + ], + "output-type": "raw", + }, + ) + + +module_paths = { + "ec": pathlib.Path("/mnt/host/source/src/platform/ec"), +} + + +def test_coreboot_sdk(fake_project, coreboot_sdk_exists): + tc = fake_project.get_toolchain(module_paths) + assert isinstance(tc, toolchains.CorebootSdkToolchain) + + config = tc.get_build_config() + assert config.cmake_defs == { + "ZEPHYR_TOOLCHAIN_VARIANT": "coreboot-sdk", + "TOOLCHAIN_ROOT": "/mnt/host/source/src/platform/ec/zephyr", + } + + +def test_llvm(fake_project, llvm_exists): + tc = fake_project.get_toolchain(module_paths) + assert isinstance(tc, toolchains.LlvmToolchain) + + config = tc.get_build_config() + assert config.cmake_defs == { + "ZEPHYR_TOOLCHAIN_VARIANT": "llvm", + "TOOLCHAIN_ROOT": "/mnt/host/source/src/platform/ec/zephyr", + } + + +def test_zephyr(fake_project, zephyr_exists): + tc = fake_project.get_toolchain(module_paths) + assert isinstance(tc, toolchains.ZephyrToolchain) + + config = tc.get_build_config() + assert config.cmake_defs == { + "ZEPHYR_TOOLCHAIN_VARIANT": "zephyr", + "ZEPHYR_SDK_INSTALL_DIR": str(pathlib.Path("/opt/zephyr-sdk")), + } + assert config.environ_defs == { + "ZEPHYR_SDK_INSTALL_DIR": str(pathlib.Path("/opt/zephyr-sdk")), + } + + +def test_zephyr_from_env(mockfs, monkeypatch, fake_project): + zephyr_sdk_path = mockfs / "zsdk" + zephyr_sdk_path.mkdir() + + environ = {"ZEPHYR_SDK_INSTALL_DIR": str(zephyr_sdk_path)} + monkeypatch.setattr(os, "environ", environ) + + tc = fake_project.get_toolchain(module_paths) + assert isinstance(tc, toolchains.ZephyrToolchain) + + config = tc.get_build_config() + assert config.cmake_defs == { + "ZEPHYR_TOOLCHAIN_VARIANT": "zephyr", + "ZEPHYR_SDK_INSTALL_DIR": str(zephyr_sdk_path), + } + assert config.environ_defs == { + "ZEPHYR_SDK_INSTALL_DIR": str(zephyr_sdk_path), + } + + +def test_host_toolchain(fake_project, host_toolchain_exists): + tc = fake_project.get_toolchain(module_paths) + assert isinstance(tc, toolchains.HostToolchain) + + config = tc.get_build_config() + assert config.cmake_defs == { + "ZEPHYR_TOOLCHAIN_VARIANT": "host", + } + + +def test_toolchain_override(mockfs, fake_project): + tc = fake_project.get_toolchain(module_paths, override="foo") + config = tc.get_build_config() + assert isinstance(tc, toolchains.GenericToolchain) + assert config.cmake_defs == {"ZEPHYR_TOOLCHAIN_VARIANT": "foo"} diff --git a/zephyr/zmake/tests/test_version.py b/zephyr/zmake/tests/test_version.py index 8fb4a09435..44997f94da 100644 --- a/zephyr/zmake/tests/test_version.py +++ b/zephyr/zmake/tests/test_version.py @@ -54,8 +54,8 @@ def _setup_example_repos(tmp_path): project_path, config_dict={ "board": "foo", - "toolchain": "bar", "output-type": "raw", + "supported-toolchains": ["coreboot-sdk"], "supported-zephyr-versions": ["v2.6"], }, ) diff --git a/zephyr/zmake/tests/test_zmake.py b/zephyr/zmake/tests/test_zmake.py index f7978764f8..641f9f3db9 100644 --- a/zephyr/zmake/tests/test_zmake.py +++ b/zephyr/zmake/tests/test_zmake.py @@ -19,6 +19,7 @@ import zmake.build_config import zmake.jobserver import zmake.multiproc as multiproc import zmake.project +import zmake.toolchains import zmake.zmake as zm OUR_PATH = os.path.dirname(os.path.realpath(__file__)) @@ -49,6 +50,12 @@ class FakeProject: def find_dts_overlays(self, module_paths): return zmake.build_config.BuildConfig() + def get_toolchain(self, module_paths, override=None): + return zmake.toolchains.GenericToolchain( + override or "foo", + modules=module_paths, + ) + class FakeJobserver(zmake.jobserver.GNUMakeJobServer): """A fake jobserver which just runs 'cat' on the provided files""" diff --git a/zephyr/zmake/zmake/project.py b/zephyr/zmake/zmake/project.py index 956971a52a..84151a90b3 100644 --- a/zephyr/zmake/zmake/project.py +++ b/zephyr/zmake/zmake/project.py @@ -12,6 +12,7 @@ import yaml import zmake.build_config as build_config import zmake.modules as modules import zmake.output_packers as packers +import zmake.toolchains as toolchains import zmake.util as util # The version of jsonschema in the chroot has a bunch of @@ -55,7 +56,12 @@ class ProjectConfig: validator = jsonschema.Draft7Validator schema = { "type": "object", - "required": ["supported-zephyr-versions", "board", "output-type", "toolchain"], + "required": [ + "board", + "output-type", + "supported-toolchains", + "supported-zephyr-versions", + ], "properties": { "supported-zephyr-versions": { "type": "array", @@ -80,8 +86,12 @@ class ProjectConfig: "type": "string", "enum": list(packers.packer_registry), }, - "toolchain": { - "type": "string", + "supported-toolchains": { + "type": "array", + "items": { + "type": "string", + "enum": list(toolchains.support_classes), + }, }, "is-test": { "type": "boolean", @@ -120,8 +130,8 @@ class ProjectConfig: return packers.packer_registry[self.config_dict["output-type"]] @property - def toolchain(self): - return self.config_dict["toolchain"] + def supported_toolchains(self): + return self.config_dict["supported-toolchains"] @property def is_test(self): @@ -211,3 +221,28 @@ class Project: "available.".format(module, self.project_dir) ) from e return result + + def get_toolchain(self, module_paths, override=None): + if override: + if override not in self.config.supported_toolchains: + logging.warning( + "Toolchain %r isn't supported by this project. You're on your own.", + override, + ) + support_class = toolchains.support_classes.get( + override, toolchains.GenericToolchain + ) + return support_class(name=override, modules=module_paths) + else: + for name in self.config.supported_toolchains: + support_class = toolchains.support_classes[name] + toolchain = support_class(name=name, modules=module_paths) + if toolchain.probe(): + logging.info("Toolchain %r selected by probe function.", toolchain) + return toolchain + raise OSError( + "No supported toolchains could be found on your system. If you see " + "this message in the chroot, it indicates a bug. Otherwise, you'll " + "either want to setup your system with a supported toolchain, or " + "manually select an unsupported toolchain with the -t flag." + ) diff --git a/zephyr/zmake/zmake/toolchains.py b/zephyr/zmake/zmake/toolchains.py index b07a2080d6..924448aec5 100644 --- a/zephyr/zmake/zmake/toolchains.py +++ b/zephyr/zmake/zmake/toolchains.py @@ -3,88 +3,152 @@ # found in the LICENSE file. """Definitions of toolchain variables.""" -import glob import os import pathlib import zmake.build_config as build_config -def find_zephyr_sdk(): - """Find the Zephyr SDK, if it's installed. +class GenericToolchain: + """Default toolchain if not known to zmake. - Returns: - The path to the Zephyr SDK, using the search rules defined by - https://docs.zephyrproject.org/latest/getting_started/installation_linux.html + Simply pass ZEPHYR_TOOLCHAIN_VARIANT=name to the build, with + nothing extra. """ - def _gen_sdk_paths(): - yield os.getenv("ZEPHYR_SDK_INSTALL_DIR") - - for searchpath in ( - "~/zephyr-sdk", - "~/.local/zephyr-sdk", - "~/.local/opt/zephyr-sdk", - "~/bin/zephyr-sdk", - "/opt/zephyr-sdk", - "/usr/zephyr-sdk", - "/usr/local/zephyr-sdk", - ): - for suffix in ("", "-*"): - yield from glob.glob(os.path.expanduser(searchpath + suffix)) - - for path in _gen_sdk_paths(): - if not path: - continue - path = pathlib.Path(path) - if (path / "sdk_version").is_file(): - return path - - raise OSError("Unable to find the Zephyr SDK") - - -# Mapping of toolchain names -> (λ (module-paths) build-config) -toolchains = { - "coreboot-sdk": lambda modules: build_config.BuildConfig( - cmake_defs={ - "TOOLCHAIN_ROOT": str(modules["ec"] / "zephyr"), - "ZEPHYR_TOOLCHAIN_VARIANT": "coreboot-sdk", - } - ), - "llvm": lambda modules: build_config.BuildConfig( - cmake_defs={ - "TOOLCHAIN_ROOT": str(modules["ec"] / "zephyr"), - "ZEPHYR_TOOLCHAIN_VARIANT": "llvm", - } - ), - "zephyr": lambda _: build_config.BuildConfig( - cmake_defs={ - "ZEPHYR_TOOLCHAIN_VARIANT": "zephyr", - "ZEPHYR_SDK_INSTALL_DIR": str(find_zephyr_sdk()), - }, - environ_defs={"ZEPHYR_SDK_INSTALL_DIR": str(find_zephyr_sdk())}, - ), - "arm-none-eabi": lambda _: build_config.BuildConfig( - cmake_defs={ - "ZEPHYR_TOOLCHAIN_VARIANT": "cross-compile", - "CROSS_COMPILE": "/usr/bin/arm-none-eabi-", + def __init__(self, name, modules=None): + self.name = name + self.modules = modules or {} + + def probe(self): + """Probe if the toolchain is available on the system.""" + # Since the toolchain is not known to zmake, we have no way to + # know if it's installed. Simply return False to indicate not + # installed. An unknown toolchain would only be used if -t + # was manually passed to zmake, and is not valid to put in a + # zmake.yaml file. + return False + + def get_build_config(self): + """Get the build configuration for the toolchain. + + Returns: + A build_config.BuildConfig to be applied to the build. + """ + return build_config.BuildConfig( + cmake_defs={ + "ZEPHYR_TOOLCHAIN_VARIANT": self.name, + }, + ) + + +class CorebootSdkToolchain(GenericToolchain): + def probe(self): + # For now, we always assume it's at /opt/coreboot-sdk, since + # that's where it's installed in the chroot. We may want to + # consider adding support for a coreboot-sdk built in the + # user's home directory, for example, which happens if a + # "make crossgcc" is done from the coreboot repository. + return pathlib.Path("/opt/coreboot-sdk").is_dir() + + def get_build_config(self): + return ( + build_config.BuildConfig( + cmake_defs={ + "TOOLCHAIN_ROOT": str(self.modules["ec"] / "zephyr"), + }, + ) + | super().get_build_config() + ) + + +class ZephyrToolchain(GenericToolchain): + def __init__(self, *args, **kwargs): + self.zephyr_sdk_install_dir = self._find_zephyr_sdk() + super().__init__(*args, **kwargs) + + @staticmethod + def _find_zephyr_sdk(): + """Find the Zephyr SDK, if it's installed. + + Returns: + The path to the Zephyr SDK, using the search rules defined by + https://docs.zephyrproject.org/latest/getting_started/installation_linux.html, + or None, if one cannot be found on the system. + """ + from_env = os.getenv("ZEPHYR_SDK_INSTALL_DIR") + if from_env: + return pathlib.Path(from_env) + + def _gen_sdk_paths(): + for prefix in ( + "~", + "~/.local", + "~/.local/opt", + "~/bin", + "/opt", + "/usr", + "/usr/local", + ): + prefix = pathlib.Path(os.path.expanduser(prefix)) + yield prefix / "zephyr-sdk" + yield from prefix.glob("zephyr-sdk-*") + + for path in _gen_sdk_paths(): + if (path / "sdk_version").is_file(): + return path + + return None + + def probe(self): + return bool(self.zephyr_sdk_install_dir) + + def get_build_config(self): + assert self.zephyr_sdk_install_dir + tc_vars = { + "ZEPHYR_SDK_INSTALL_DIR": str(self.zephyr_sdk_install_dir), } - ), -} + return ( + build_config.BuildConfig( + environ_defs=tc_vars, + cmake_defs=tc_vars, + ) + | super().get_build_config() + ) -def get_toolchain(name, module_paths): - """Get a toolchain by name. +class LlvmToolchain(GenericToolchain): + def probe(self): + # TODO: differentiate chroot llvm path vs. something more + # generic? + return pathlib.Path("/usr/bin/x86_64-pc-linux-gnu-clang").exists() - Args: - name: The name of the toolchain. - module_paths: Dictionary mapping module names to paths. + def get_build_config(self): + # TODO: this contains custom settings for the chroot. Plumb a + # toolchain for "generic-llvm" for external uses? + return ( + build_config.BuildConfig( + cmake_defs={ + "TOOLCHAIN_ROOT": str(self.modules["ec"] / "zephyr"), + }, + ) + | super().get_build_config() + ) - Returns: - The corresponding BuildConfig from the defined toolchains, if - one exists, otherwise a simple BuildConfig which sets - ZEPHYR_TOOLCHAIN_VARIANT to the corresponding name. - """ - if name in toolchains: - return toolchains[name](module_paths) - return build_config.BuildConfig(cmake_defs={"ZEPHYR_TOOLCHAIN_VARIANT": name}) + +class HostToolchain(GenericToolchain): + def probe(self): + # "host" toolchain for Zephyr means GCC. + for search_path in os.getenv("PATH", "/usr/bin").split(":"): + if (pathlib.Path(search_path) / "gcc").exists(): + return True + return False + + +# Mapping of toolchain names -> support class +support_classes = { + "coreboot-sdk": CorebootSdkToolchain, + "host": HostToolchain, + "llvm": LlvmToolchain, + "zephyr": ZephyrToolchain, +} diff --git a/zephyr/zmake/zmake/zmake.py b/zephyr/zmake/zmake/zmake.py index 58afdbfec0..2559a16c45 100644 --- a/zephyr/zmake/zmake/zmake.py +++ b/zephyr/zmake/zmake/zmake.py @@ -16,7 +16,6 @@ import zmake.jobserver import zmake.modules import zmake.multiproc import zmake.project -import zmake.toolchains as toolchains import zmake.util as util import zmake.version @@ -260,10 +259,8 @@ class Zmake: dts_overlay_config = project.find_dts_overlays(module_paths) - if not toolchain: - toolchain = project.config.toolchain - - toolchain_config = toolchains.get_toolchain(toolchain, module_paths) + toolchain_support = project.get_toolchain(module_paths, override=toolchain) + toolchain_config = toolchain_support.get_build_config() if bringup: base_config |= zmake.build_config.BuildConfig( |