Determines final build properties, generates sources,
        and calls 'construct'. This method should not be
        overridden.

def generate (self, ps):
        """ Determines final build properties, generates sources,
        and calls 'construct'. This method should not be
        overridden.
        """
        assert isinstance(ps, property_set.PropertySet)
        self.manager_.errors().push_user_context(
            "Generating target " + self.full_name(), self.user_context_)

        if self.manager().targets().logging():
            self.manager().targets().log(
                "Building target '%s'" % self.name_)
            self.manager().targets().increase_indent ()
            self.manager().targets().log(
                "Build request: '%s'" % str (ps.raw ()))
            cf = self.manager().command_line_free_features()
            self.manager().targets().log(
                "Command line free features: '%s'" % str (cf.raw ()))
            self.manager().targets().log(
                "Target requirements: %s'" % str (self.requirements().raw ()))

        self.manager().targets().push_target(self)

        if ps not in self.generated_:

            # Apply free features form the command line.  If user
            # said
            #   define=FOO
            # he most likely want this define to be set for all compiles.
            ps = ps.refine(self.manager().command_line_free_features())
            rproperties = self.common_properties (ps, self.requirements_)

            self.manager().targets().log(
                "Common properties are '%s'" % str (rproperties))

            if rproperties.get("<build>") != ["no"]:

                result = GenerateResult ()

                properties = rproperties.non_dependency ()

                (p, u) = self.generate_dependency_properties (rproperties.dependency (), rproperties)
                properties += p
                assert all(isinstance(p, property.Property) for p in properties)
                usage_requirements = u

                (source_targets, u) = self.generate_dependency_targets (self.sources_, rproperties)
                usage_requirements += u

                self.manager_.targets().log(
                    "Usage requirements for '%s' are '%s'" % (self.name_, usage_requirements))

                # FIXME:

                rproperties = property_set.create(properties + usage_requirements)
                usage_requirements = property_set.create (usage_requirements)

                self.manager_.targets().log(
                    "Build properties: '%s'" % str(rproperties))

                source_targets += rproperties.get('<source>')

                # We might get duplicate sources, for example if
                # we link to two library which have the same <library> in
                # usage requirements.
                # Use stable sort, since for some targets the order is
                # important. E.g. RUN_PY target need python source to come
                # first.
                source_targets = unique(source_targets, stable=True)

                # FIXME: figure why this call messes up source_targets in-place
                result = self.construct (self.name_, source_targets[:], rproperties)

                if result:
                    assert len(result) == 2
                    gur = result [0]
                    result = result [1]

                    if self.always_:
                        for t in result:
                            t.always()

                    s = self.create_subvariant (
                        result,
                        self.manager().virtual_targets().recent_targets(), ps,
                        source_targets, rproperties, usage_requirements)
                    self.manager().virtual_targets().clear_recent_targets()

                    ur = self.compute_usage_requirements (s)
                    ur = ur.add (gur)
                    s.set_usage_requirements (ur)

                    self.manager_.targets().log (
                        "Usage requirements from '%s' are '%s'" %
                        (self.name(), str(rproperties)))

                    self.generated_[ps] = GenerateResult (ur, result)
                else:
                    self.generated_[ps] = GenerateResult (property_set.empty(), [])
            else:
                # If we just see <build>no, we cannot produce any reasonable
                # diagnostics. The code that adds this property is expected
                # to explain why a target is not built, for example using
                # the configure.log-component-configuration function.

                # If this target fails to build, add <build>no to properties
                # to cause any parent target to fail to build.  Except that it
                # - does not work now, since we check for <build>no only in
                #   common properties, but not in properties that came from
                #   dependencies
                # - it's not clear if that's a good idea anyway.  The alias
                #   target, for example, should not fail to build if a dependency
                #   fails.
                self.generated_[ps] = GenerateResult(
                    property_set.create(["<build>no"]), [])
        else:
            self.manager().targets().log ("Already built")

        self.manager().targets().pop_target()
        self.manager().targets().decrease_indent()

        return self.generated_[ps]