Coverage for apio/utils/apio_platforms.py: 85%
39 statements
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-23 03:53 +0000
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-23 03:53 +0000
1# -*- coding: utf-8 -*-
2# -- This file is part of the Apio project
3# -- (C) 2016-2018 FPGAwars
4# -- Author Jesús Arroyo
5# -- License GPLv2
6# -- Derived from:
7# ---- Platformio project
8# ---- (C) 2014-2016 Ivan Kravets <me@ikravets.com>
9# ---- License Apache v2
10"""Definition of underlying platforms supported by Apio."""
12import re
13import platform
14from dataclasses import dataclass
15from apio.utils import env_options
16from apio.common.apio_console import fatal_error
18# # -- The list of supported platforms and their attribute. The fields match
19# # -- the dataclass ApioPlatform below.
20# _SUPPORTED_PLATFORMS = {
21# "darwin-arm64": {
22# "type": "Mac OSX",
23# "variant": "ARM 64 bit (Apple Silicon)",
24# "is_darwin": True,
25# },
26# "linux-x86-64": {
27# "type": "Linux",
28# "variant": "X86 64 bit",
29# "is_linux": True,
30# },
31# "windows-amd64": {
32# "type": "Windows",
33# "variant": "x86 64 bit",
34# "is_windows": True,
35# },
36# }
39@dataclass(frozen=True)
40class ApioPlatform:
41 """A class with Apio supported platforms and their attributes."""
43 # -- Platform id.
44 id: str
46 # -- Human readable general platform type.
47 type: str
49 # -- Human readable variant of the platform type.
50 variant: str
52 # -- Set to True exactly one of these
53 is_darwin: bool = False
54 is_linux: bool = False
55 is_windows: bool = False
57 def __post_init__(self):
58 """Post init validation"""
60 # -- Constraint chars in platform id.
61 assert re.fullmatch(r"[a-z0-9-]+", self.id), self.id
63 # -- Exactly one of the platform types should be true.
64 assert (
65 sum([self.is_linux, self.is_windows, self.is_darwin]) == 1
66 ), self.id
68 # -- Sanity check the matching between names and types.
69 assert ("darwin" in self.id) == self.is_darwin, self.id
70 assert ("linux" in self.id) == self.is_linux, self.id
71 assert ("windows" in self.id) == self.is_windows, self.id
74# -- The supported platforms as a dict with platform id as keys and
75# -- ApioPlatform as values. It is constructed from the values in
76# -- _SUPPORTED_PLATFORMS.
77# _APIO_PLATFORMS: dict[str, ApioPlatform] = {
78# id: ApioPlatform(id=id, **fields)
79# for id, fields in _SUPPORTED_PLATFORMS.items()
80# }
82# -- The list of supported platforms and their attribute.
83_APIO_PLATFORMS_DICT = {
84 "darwin-arm64": ApioPlatform(
85 id="darwin-arm64",
86 type="Mac OSX",
87 variant="ARM 64 bit (Apple Silicon)",
88 is_darwin=True,
89 ),
90 "linux-x86-64": ApioPlatform(
91 id="linux-x86-64",
92 type="Linux",
93 variant="X86 64 bit",
94 is_linux=True,
95 ),
96 "windows-amd64": ApioPlatform(
97 id="windows-amd64",
98 type="Windows",
99 variant="x86 64 bit",
100 is_windows=True,
101 ),
102}
104# -- Same set of platforms, but keyed by platform id.
105# _APIO_PLATFORMS_DICT: dict[str, ApioPlatform] = {
106# p.id: p for p in _APIO_PLATFORMS_LIST
107# }
109# assert len(_APIO_PLATFORMS_LIST) == len(_APIO_PLATFORMS_DICT)
112def _determine_system_platform_id() -> str:
113 """Return a String with the current platform:
114 ex. linux-x86-64
115 ex. windows-amd64"""
117 # -- Get the platform: linux, windows, darwin
118 type_ = platform.system().lower()
119 platform_str = f"{type_}"
121 # -- Get the architecture
122 arch = platform.machine().lower()
124 # -- Special case for windows
125 if type_ == "windows": 125 ↛ 127line 125 didn't jump to line 127 because the condition on line 125 was never true
126 # -- Assume all the windows to be 64-bits
127 arch = "amd64"
129 # -- Add the architecture, if it exists
130 if arch: 130 ↛ 134line 130 didn't jump to line 134 because the condition on line 130 was always true
131 platform_str += f"_{arch}"
133 # -- Return the full platform
134 return platform_str
137def get_apio_platform() -> ApioPlatform:
138 """Determines and returns the platform id based on system info and
139 optional override."""
140 # -- Use override and get from the underlying system.
141 platform_id_override = env_options.get(env_options.APIO_PLATFORM)
142 if platform_id_override: 142 ↛ 143line 142 didn't jump to line 143 because the condition on line 142 was never true
143 platform_id = platform_id_override
144 else:
145 platform_id = _determine_system_platform_id()
147 # Stick to the naming conventions we use for boards, fpgas, etc.
148 platform_id = platform_id.replace("_", "-")
150 # -- Verify it's valid. This can be a user error if the override
151 # -- is invalid.
152 if platform_id not in _APIO_PLATFORMS_DICT: 152 ↛ 153line 152 didn't jump to line 153 because the condition on line 152 was never true
153 fatal_error(
154 f"Unknown platform id: [{platform_id}]",
155 info="See Apio's documentation for supported platforms.",
156 )
158 # -- All done ok.
159 return _APIO_PLATFORMS_DICT[platform_id]
162def get_all_apio_platforms() -> dict[str, ApioPlatform]:
163 """Return a dict with all supported platforms."""
164 return _APIO_PLATFORMS_DICT.copy()
167def get_system_info() -> str:
168 """Return a short string with additional platform info such as version."""
169 return platform.platform()