Skip to content
Open
32 changes: 32 additions & 0 deletions pycheribuild/config/compilation_targets.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ def default_install_dir(self, install_dir: DefaultInstallDir) -> Path:
return self.sysroot_dir
return super().default_install_dir(install_dir)

@classmethod
def _get_csa_project(cls) -> "type[BuildLLVMInterface]":
raise NotImplementedError()

@property
def c_compiler(self) -> Path:
return self._compiler_dir / "clang"
Expand Down Expand Up @@ -176,6 +180,18 @@ def nm(self) -> Path:
def strip_tool(self) -> Path:
return self._compiler_dir / "llvm-strip"

@property
def ccc_analyzer(self) -> Path:
return self._get_csa_project().get_native_install_path(self.config) / "libexec/ccc-analyzer"

@property
def cxx_analyzer(self) -> Path:
return self._get_csa_project().get_native_install_path(self.config) / "libexec/c++-analyzer"

@property
def scan_build(self) -> Path:
return self._get_csa_project().get_native_install_path(self.config) / "bin/scan-build"

@classmethod
@abstractmethod
def triple_for_target(
Expand Down Expand Up @@ -638,6 +654,10 @@ def _get_run_project(self, xtarget: "CrossCompileTarget", caller: SimpleProject)
result = SimpleProject.get_instance_for_target_name("run", xtarget, caller.config, caller)
return typing.cast(LaunchFreeBSDInterface, result)

@classmethod
def _get_csa_project(cls) -> "type[BuildLLVMInterface]":
return typing.cast("type[BuildLLVMInterface]", SimpleProject.get_class_for_target_name("cheri-csa", None))

@classmethod
def is_cheribsd(cls) -> bool:
return True
Expand Down Expand Up @@ -725,6 +745,10 @@ def essential_compiler_and_linker_flags_impl(cls, instance: "CheriBSDTargetInfo"
result.extend(cheribsd_morello_version_dependent_flags(version, xtarget.is_cheri_purecap()))
return result

@classmethod
def _get_csa_project(cls) -> "type[BuildLLVMInterface]":
return typing.cast("type[BuildLLVMInterface]", SimpleProject.get_class_for_target_name("morello-csa", None))


# FIXME: This is completely wrong since cherios is not cheribsd, but should work for now:
class CheriOSTargetInfo(CheriBSDTargetInfo):
Expand Down Expand Up @@ -1093,6 +1117,14 @@ def nm(self) -> Path:
def strip_tool(self) -> Path:
return self.bindir / (self.binary_prefix + "strip")

@property
def ccc_analyzer(self) -> Path:
raise NotImplementedError

@property
def cxx_analyzer(self) -> Path:
raise NotImplementedError

@classmethod
def essential_compiler_and_linker_flags_impl(cls, *args, **kwargs) -> "list[str]":
# This version of GCC should work without any additional flags
Expand Down
16 changes: 16 additions & 0 deletions pycheribuild/config/target_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,14 @@ def nm(self) -> Path: ...
@abstractmethod
def strip_tool(self) -> Path: ...

@property
@abstractmethod
def ccc_analyzer(self) -> Path: ...

@property
@abstractmethod
def cxx_analyzer(self) -> Path: ...

@classmethod
@abstractmethod
def essential_compiler_and_linker_flags_impl(
Expand Down Expand Up @@ -635,6 +643,14 @@ def nm(self) -> Path:
def strip_tool(self) -> Path:
return self.c_compiler.parent / "strip"

@property
def ccc_analyzer(self) -> Path:
raise NotImplementedError

@property
def cxx_analyzer(self) -> Path:
raise NotImplementedError

@classmethod
def is_freebsd(cls) -> bool:
return OSInfo.IS_FREEBSD
Expand Down
4 changes: 4 additions & 0 deletions pycheribuild/projects/cmake.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ def custom_target_name(base_target: str, xtarget: CrossCompileTarget) -> str:
cross_install_dir = DefaultInstallDir.ROOTFS_OPTBASE
supported_architectures = CompilationTargets.ALL_SUPPORTED_CHERIBSD_TARGETS

@classmethod
def can_build_with_csa(cls) -> bool:
return True

def linkage(self):
# We always want to build the CheriBSD CTest binary static so that we can use in QEMU without needing libuv.
assert "libuv" in self.dependencies
Expand Down
21 changes: 19 additions & 2 deletions pycheribuild/projects/cross/cheribsd.py
Original file line number Diff line number Diff line change
Expand Up @@ -1005,8 +1005,8 @@ def _setup_cross_toolchain_config(self) -> None:
if not xccinfo.is_clang:
self.ask_for_confirmation("Cross compiler is not clang, are you sure you want to continue?")
self.cross_toolchain_config.set_env(
XCC=self.CC,
XCXX=self.CXX,
XCC=self.cc_wrapper,
XCXX=self.cxx_wrapper,
XCPP=self.CPP,
X_COMPILER_TYPE=xccinfo.compiler, # This is needed otherwise the build assumes it should build with $CC
)
Expand Down Expand Up @@ -1196,9 +1196,14 @@ def _buildkernel(
# Don't build a compiler if we are using and external toolchain (only build config, etc)
if not self.use_bootstrapped_toolchain:
kernel_toolchain_opts.set_with_options(LLD_BOOTSTRAP=False, CLANG=False, CLANG_BOOTSTRAP=False)
kernel_toolchain_opts.exclude_from_csa = True
self.run_make("kernel-toolchain", options=kernel_toolchain_opts)
self.kernel_toolchain_exists = True
self.info("Building kernels for configs:", " ".join(kernconfs))

if self.use_csa:
kernel_make_args.set(BUILD_WITH_STRICT_TMPPATH=False) # Look for perl in PATH

self.run_make(
"buildkernel",
options=kernel_make_args,
Expand Down Expand Up @@ -1523,6 +1528,10 @@ def add_cross_build_options(self) -> None:
# links from /usr/bin/mail to /usr/bin/Mail won't work on case-insensitve fs
self.make_args.set_with_options(MAIL=False)

if self.use_csa:
ccinfo = self.get_compiler_info(self.host_CC)
self.make_args.set_env(COMPILER_TYPE=ccinfo.compiler)

def libcompat_name(self) -> str:
if self.crosscompile_target.is_cheri_purecap():
return "lib64"
Expand Down Expand Up @@ -1917,6 +1926,14 @@ def setup_config_options(cls, kernel_only_target=False, install_directory_help=N
"build the libraries and skip all binaries",
)

@classmethod
def can_build_with_csa(cls) -> bool:
return True

@classproperty
def extra_scan_build_args(self) -> "list[str]":
return ["-disable-checker", "alpha.core.PointerSub"]

def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
self.extra_kernels_with_mfs: "list[str]" = []
Expand Down
4 changes: 4 additions & 0 deletions pycheribuild/projects/cross/compiler_rt.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ class BuildCompilerRt(CrossCompileCMakeProject):
_check_install_dir_conflict = False
supported_architectures = CompilationTargets.ALL_SUPPORTED_CHERIBSD_AND_HOST_TARGETS

@classmethod
def can_build_with_csa(cls) -> bool:
return True

def setup(self):
# For the NATIVE variant we want to install to the compiler resource dir:
if self.compiling_for_host():
Expand Down
6 changes: 5 additions & 1 deletion pycheribuild/projects/cross/dlmalloc.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ class DLMalloc(CrossCompileProject):
make_kind = MakeCommandKind.GnuMake
native_install_dir = DefaultInstallDir.CHERI_SDK

@classmethod
def can_build_with_csa(cls) -> bool:
return True

@classmethod
def setup_config_options(cls, **kwargs):
super().setup_config_options(**kwargs)
Expand Down Expand Up @@ -119,7 +123,7 @@ def setup(self):
self.make_args.set(DEBUG=self.debug)
self.make_args.set(CAPREVOKE=self.revoke)
self.make_args.set(SRCDIR=self.source_dir)
self.make_args.set_env(CC=self.CC, CFLAGS=commandline_to_str(self.default_compiler_flags + self.CFLAGS))
self.make_args.set_env(CC=self.cc_wrapper, CFLAGS=commandline_to_str(self.default_compiler_flags + self.CFLAGS))
if not self.compiling_for_host():
self.make_args.set_env(CHERI_SDK=self.target_info.sdk_root_dir)

Expand Down
4 changes: 4 additions & 0 deletions pycheribuild/projects/cross/libcxx.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ class BuildLibCXXRT(_CxxRuntimeCMakeProject):
repository = GitRepository("https://github.com/CTSRD-CHERI/libcxxrt.git")
supported_architectures = CompilationTargets.ALL_SUPPORTED_CHERIBSD_AND_BAREMETAL_AND_HOST_TARGETS

@classmethod
def can_build_with_csa(cls) -> bool:
return True

@classmethod
def dependencies(cls, config: CheriConfig) -> "tuple[str, ...]":
result = super().dependencies(config)
Expand Down
40 changes: 40 additions & 0 deletions pycheribuild/projects/cross/llvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -871,3 +871,43 @@ def update(self):
src_dir=self.source_dir / "tools/lldb",
revision=self.lldb_revision,
)


class BuildCheriLLVMWithCSA(BuildCheriLLVM):
repository = GitRepository(
"https://github.com/rems-project/llvm-project.git", force_branch=True, default_branch="cheri-csa"
)
default_directory_basename = "cheri-csa"
target = "cheri-csa"
_default_install_dir_fn = ComputedDefaultValue(
function=lambda config, project: config.output_root / "cheri-csa", as_string="$INSTALL_ROOT/cheri-csa"
)

skip_misc_llvm_tools = True
included_projects = ["clang"]
skip_static_analyzer = False
hide_options_from_help = True

@classmethod
def get_native_install_path(cls, config: CheriConfig):
return config.output_root / "cheri-csa"


class BuildMorelloLLVMWithCSA(BuildMorelloLLVM):
repository = GitRepository(
"https://github.com/rems-project/llvm-project.git", force_branch=True, default_branch="morello-csa-llvm-14"
)
default_directory_basename = "morello-csa"
target = "morello-csa"
_default_install_dir_fn = ComputedDefaultValue(
function=lambda config, project: config.output_root / "morello-csa", as_string="$INSTALL_ROOT/morello-csa"
)

skip_misc_llvm_tools = True
included_projects = ["clang"]
skip_static_analyzer = False
hide_options_from_help = True

@classmethod
def get_native_install_path(cls, config: CheriConfig):
return config.output_root / "morello-csa"
8 changes: 6 additions & 2 deletions pycheribuild/projects/cross/newlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ def custom_target_name(base_target: str, xtarget: CrossCompileTarget) -> str:
return base_target + "-baremetal-" + xtarget.base_arch_suffix
return base_target + "-" + xtarget.generic_target_suffix

@classmethod
def can_build_with_csa(cls) -> bool:
return True

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
assert self._install_prefix == Path("/", self.target_info.target_triple)
Expand Down Expand Up @@ -99,8 +103,8 @@ def setup(self):
bindir = self.sdk_bindir
self.add_configure_vars(
AS_FOR_TARGET=str(self.CC), # + target_cflags,
CC_FOR_TARGET=str(self.CC), # + target_cflags,
CXX_FOR_TARGET=str(self.CXX), # + target_cflags,
CC_FOR_TARGET=str(self.cc_wrapper), # + target_cflags,
CXX_FOR_TARGET=str(self.cxx_wrapper), # + target_cflags,
AR_FOR_TARGET=self.target_info.ar,
STRIP_FOR_TARGET=self.target_info.strip_tool,
OBJCOPY_FOR_TARGET=bindir / "objcopy",
Expand Down
4 changes: 4 additions & 0 deletions pycheribuild/projects/cross/sqlite.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ class BuildSQLite(CrossCompileAutotoolsProject):
"https://github.com/CTSRD-CHERI/sqlite.git", default_branch="3.22.0-cheri", force_branch=True
)

@classmethod
def can_build_with_csa(cls) -> bool:
return True

def check_system_dependencies(self) -> None:
super().check_system_dependencies()
# XXX: Disabling amalgamation should remove the requirement for tclsh, but it seems the build still invokes it.
Expand Down
4 changes: 4 additions & 0 deletions pycheribuild/projects/cross/zlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
class BuildZlib(CrossCompileAutotoolsProject):
repository = GitRepository("https://github.com/CTSRD-CHERI/zlib.git")

@classmethod
def can_build_with_csa(cls) -> bool:
return True

# Enable the same hacks as nginx since this isn't really autoconf...
add_host_target_build_config_options = False
_configure_understands_enable_static = False
Expand Down
Loading