def doProcess(self, recipe):
        compFilters = []
        self.macros = recipe.macros
        self.rootdir = self.rootdir % recipe.macros

        self.loadFilterDirs()

        # The extras need to come before base in order to override decisions
        # in the base subfilters; invariants come first for those very few
        # specs that absolutely should not be overridden in recipes.
        for filteritem in itertools.chain(self.invariantFilters,
                                          self.extraFilters,
                                          self.derivedFilters,
                                          self.configFilters,
                                          self.baseFilters):
            if not isinstance(filteritem, (filter.Filter, filter.PathSet)):
                name = filteritem[0] % self.macros
                assert(name != 'source')
                args, kwargs = self.filterExpArgs(filteritem[1:], name=name)
                filteritem = filter.Filter(*args, **kwargs)

            compFilters.append(filteritem)

        # by default, everything that hasn't matched a filter pattern yet
        # goes in the catchall component ('runtime' by default)
        compFilters.append(filter.Filter('.*', self.macros, name=self.catchall))

        # pass these down to PackageSpec for building the package
        recipe.PackageSpec(compFilters=compFilters)