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

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.""" 

11 

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 

20 

21# TODO: Delete the commented out platforms and the xilinx_supported attribute. 

22 

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} 

42 

43 

44@dataclass(frozen=True) 

45class ApioPlatform: 

46 """A class with Apio supported platforms and their attributes.""" 

47 

48 # -- Platform id. 

49 id: str 

50 

51 # -- Human readable general platform type. 

52 type: str 

53 

54 # -- Human readable variant of the platform type. 

55 variant: str 

56 

57 # -- Set to True exactly one of these 

58 is_darwin: bool = False 

59 is_linux: bool = False 

60 is_windows: bool = False 

61 

62 def __post_init__(self): 

63 """Post init validation""" 

64 

65 # -- Constraint chars in platform id. 

66 assert re.fullmatch(r"[a-z0-9-]+", self.id), self.id 

67 

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 

72 

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 

77 

78 

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} 

86 

87 

88def _determine_system_platform_id() -> str: 

89 """Return a String with the current platform: 

90 ex. linux-x86-64 

91 ex. windows-amd64""" 

92 

93 # -- Get the platform: linux, windows, darwin 

94 type_ = platform.system().lower() 

95 platform_str = f"{type_}" 

96 

97 # -- Get the architecture 

98 arch = platform.machine().lower() 

99 

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" 

104 

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}" 

108 

109 # -- Return the full platform 

110 return platform_str 

111 

112 

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() 

122 

123 # Stick to the naming conventions we use for boards, fpgas, etc. 

124 platform_id = platform_id.replace("_", "-") 

125 

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) 

135 

136 # -- All done ok. 

137 return _APIO_PLATFORMS[platform_id] 

138 

139 

140def get_all_apio_platforms() -> Dict[str, ApioPlatform]: 

141 """Return a dict with all supported platforms.""" 

142 return _APIO_PLATFORMS.copy() 

143 

144 

145def get_system_info() -> str: 

146 """Return a short string with additional platform info such as version.""" 

147 return platform.platform()