diff --git a/lib/spack/spack/architecture.py b/lib/spack/spack/architecture.py
index 6ea7bafb6af9fe3162be99666ff46edf11889aed..a77832fcb184e6a09ec4544431d31c9e1a0a282a 100644
--- a/lib/spack/spack/architecture.py
+++ b/lib/spack/spack/architecture.py
@@ -513,3 +513,8 @@ def sys_type():
     """
     arch = Arch(platform(), 'default_os', 'default_target')
     return str(arch)
+
+
+@memoized
+def frontend_sys_type():
+    return str(Arch(platform(), 'frontend', 'frontend'))
diff --git a/lib/spack/spack/concretize.py b/lib/spack/spack/concretize.py
index 1bc933e543413468b9302134c1a9dfe75601a0c6..51d3c777fc3444a7fbb3fd514d5a6ab956a0a90e 100644
--- a/lib/spack/spack/concretize.py
+++ b/lib/spack/spack/concretize.py
@@ -251,8 +251,12 @@ def concretize_architecture(self, spec):
         DAG has an architecture, then use the root otherwise use the defaults
         on the platform.
         """
-        root_arch = spec.root.architecture
-        sys_arch = spack.spec.ArchSpec(spack.architecture.sys_type())
+        root_arch = spec.link_root().architecture
+        if spec.build_dep() and spec.disjoint_build_tree():
+            sys_arch = spack.spec.ArchSpec(
+                spack.architecture.frontend_sys_type())
+        else:
+            sys_arch = spack.spec.ArchSpec(spack.architecture.sys_type())
         spec_changed = False
 
         if spec.architecture is None:
@@ -321,14 +325,21 @@ def _proper_compiler_style(cspec, aspec):
                 spec.compiler in all_compilers):
             return False
 
-        # Find the another spec that has a compiler, or the root if none do
-        other_spec = spec if spec.compiler else find_spec(
-            spec, lambda x: x.compiler)
+        if spec.compiler:
+            other_spec = spec
+        elif spec.build_dep() and spec.disjoint_build_tree():
+            link_root = spec.link_root()
+            build_subtree = list(link_root.traverse(direction='children'))
+            candidates = list(x for x in build_subtree if x.compiler)
+            other_spec = candidates[0] if candidates else link_root
+        else:
+            # Find another spec that has a compiler, or the root if none do.
+            # Prefer compiler info from other specs which are not build deps.
+            other_spec = (
+                find_spec(spec, lambda x: x.compiler and not x.build_dep()) or
+                spec.root)
 
-        if not other_spec:
-            other_spec = spec.root
         other_compiler = other_spec.compiler
-        assert(other_spec)
 
         # Check if the compiler is already fully specified
         if other_compiler in all_compilers:
@@ -372,16 +383,20 @@ def concretize_compiler_flags(self, spec):
             # changes
             return True
 
+        def compiler_match(spec1, spec2):
+            return ((spec1.compiler, spec1.architecture) ==
+                    (spec2.compiler, spec2.architecture))
+
         ret = False
         for flag in spack.spec.FlagMap.valid_compiler_flags():
             try:
                 nearest = next(p for p in spec.traverse(direction='parents')
-                               if ((p.compiler == spec.compiler and
-                                    p is not spec) and
+                               if ((p is not spec) and
+                                   compiler_match(p, spec) and
                                    flag in p.compiler_flags))
-                if flag not in spec.compiler_flags or \
-                        not (sorted(spec.compiler_flags[flag]) >=
-                             sorted(nearest.compiler_flags[flag])):
+                if (flag not in spec.compiler_flags or
+                        (set(nearest.compiler_flags[flag]) -
+                            set(spec.compiler_flags[flag]))):
                     if flag in spec.compiler_flags:
                         spec.compiler_flags[flag] = list(
                             set(spec.compiler_flags[flag]) |
@@ -392,10 +407,11 @@ def concretize_compiler_flags(self, spec):
                     ret = True
 
             except StopIteration:
-                if (flag in spec.root.compiler_flags and
-                    ((flag not in spec.compiler_flags) or
-                     sorted(spec.compiler_flags[flag]) !=
-                     sorted(spec.root.compiler_flags[flag]))):
+                if (compiler_match(spec.root, spec) and
+                        flag in spec.root.compiler_flags and
+                        ((flag not in spec.compiler_flags) or
+                            (set(spec.root.compiler_flags[flag]) -
+                                set(spec.compiler_flags[flag])))):
                     if flag in spec.compiler_flags:
                         spec.compiler_flags[flag] = list(
                             set(spec.compiler_flags[flag]) |
@@ -419,10 +435,8 @@ def concretize_compiler_flags(self, spec):
                 if compiler.flags[flag] != []:
                     ret = True
             else:
-                if ((sorted(spec.compiler_flags[flag]) !=
-                     sorted(compiler.flags[flag])) and
-                    (not set(spec.compiler_flags[flag]) >=
-                     set(compiler.flags[flag]))):
+                if (set(compiler.flags[flag]) -
+                        set(spec.compiler_flags[flag])):
                     ret = True
                     spec.compiler_flags[flag] = list(
                         set(spec.compiler_flags[flag]) |
diff --git a/lib/spack/spack/operating_systems/cnl.py b/lib/spack/spack/operating_systems/cnl.py
index 78807865b3616df7d26a54d8d5501539a2458814..fa5394ce662ba577d56453ccedd99d7109426fe5 100644
--- a/lib/spack/spack/operating_systems/cnl.py
+++ b/lib/spack/spack/operating_systems/cnl.py
@@ -22,7 +22,7 @@ def __init__(self):
         super(Cnl, self).__init__(name, version)
 
     def __str__(self):
-        return self.name
+        return self.name + self.version
 
     def find_compilers(self, *paths):
         types = spack.compilers.all_compiler_types()
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index 2ef3757689dcedfcf8a053c04bb0caf7e94ab8a0..aba046607691c13ec25b53ebb346bf3031e04fe5 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -1090,7 +1090,7 @@ def return_val(res):
 
             successors = deps
             if direction == 'parents':
-                successors = self.dependents_dict()  # TODO: deptype?
+                successors = self.dependents_dict(deptype)
 
             visited.add(key)
             for name in sorted(successors):
@@ -1308,6 +1308,23 @@ def from_json(stream):
         except Exception as e:
             raise sjson.SpackJSONError("error parsing JSON spec:", str(e))
 
+    def build_dep(self):
+        # If this spec is the root, it will automatically be included in
+        # traverse
+        return not (self.root in
+                    self.traverse(
+                        deptype=('link', 'run'), direction='parents'))
+
+    def link_root(self):
+        parents = list(self.traverse(deptype=('link',), direction='parents',
+                       order='pre'))
+        return parents[-1]
+
+    def disjoint_build_tree(self):
+        link_root = self.link_root()
+        build_subtree = list(link_root.traverse(direction='children'))
+        return all(x.build_dep() for x in build_subtree)
+
     def _concretize_helper(self, presets=None, visited=None):
         """Recursive helper function for concretize().
            This concretizes everything bottom-up.  As things are
@@ -1326,8 +1343,8 @@ def _concretize_helper(self, presets=None, visited=None):
 
         # Concretize deps first -- this is a bottom-up process.
         for name in sorted(self._dependencies.keys()):
-            changed |= self._dependencies[
-                name].spec._concretize_helper(presets, visited)
+            dep = self._dependencies[name]
+            changed |= dep.spec._concretize_helper(presets, visited)
 
         if self.name in presets:
             changed |= self.constrain(presets[self.name])
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index 154e0eb68eb4838a0cb0f073742f372b4073a31f..4e2354a17a90df16d5d975c94f975bed9d276b95 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -85,6 +85,36 @@ def test_concretize_variant(self):
         self.check_concretize('mpich debug=2')
         self.check_concretize('mpich')
 
+    def test_concretize_with_build_dep(self):
+        # Set the target as the backend. Since the cmake build dependency is
+        # not explicitly configured to target the backend it should target
+        # the frontend (whatever compiler that is, it is different)
+        spec = self.check_concretize('cmake-client platform=test target=be')
+        client_compiler = spack.compilers.compiler_for_spec(
+            spec.compiler, spec.architecture)
+        cmake_spec = spec['cmake']
+        cmake_compiler = spack.compilers.compiler_for_spec(
+            cmake_spec.compiler, cmake_spec.architecture)
+        self.assertTrue(client_compiler.operating_system !=
+                        cmake_compiler.operating_system)
+
+    def test_concretize_link_dep_of_build_dep(self):
+        # The link dep of the build dep should use the same compiler as
+        # the build dep, and both should be different from the root
+        spec = self.check_concretize('dttop platform=test target=be')
+        dttop_compiler = spack.compilers.compiler_for_spec(
+            spec.compiler, spec.architecture)
+        dtlink2_spec = spec['dtlink2']
+        dtlink2_compiler = spack.compilers.compiler_for_spec(
+            dtlink2_spec.compiler, dtlink2_spec.architecture)
+        dtbuild1_spec = spec['dtbuild1']
+        dtbuild1_compiler = spack.compilers.compiler_for_spec(
+            dtbuild1_spec.compiler, dtbuild1_spec.architecture)
+        self.assertTrue(dttop_compiler.operating_system !=
+                        dtlink2_compiler.operating_system)
+        self.assertTrue(dtbuild1_compiler.operating_system ==
+                        dtlink2_compiler.operating_system)
+
     def test_conretize_compiler_flags(self):
         self.check_concretize('mpich cppflags="-O3"')