'A spec is concrete if it describes one build of a package uniquely.
This will ensure that this spec is concrete.
If this spec could describe more than one version, variant, or build
of a package, this will add constraints to make it concrete.
Some rigorous validation and checks are also performed on the spec.
Concretizing ensures that it is self-consistent and that it\'s
consistent with requirements of its pacakges.  See flatten() and
normalize() for more details on this.'

def concretize(self):

    if (not self.name):
        raise SpecError('Attempting    to    concretize    anonymous    spec')
    if self._concrete:
        return
    changed = True
    force = False
    while changed:
        changes = (self.normalize(force), self._expand_virtual_packages(), self._concretize_helper())
        changed = any(changes)
        force = True
    for s in self.traverse(deptype_query=alldeps):
        if (s.namespace is None):
            s.namespace = spack.repo.repo_for_pkg(s.name).namespace
    for s in self.traverse():
        if s.external_module:
            compiler = spack.compilers.compiler_for_spec(s.compiler, s.architecture)
            for mod in compiler.modules:
                load_module(mod)
            s.external_path = get_path_from_module(s.external_module)
    self._mark_concrete()
    matches = []
    for x in self.traverse():
        for (conflict_spec, when_list) in x.package.conflicts.items():
            if x.satisfies(conflict_spec):
                for when_spec in when_list:
                    if x.satisfies(when_spec):
                        matches.append((x, conflict_spec, when_spec))
    if matches:
        raise ConflictsInSpecError(self, matches)
