Ejemplo n.º 1
0
def get_compilation_subgraph(toolset, target, ft_to, outfile):
    """
    Given list of source files (as :class:`bkl.expr.ListExpr`), produces build
    subgraph (:class:`bkl.api.BuildSubgraph`) with appropriate
    :class:`bkl.api.BuildNode` nodes.

    :param toolset: The toolset used (as :class:`bkl.api.Toolset`).
    :param target:  The target object for which the invocation is done.
    :param ft_to:   Type of the output file to compile to.
    :param outfile: Name of the output file (as :class:`bkl.expr.PathExpr`).
    """

    # FIXME: support direct many-files-into-one (e.g. java->jar, .cs->exe)
    # compilation too

    objects = []
    allnodes = []
    files_map = disambiguate_intermediate_file_names(target.sources)

    for srcfile in target.sources:
        with error_context(srcfile):
            if not srcfile.should_build():  # TODO: allow runtime decision
                continue
            if srcfile["compile-commands"]:
                allnodes += _make_build_nodes_for_generated_file(srcfile)
            else:
                # FIXME: toolset.object_type shouldn't be needed
                obj, all = _make_build_nodes_for_file(toolset, target, srcfile,
                                                      toolset.object_type,
                                                      files_map)
                objects += obj
                allnodes += all
    for srcfile in target.headers:
        with error_context(srcfile):
            if not srcfile.should_build():  # TODO: allow runtime decision
                continue
            if srcfile["compile-commands"]:
                allnodes += _make_build_nodes_for_generated_file(srcfile)

    linker = get_compiler(toolset, toolset.object_type, ft_to)
    assert linker

    object_files = [o.outputs[0] for o in objects]
    link_commands = linker.commands(toolset, target,
                                    expr.ListExpr(object_files), outfile)
    link_node = BuildNode(commands=link_commands,
                          inputs=object_files,
                          outputs=[outfile],
                          source_pos=target.source_pos)

    return BuildSubgraph(link_node, allnodes)
Ejemplo n.º 2
0
def get_compilation_subgraph(toolset, target, ft_to, outfile):
    """
    Given list of source files (as :class:`bkl.expr.ListExpr`), produces build
    subgraph (:class:`bkl.api.BuildSubgraph`) with appropriate
    :class:`bkl.api.BuildNode` nodes.

    :param toolset: The toolset used (as :class:`bkl.api.Toolset`).
    :param target:  The target object for which the invocation is done.
    :param ft_to:   Type of the output file to compile to.
    :param outfile: Name of the output file (as :class:`bkl.expr.PathExpr`).
    """

    # FIXME: support direct many-files-into-one (e.g. java->jar, .cs->exe)
    # compilation too

    objects = []
    allnodes = []
    files_map = disambiguate_intermediate_file_names(target.sources)

    for srcfile in target.sources:
        with error_context(srcfile):
            if not srcfile.should_build(): # TODO: allow runtime decision
                continue
            if srcfile["compile-commands"]:
                allnodes += _make_build_nodes_for_generated_file(srcfile)
            else:
                # FIXME: toolset.object_type shouldn't be needed
                obj, all = _make_build_nodes_for_file(toolset, target, srcfile, toolset.object_type, files_map)
                objects += obj
                allnodes += all
    for srcfile in target.headers:
        with error_context(srcfile):
            if not srcfile.should_build(): # TODO: allow runtime decision
                continue
            if srcfile["compile-commands"]:
                allnodes += _make_build_nodes_for_generated_file(srcfile)

    linker = get_compiler(toolset, toolset.object_type, ft_to)
    assert linker

    object_files = [o.outputs[0] for o in objects]
    link_commands = linker.commands(toolset, target, expr.ListExpr(object_files), outfile)
    link_node = BuildNode(commands=link_commands,
                          inputs=object_files,
                          outputs=[outfile],
                          source_pos=target.source_pos)

    return BuildSubgraph(link_node, allnodes)
Ejemplo n.º 3
0
    def validate(self, e):
        """
        Validates if the expression *e* is of this type. If it isn't, throws
        :exc:`bkl.error.TypeError` with description of the error.

        Note that this method transparently handles references and conditional
        expressions.
        """
        with error_context(e):
            if isinstance(e, expr.NullExpr):
                # Null expression is rarely a valid value, but it can happen all
                # over the place due to conditional processing
                pass
            elif isinstance(e, expr.ReferenceExpr):
                try:
                    # FIXME: Compare referenced var's type with self, do this only if
                    #        it is AnyType. Need to handle type promotion then as well.
                    self.validate(e.get_value())
                except TypeError as err:
                    # If the error happened in a referenced variable, then
                    # it's location is not interesting -- we want to report
                    # the error at the place where validation was requested.
                    # FIXME: push the old location on a stack instead?
                    err.pos = None
                    raise
            elif isinstance(e, expr.IfExpr):
                self.validate(e.value_yes)
                self.validate(e.value_no)
            elif isinstance(e, expr.PlaceholderExpr):
                # FIXME: once settings are implemented, check their types
                pass
                # raise TypeError(self, e, "value not determinable")
            else:
                # finally, perform actual type-specific validation:
                self._validate_impl(e)
Ejemplo n.º 4
0
 def get_value(self):
     """
     Returns value of the referenced variable. Throws an exception if
     the reference couldn't be resolved.
     """
     with error_context(self):
         return self.context.get_variable_value(self.var)
Ejemplo n.º 5
0
def get_model_name_from_path(e):
    """
    Give an expression representing filename, return name suitable for
    model.SourceFile.name.
    """
    with error_context(e):
        return _ModelNameFromPathVisitor().visit(e)
Ejemplo n.º 6
0
    def validate(self, e):
        """
        Validates if the expression *e* is of this type. If it isn't, throws
        :exc:`bkl.error.TypeError` with description of the error.

        Note that this method transparently handles references and conditional
        expressions.
        """
        with error_context(e):
            if isinstance(e, expr.NullExpr):
                # Null expression is rarely a valid value, but it can happen all
                # over the place due to conditional processing
                pass
            elif isinstance(e, expr.ReferenceExpr):
                try:
                    # FIXME: Compare referenced var's type with self, do this only if
                    #        it is AnyType. Need to handle type promotion then as well.
                    self.validate(e.get_value())
                except TypeError as err:
                    # If the error happened in a referenced variable, then
                    # it's location is not interesting -- we want to report
                    # the error at the place where validation was requested.
                    # FIXME: push the old location on a stack instead?
                    err.pos = None
                    raise
            elif isinstance(e, expr.IfExpr):
                self.validate(e.value_yes)
                self.validate(e.value_no)
            elif isinstance(e, expr.PlaceholderExpr):
                # FIXME: once settings are implemented, check their types
                pass
                # raise TypeError(self, e, "value not determinable")
            else:
                # finally, perform actual type-specific validation:
                self._validate_impl(e)
Ejemplo n.º 7
0
 def get_value(self):
     """
     Returns value of the conditional expression, i.e. either
     :attr:`value_yes` or :attr:`value_no`, depending on what the condition
     evaluates to. Throws if the condition cannot be evaluated.
     """
     with error_context(self):
         return self.value_yes if self.cond.as_py() else self.value_no
Ejemplo n.º 8
0
def split(e, sep):
    """
    Splits expression *e* into a list of expressions, using *sep* as the
    delimiter character. Works with conditional expressions and variable
    references too.
    """
    assert len(sep) == 1
    with error_context(e):
        return _SplitVisitor(sep).visit(e)
Ejemplo n.º 9
0
    def get_variable(self):
        """
        Return the variable object this reference points to.

        Use this method only if necessary; whenever possible,
        :meth:`get_value()` should be used instead.

        Note that the returned value may be None, either if the referenced
        variable doesn't exist or when the reference is to a property that
        wasn't explicitly set and uses the default value.
        """
        with error_context(self):
            return self.context.resolve_variable(self.var)
Ejemplo n.º 10
0
def split_into_path(e):
    """
    Splits expression *e* into a list of expressions, using '/' as the
    delimiter character. Returns a PathExpr.  Works with conditional
    expressions and variable references too.
    """
    with error_context(e):
        visitor = _SplitIntoPathVisitor()
        components = visitor.visit(e)
        # filter out empty components (e.g. "foo//bar.c")
        components = [x for x in components
                      if not isinstance(x, LiteralExpr) or x.value]
        return PathExpr(components,
                        anchor=visitor.anchor, anchor_file=visitor.anchor_file,
                        pos=e.pos)