Skip to content

Commit

Permalink
Add new current-directory and current-directory-<type> targets
Browse files Browse the repository at this point in the history
These are special targets that perform a build where the source
directory is the current working directory and the build directory's
basename is the name of the current directory.

The current-directory-<type> targets are for a specific build system.
The current-directory target is an even more special target that looks
for various build system files and tries to infer what to use; note that
any options must be set on the real tool target still, as it's
implemented by having a dynamically-calculated dependency.
  • Loading branch information
jrtc27 committed Aug 6, 2021
1 parent bc087aa commit 7e2ff92
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 9 deletions.
12 changes: 8 additions & 4 deletions pycheribuild/projects/cross/crosscompileproject.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@

from ..project import (AutotoolsProject, BuildType, CheriConfig, CMakeProject, commandline_to_str, CrossCompileTarget,
DefaultInstallDir, GitRepository, Linkage, MakeCommandKind, MakefileProject, MesonProject,
Project, SubversionRepository)
Project, SimpleProject, SubversionRepository)
from ...config.compilation_targets import CompilationTargets
from ...config.target_info import AutoVarInit
from ...utils import AnsiColour, coloured

__all__ = ["CheriConfig", "CrossCompileCMakeProject", "CrossCompileAutotoolsProject", # no-combine
"CrossCompileTarget", "CrossCompileProject", "MakeCommandKind", "Linkage", # no-combine
"DefaultInstallDir", "BuildType", "CompilationTargets", "GitRepository", # no-combine
"CrossCompileMixin", "FettProjectMixin", "CrossCompileMakefileProject", # no-combine
"CrossCompileTarget", "CrossCompileSimpleProject", "CrossCompileProject", # no-combine
"MakeCommandKind", "Linkage", "DefaultInstallDir", "BuildType", "CompilationTargets", # no-combine
"GitRepository", "CrossCompileMixin", "FettProjectMixin", "CrossCompileMakefileProject", # no-combine
"CrossCompileMesonProject", "commandline_to_str", "SubversionRepository"] # no-combine


Expand All @@ -59,6 +59,10 @@ class CrossCompileMixin(object):
cross_install_dir = DefaultInstallDir.ROOTFS_LOCALBASE


class CrossCompileSimpleProject(CrossCompileMixin, SimpleProject):
do_not_add_to_targets = True


class CrossCompileProject(CrossCompileMixin, Project):
do_not_add_to_targets = True

Expand Down
91 changes: 91 additions & 0 deletions pycheribuild/projects/cross/current_directory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Jessica Clarke
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

import os
from pathlib import Path

from .crosscompileproject import (CrossCompileSimpleProject, CrossCompileAutotoolsProject, CrossCompileCMakeProject,
CrossCompileMakefileProject, CrossCompileMesonProject)
from ..project import ExternallyManagedSourceRepository
from ...config.loader import ComputedDefaultValue


_cwd_path = Path(os.getcwd())


def _cwd_source_dir(config, project):
return _cwd_path


def _cwd_directory_basename(config, project):
return _cwd_path.name


class CurrentDirectoryMixin(object):
do_not_add_to_targets = True
default_directory_basename = ComputedDefaultValue(function=_cwd_directory_basename,
as_string="$SOURCE_DIR_NAME")
inherit_default_directory_basename = True
repository = ExternallyManagedSourceRepository()
source_dir = ComputedDefaultValue(function=_cwd_source_dir, as_string="$CWD")


class BuildCurrent_Directory_Autotools(CurrentDirectoryMixin, CrossCompileAutotoolsProject):
autodetect_files = ["configure"]


class BuildCurrent_Directory_CMake(CurrentDirectoryMixin, CrossCompileCMakeProject):
autodetect_files = ["CMakeLists.txt"]


class BuildCurrent_Directory_Makefile(CurrentDirectoryMixin, CrossCompileMakefileProject):
autodetect_files = ["GNUmakefile", "makefile", "Makefile"]


class BuildCurrent_Directory_Meson(CurrentDirectoryMixin, CrossCompileMesonProject):
autodetect_files = ["meson.build"]


class BuildCurrent_Directory(CurrentDirectoryMixin, CrossCompileSimpleProject):
dependencies_must_be_built = True
direct_dependencies_only = True

@classmethod
def dependencies(cls, config):
classes = [
BuildCurrent_Directory_Autotools,
BuildCurrent_Directory_CMake,
BuildCurrent_Directory_Makefile,
BuildCurrent_Directory_Meson
]
for c in classes:
for f in c.autodetect_files:
if (_cwd_path / f).is_file():
return [c.target]
return []

def process(self):
if not self.dependencies(self.config):
self.fatal("Could not infer build system in use")
28 changes: 23 additions & 5 deletions pycheribuild/projects/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def die(msg):
" -- set target= or do_not_add_to_targets=True")

# The default source/build/install directory name defaults to the target unless explicitly overwritten.
if "default_directory_basename" not in clsdict:
if "default_directory_basename" not in clsdict and not cls.inherit_default_directory_basename:
cls.default_directory_basename = target_name

if "project_name" in clsdict:
Expand Down Expand Up @@ -207,7 +207,10 @@ class SimpleProject(FileSystemUtils, metaclass=ProjectSubclassDefinitionHook):
# These two class variables can be defined in subclasses to customize dependency ordering of targets
target = "" # type: str
# The source dir/build dir names will be inferred from the target name unless default_directory_basename is set.
# Note that this is not inherited by default unless you set inherit_default_directory_basename (which itself is
# inherited as normal, so can be set in a base class).
default_directory_basename = None # type: str
inherit_default_directory_basename = False # type: bool
# Old names in the config file (per-architecture) for backwards compat
_config_file_aliases = tuple() # type: typing.Tuple[str, ...]
dependencies = [] # type: typing.List[str]
Expand Down Expand Up @@ -1959,7 +1962,11 @@ def dependencies(cls, config: CheriConfig) -> "list[str]":

@classmethod
def project_build_dir_help(cls):
result = "$BUILD_ROOT/" + cls.default_directory_basename
result = "$BUILD_ROOT/"
if isinstance(cls.default_directory_basename, ComputedDefaultValue):
result += cls.default_directory_basename.as_string
else:
result += cls.default_directory_basename
if cls._xtarget is not BasicCompilationTargets.NATIVE or cls.add_build_dir_suffix_for_native:
result += "-$TARGET"
result += "-build"
Expand Down Expand Up @@ -2087,8 +2094,10 @@ def check_system_dependencies(self):
@classmethod
def setup_config_options(cls, install_directory_help="", **kwargs):
super().setup_config_options(**kwargs)
cls._initial_source_dir = cls.add_path_option("source-directory", metavar="DIR", default=cls.default_source_dir,
help="Override default source directory for " + cls.target)
if cls.source_dir is None:
cls._initial_source_dir = cls.add_path_option("source-directory", metavar="DIR",
default=cls.default_source_dir,
help="Override default source directory for " + cls.target)
# --<target>-<suffix>/build-directory is not inherited from the unsuffixed target (unless there is only one
# supported target).
default_xtarget = cls.default_architecture
Expand Down Expand Up @@ -2308,7 +2317,16 @@ def __init__(self, config: CheriConfig):
if hasattr(self, "_repository_url") and isinstance(self.repository, GitRepository):
# TODO: remove this and use a custom argparse.Action subclass
self.repository.url = self._repository_url
self.source_dir = self.repository.get_real_source_dir(self, self._initial_source_dir)

if isinstance(self.default_directory_basename, ComputedDefaultValue):
self.default_directory_basename = self.default_directory_basename(config, self)

if self.source_dir is None:
self.source_dir = self.repository.get_real_source_dir(self, self._initial_source_dir)
else:
if isinstance(self.source_dir, ComputedDefaultValue):
self.source_dir = self.source_dir(config, self)
self._initial_source_dir = self.source_dir

if self.build_in_source_dir:
self.verbose_print("Cannot build", self.target, "in a separate build dir, will build in", self.source_dir)
Expand Down

0 comments on commit 7e2ff92

Please sign in to comment.