Coverage for apio/utils/apio_platforms.py: 83%
45 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-09 01:55 +0000
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-09 01:55 +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 sys
13import re
14import platform
15from dataclasses import dataclass
16from typing import Dict
17from apio.utils import env_options
18from apio.common.apio_console import cout, cerror
19from apio.common.apio_styles import INFO
21# TODO: Delete the commented out platforms and the xilinx_supported attribute.
23# -- The list of supported platforms and their attribute. The fields match
24# -- the dataclass ApioPlatform below.
25_SUPPORTED_PLATFORMS = {
26 "darwin-arm64": {
27 "type": "Mac OSX",
28 "variant": "ARM 64 bit (Apple Silicon)",
29 "is_darwin": True,
30 },
31 "linux-x86-64": {
32 "type": "Linux",
33 "variant": "X86 64 bit",
34 "is_linux": True,
35 },
36 "windows-amd64": {
37 "type": "Windows",
38 "variant": "x86 64 bit",
39 "is_windows": True,
40 },
41}
44@dataclass(frozen=True)
45class ApioPlatform:
46 """A class with Apio supported platforms and their attributes."""
48 # -- Platform id.
49 id: str
51 # -- Human readable general platform type.
52 type: str
54 # -- Human readable variant of the platform type.
55 variant: str
57 # -- Set to True exactly one of these
58 is_darwin: bool = False
59 is_linux: bool = False
60 is_windows: bool = False
62 def __post_init__(self):
63 """Post init validation"""
65 # -- Constraint chars in platform id.
66 assert re.fullmatch(r"[a-z0-9-]+", self.id), self.id
68 # -- Exactly one of the platform types should be true.
69 assert (
70 sum([self.is_linux, self.is_windows, self.is_darwin]) == 1
71 ), self.id
73 # -- Sanity check the matching between names and types.
74 assert ("darwin" in self.id) == self.is_darwin, self.id
75 assert ("linux" in self.id) == self.is_linux, self.id
76 assert ("windows" in self.id) == self.is_windows, self.id
79# -- The supported platforms as a dict with platform id as keys and
80# -- ApioPlatform as values. It is constructed from the values in
81# -- _SUPPORTED_PLATFORMS.
82_APIO_PLATFORMS: Dict[str, ApioPlatform] = {
83 id: ApioPlatform(id=id, **fields)
84 for id, fields in _SUPPORTED_PLATFORMS.items()
85}
88def _determine_system_platform_id() -> str:
89 """Return a String with the current platform:
90 ex. linux-x86-64
91 ex. windows-amd64"""
93 # -- Get the platform: linux, windows, darwin
94 type_ = platform.system().lower()
95 platform_str = f"{type_}"
97 # -- Get the architecture
98 arch = platform.machine().lower()
100 # -- Special case for windows
101 if type_ == "windows": 101 ↛ 103line 101 didn't jump to line 103 because the condition on line 101 was never true
102 # -- Assume all the windows to be 64-bits
103 arch = "amd64"
105 # -- Add the architecture, if it exists
106 if arch: 106 ↛ 110line 106 didn't jump to line 110 because the condition on line 106 was always true
107 platform_str += f"_{arch}"
109 # -- Return the full platform
110 return platform_str
113def get_apio_platform() -> ApioPlatform:
114 """Determines and returns the platform id based on system info and
115 optional override."""
116 # -- Use override and get from the underlying system.
117 platform_id_override = env_options.get(env_options.APIO_PLATFORM)
118 if platform_id_override: 118 ↛ 119line 118 didn't jump to line 119 because the condition on line 118 was never true
119 platform_id = platform_id_override
120 else:
121 platform_id = _determine_system_platform_id()
123 # Stick to the naming conventions we use for boards, fpgas, etc.
124 platform_id = platform_id.replace("_", "-")
126 # -- Verify it's valid. This can be a user error if the override
127 # -- is invalid.
128 if platform_id not in _APIO_PLATFORMS.keys(): 128 ↛ 129line 128 didn't jump to line 129 because the condition on line 128 was never true
129 cerror(f"Unknown platform id: [{platform_id}]")
130 cout(
131 "See Apio's documentation for supported platforms.",
132 style=INFO,
133 )
134 sys.exit(1)
136 # -- All done ok.
137 return _APIO_PLATFORMS[platform_id]
140def get_all_apio_platforms() -> Dict[str, ApioPlatform]:
141 """Return a dict with all supported platforms."""
142 return _APIO_PLATFORMS.copy()
145def get_system_info() -> str:
146 """Return a short string with additional platform info such as version."""
147 return platform.platform()