Skip to content

Commit 6504b03

Browse files
authored
Merge branch 'main' into grpc-targets
2 parents fb958af + 0144e72 commit 6504b03

File tree

13 files changed

+128
-96
lines changed

13 files changed

+128
-96
lines changed

pycheribuild/config/chericonfig.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ def clang_march_flag(self) -> str:
123123
return self.value[1]
124124

125125

126+
class RiscvFloatAbi(Enum):
127+
SOFT = "soft"
128+
HARD = "hard"
129+
130+
126131
def _default_arm_none_eabi_prefix(c: "CheriConfig", _):
127132
# see if the local install exists:
128133
default_path = c.output_root / c.local_arm_none_eabi_toolchain_relpath
@@ -319,7 +324,14 @@ def __init__(self, loader, action_class: "type[CheribuildActionEnum]") -> None:
319324
default=MipsFloatAbi.SOFT,
320325
type=MipsFloatAbi,
321326
group=loader.cross_compile_options_group,
322-
help="The floating point ABI to use for building MIPS+CHERI programs",
327+
help="Whether to use soft or hard float ABIs when targeting MIPS",
328+
)
329+
self.riscv_float_abi = loader.add_option(
330+
"riscv-float-abi",
331+
default=RiscvFloatAbi.HARD,
332+
type=RiscvFloatAbi,
333+
group=loader.cross_compile_options_group,
334+
help="Whether to use soft or hard float ABIs when targeting RISC-V",
323335
)
324336
self.aarch64_fp_and_simd_options = loader.add_option(
325337
"aarch64-fp-and-simd-options",

pycheribuild/config/compilation_targets.py

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -149,15 +149,18 @@ def default_install_dir(self, install_dir: DefaultInstallDir) -> Path:
149149

150150
@property
151151
def c_compiler(self) -> Path:
152-
return self._compiler_dir / "clang"
152+
override = self.project.custom_c_compiler
153+
return self._compiler_dir / "clang" if override is None else override
153154

154155
@property
155156
def cxx_compiler(self) -> Path:
156-
return self._compiler_dir / "clang++"
157+
override = self.project.custom_cxx_compiler
158+
return self._compiler_dir / "clang++" if override is None else override
157159

158160
@property
159161
def c_preprocessor(self) -> Path:
160-
return self._compiler_dir / "clang-cpp"
162+
override = self.project.custom_c_preprocessor
163+
return self._compiler_dir / "clang-cpp" if override is None else override
161164

162165
@property
163166
def linker(self) -> Path:
@@ -203,10 +206,10 @@ def essential_compiler_and_linker_flags_impl(
203206
default_flags_only=False,
204207
):
205208
assert xtarget is not None
206-
if softfloat is None:
207-
softfloat = cls.uses_softfloat_by_default(xtarget)
208209
config = instance.config
209210
project = instance.project
211+
if softfloat is None:
212+
softfloat = project.uses_softfloat_by_default()
210213
# noinspection PyProtectedMember
211214
if perform_sanity_checks and not project._setup_called:
212215
project.fatal(
@@ -241,19 +244,18 @@ def essential_compiler_and_linker_flags_impl(
241244
result.append("-integrated-as")
242245
result.append("-G0") # no small objects in GOT optimization
243246
# Floating point ABI:
247+
float_abi = MipsFloatAbi.SOFT if softfloat else MipsFloatAbi.HARD
248+
result.append(float_abi.clang_float_flag())
244249
if cls.is_baremetal() or cls.is_rtems():
245-
# The baremetal driver doesn't add -fPIC for CHERI
246250
if xtarget.is_cheri_purecap([CPUArchitecture.MIPS64]):
251+
assert float_abi == MipsFloatAbi.SOFT # For now use soft-float to avoid compiler crashes
252+
# The baremetal driver doesn't add -fPIC for CHERI
247253
result.append("-fPIC")
248-
# For now use soft-float to avoid compiler crashes
249-
result.append(MipsFloatAbi.SOFT.clang_float_flag())
250254
else:
251255
# We don't have a softfloat library baremetal so always compile hard-float
252-
result.append(MipsFloatAbi.HARD.clang_float_flag())
256+
assert float_abi == MipsFloatAbi.HARD # For now use soft-float to avoid compiler crashes
253257
result.append("-fno-pic")
254258
result.append("-mno-abicalls")
255-
else:
256-
result.append(config.mips_float_abi.clang_float_flag())
257259

258260
# CPU flags (currently always BERI):
259261
if cls.is_cheribsd():
@@ -340,10 +342,6 @@ def get_riscv_abi(cls, xtarget: CrossCompileTarget, *, softfloat: bool) -> str:
340342
abi += "d"
341343
return abi
342344

343-
@classmethod
344-
def uses_softfloat_by_default(cls, xtarget: "CrossCompileTarget"):
345-
return False
346-
347345

348346
class FreeBSDTargetInfo(_ClangBasedTargetInfo):
349347
shortname: str = "FreeBSD"
@@ -843,11 +841,6 @@ def localbase(self) -> Path:
843841
def is_baremetal(cls):
844842
return True
845843

846-
@classmethod
847-
def uses_softfloat_by_default(cls, xtarget: "CrossCompileTarget"):
848-
# Note: RISC-V Baremetal/FreeRTOS currently only supports softfloat
849-
return xtarget.is_riscv(include_purecap=True)
850-
851844

852845
class NewlibBaremetalTargetInfo(BaremetalClangTargetInfo):
853846
shortname = "Newlib"
@@ -928,10 +921,6 @@ def cmake_extra_toolchain_file_code(self) -> str:
928921
set(CMAKE_DL_LIBS "")
929922
"""
930923

931-
@classmethod
932-
def uses_softfloat_by_default(cls, xtarget: "CrossCompileTarget"):
933-
return False
934-
935924
@classmethod
936925
def essential_compiler_and_linker_flags_impl(cls, *args, xtarget: "CrossCompileTarget", **kwargs) -> "list[str]":
937926
result = super().essential_compiler_and_linker_flags_impl(*args, xtarget=xtarget, **kwargs)
@@ -952,7 +941,10 @@ def essential_compiler_and_linker_flags_impl(cls, *args, xtarget: "CrossCompileT
952941
@property
953942
def sysroot_dir(self) -> Path:
954943
sysroot_dir = self.config.sysroot_output_root / self.config.default_cheri_sdk_directory_name
955-
return sysroot_dir / "picolibc" / self.target.get_rootfs_target().generic_arch_suffix
944+
result = sysroot_dir / "picolibc" / self.target.get_rootfs_target().generic_arch_suffix
945+
if self.target.is_riscv(include_purecap=True):
946+
result /= self.get_riscv_abi(self.target, softfloat=self.project.uses_softfloat_by_default())
947+
return result
956948

957949
@classmethod
958950
def _get_compiler_project(cls) -> "type[BuildLLVMInterface]":

pycheribuild/config/config_loader_base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ class ConfigLoaderBase(ABC):
6565
# will be set later...
6666
_cheri_config: ConfigBase
6767

68-
option_handles: "typing.ClassVar[dict[str, ConfigOptionHandle]]" = {}
69-
_json: "typing.ClassVar[dict[str, _LoadedConfigValue]]" = {}
68+
option_handles: "dict[str, ConfigOptionHandle]" = {}
69+
_json: "dict[str, _LoadedConfigValue]" = {}
7070
is_completing_arguments: bool = "_ARGCOMPLETE" in os.environ
7171
is_generating_readme: bool = "_GENERATING_README" in os.environ
7272
is_running_unit_tests: bool = False

pycheribuild/config/target_info.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
from pathlib import Path
3838
from typing import ClassVar, Optional
3939

40-
from .chericonfig import AArch64FloatSimdOptions, CheriConfig, MipsFloatAbi
40+
from .chericonfig import AArch64FloatSimdOptions, CheriConfig, MipsFloatAbi, RiscvFloatAbi
4141
from ..filesystemutils import FileSystemUtils
4242
from ..processutils import CompilerInfo, get_compiler_info
4343
from ..utils import OSInfo, fatal_error, final, status_update, warning_message
@@ -180,6 +180,8 @@ def __init__(self, config):
180180
super().__init__(config)
181181
self._init_called = False
182182

183+
def uses_softfloat_by_default(self) -> bool: ...
184+
183185
def get_compiler_info(self, compiler: Path) -> CompilerInfo:
184186
return get_compiler_info(compiler, config=self.config)
185187

@@ -603,21 +605,18 @@ def default_install_dir(self, install_dir: DefaultInstallDir) -> Path:
603605

604606
@property
605607
def c_compiler(self) -> Path:
606-
if self.project.custom_c_compiler is not None:
607-
return self.project.custom_c_compiler
608-
return self.host_c_compiler(self.config)
608+
override = self.project.custom_c_compiler
609+
return self.host_c_compiler(self.config) if override is None else override
609610

610611
@property
611612
def cxx_compiler(self) -> Path:
612-
if self.project.custom_cxx_compiler is not None:
613-
return self.project.custom_cxx_compiler
614-
return self.host_cxx_compiler(self.config)
613+
override = self.project.custom_cxx_compiler
614+
return self.host_cxx_compiler(self.config) if override is None else override
615615

616616
@property
617617
def c_preprocessor(self) -> Path:
618-
if self.project.custom_c_preprocessor is not None:
619-
return self.project.custom_c_preprocessor
620-
return self.host_c_preprocessor(self.config)
618+
override = self.project.custom_c_preprocessor
619+
return self.host_c_preprocessor(self.config) if override is None else override
621620

622621
@property
623622
def linker(self) -> Path:
@@ -933,6 +932,8 @@ def cheri_config_suffix(self, config: CheriConfig) -> str:
933932
result += "-subobject-nodebug"
934933
if self.is_mips(include_purecap=True) and config.mips_float_abi == MipsFloatAbi.HARD:
935934
result += "-hardfloat"
935+
if self.is_riscv(include_purecap=True) and config.riscv_float_abi == RiscvFloatAbi.SOFT:
936+
result += "-softfloat"
936937
if self.is_aarch64(include_purecap=True):
937938
if config.aarch64_fp_and_simd_options != AArch64FloatSimdOptions.DEFAULT:
938939
result += config.aarch64_fp_and_simd_options.config_suffix()

pycheribuild/mtree.py

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
# SUCH DAMAGE.
2929
#
3030

31-
import collections
31+
import collections.abc
3232
import fnmatch
3333
import io
3434
import os
@@ -190,31 +190,34 @@ def _glob(self, patfrags: "list[str]", prefix: MtreePath, *, case_sensitive=Fals
190190

191191
def glob(self, pattern: str, *, case_sensitive=False) -> Iterator[MtreePath]:
192192
if len(pattern) == 0:
193-
raise StopIteration() # pytype does not like plain "return"
193+
return iter([])
194194
head, tail = os.path.split(pattern)
195195
patfrags = [tail]
196196
while head:
197197
head, tail = os.path.split(head)
198198
patfrags.insert(0, tail)
199199
return self._glob(patfrags, MtreePath(), case_sensitive=case_sensitive)
200200

201-
def _walk(self, top, prefix):
201+
def _walk(self, top, prefix) -> "Iterator[tuple[MtreePath, list[str], list[str]]]":
202202
split = self._split_key(top)
203203
if split is not None:
204-
return self.children[split[0]]._walk(split[1], prefix / split[0])
204+
if split[0] in self.children:
205+
yield from self.children[split[0]]._walk(split[1], prefix / split[0])
206+
return
205207
if self.entry is not None and self.entry.attributes["type"] != "dir":
206-
raise StopIteration() # pytype does not like plain "return"
207-
files = []
208-
dirs = []
208+
return
209+
files: "list[tuple[str, MtreeSubtree]]" = []
210+
dirs: "list[tuple[str, MtreeSubtree]]" = []
209211
for k, v in self.children.items():
210212
if v.entry is not None and v.entry.attributes["type"] != "dir":
211213
files.append((k, v))
212214
else:
213215
dirs.append((k, v))
214-
yield (prefix, list([k for k, _ in dirs]), list([k for k, _ in files]))
215-
return iter([v._walk(MtreePath(), prefix) for _, v in dirs])
216+
yield prefix, list([k for k, _ in dirs]), list([k for k, _ in files])
217+
for _, v in dirs:
218+
yield from v._walk(MtreePath(), prefix)
216219

217-
def walk(self, top):
220+
def walk(self, top) -> "Iterator[tuple[MtreePath, list[str], list[str]]]":
218221
return self._walk(top, MtreePath())
219222

220223

@@ -315,6 +318,7 @@ def add_file(
315318
if symlink_dest is not None:
316319
mode = "0755"
317320
else:
321+
assert file is not None
318322
mode = self.infer_mode_string(file, False)
319323
mode = self._ensure_mtree_mode_fmt(mode)
320324
mtree_path = self._ensure_mtree_path_fmt(path_in_image)
@@ -401,15 +405,16 @@ def add_from_mtree(self, mtree_file: "MtreeFile", path: "Union[PurePath, str]",
401405
assert not path.startswith("/")
402406
path = path.rstrip("/") # remove trailing slashes
403407
mtree_path = self._ensure_mtree_path_fmt(path)
404-
if mtree_path in self._mtree:
408+
if self.get(mtree_path) is not None:
405409
return
406-
if mtree_path not in mtree_file._mtree:
410+
subtree = mtree_file.get(mtree_path)
411+
if subtree is None:
407412
fatal_error("Could not find " + str(mtree_path) + " in source mtree", pretend=True)
408413
return
409414
parent = mtree_path.parent
410415
if parent != mtree_path:
411416
self.add_from_mtree(mtree_file, parent, print_status=print_status)
412-
attribs = mtree_file.get(mtree_path).attributes
417+
attribs = subtree.attributes
413418
entry = MtreeEntry(mtree_path, attribs)
414419
if print_status:
415420
if "link" in attribs:
@@ -465,15 +470,15 @@ def write(self, output: "Union[io.StringIO,Path,typing.IO]", *, pretend):
465470
output.write("\n")
466471
output.write("# END\n")
467472

468-
def get(self, key):
473+
def get(self, key) -> Optional[MtreeEntry]:
469474
return self._mtree.get(key)
470475

471476
@property
472-
def root(self):
477+
def root(self) -> MtreeSubtree:
473478
return self._mtree
474479

475480
def glob(self, pattern: str, *, case_sensitive=False) -> Iterator[MtreePath]:
476481
return self._mtree.glob(pattern, case_sensitive=case_sensitive)
477482

478-
def walk(self, top):
483+
def walk(self, top) -> "Iterator[tuple[MtreePath, list[str], list[str]]]":
479484
return self._mtree.walk(top)

pycheribuild/projects/build_qemu.py

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,6 @@ def setup(self):
241241
"-Werror=implicit-function-declaration",
242242
"-Werror=incompatible-pointer-types",
243243
"-Werror=format",
244-
"-Werror=return-type",
245244
"-Wno-sign-compare",
246245
"-Wno-unused-parameter",
247246
"-Wno-missing-field-initializers",
@@ -316,6 +315,25 @@ def setup(self):
316315
"--make=" + self.make_args.command,
317316
],
318317
)
318+
python_bin = sys.executable
319+
python_search_path = self.config.dollar_path_with_other_tools
320+
# Python from a venv cannot be used for QEMU builds, use the base installation instead.
321+
if sys.prefix != sys.base_prefix:
322+
python_bin = sys.executable.replace(sys.prefix, sys.base_prefix)
323+
python_search_path = python_search_path.replace(sys.prefix, sys.base_prefix)
324+
py3_version = get_program_version(
325+
Path(python_bin),
326+
config=self.config,
327+
regex=re.compile(rb"Python\s+(\d+)\.(\d+)\.?(\d+)?"),
328+
)
329+
# QEMU tests are not compatible with 3.12 yet, try to use an older version in that case
330+
if py3_version >= (3, 12, 0):
331+
for minor_version in (11, 10, 9):
332+
found = shutil.which(f"python3.{minor_version}", path=python_search_path)
333+
if found:
334+
python_bin = found
335+
break
336+
self.configure_args.append(f"--python={python_bin}")
319337

320338
if self.config.create_compilation_db:
321339
self.make_args.set(V=1) # Otherwise bear can't parse the compiler output
@@ -506,25 +524,6 @@ def setup(self):
506524
# Linux/BSD-user is not supported for CHERI (yet)
507525
self.configure_args.append("--disable-bsd-user")
508526
self.configure_args.append("--disable-linux-user")
509-
python_bin = sys.executable
510-
python_search_path = self.config.dollar_path_with_other_tools
511-
# Python from a venv cannot be used for QEMU builds, use the base installation instead.
512-
if sys.prefix != sys.base_prefix:
513-
python_bin = sys.executable.replace(sys.prefix, sys.base_prefix)
514-
python_search_path = python_search_path.replace(sys.prefix, sys.base_prefix)
515-
py3_version = get_program_version(
516-
Path(python_bin),
517-
config=self.config,
518-
regex=re.compile(rb"Python\s+(\d+)\.(\d+)\.?(\d+)?"),
519-
)
520-
# QEMU tests are not compatible with 3.12 yet, try to use an older version in that case
521-
if py3_version >= (3, 12, 0):
522-
for minor_version in (11, 10, 9):
523-
found = shutil.which(f"python3.{minor_version}", path=python_search_path)
524-
if found:
525-
python_bin = found
526-
break
527-
self.configure_args.append(f"--python={python_bin}")
528527

529528
# TODO: tests:
530529
# noinspection PyUnreachableCode

pycheribuild/projects/cross/freertos.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ class BuildFreeRTOS(CrossCompileAutotoolsProject):
5353
)
5454
default_install_dir = DefaultInstallDir.ROOTFS_LOCALBASE
5555

56+
def uses_softfloat_by_default(self) -> bool:
57+
return True # FreeRTOS currently only supports soft-float
58+
5659
# FreeRTOS Demos to build
5760
supported_freertos_demos = [
5861
# Generic/simple (CHERI-)RISC-V Demo that runs main_blinky on simulators

0 commit comments

Comments
 (0)