From 39772e4c4c2a6cfba55f2e11bcf5b8bf8221782e Mon Sep 17 00:00:00 2001
From: Denis Davydov <davydden@gmail.com>
Date: Tue, 25 Oct 2016 20:25:13 +0200
Subject: [PATCH] filter system paths (#2083)

* add filter_system_paths()

* filter system paths in set_build_environment_variables()

* two function: lib/inc + bin

* reverse order in bin

* fix order

* minor

* improvements of the code

* more cleanup

* alternative solution for filter_bins

* fiddle base alalazo's approach

* minor

* minor
---
 lib/spack/spack/build_environment.py | 11 ++++++---
 lib/spack/spack/test/environment.py  | 36 ++++++++++++++++++++++++++++
 lib/spack/spack/util/environment.py  | 18 ++++++++++++++
 3 files changed, 62 insertions(+), 3 deletions(-)

diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py
index 7579f9adc6..abbc385a39 100644
--- a/lib/spack/spack/build_environment.py
+++ b/lib/spack/spack/build_environment.py
@@ -251,6 +251,8 @@ def set_build_environment_variables(pkg, env, dirty=False):
         if os.path.isdir(ci):
             env_paths.append(ci)
 
+    env_paths = filter_system_paths(env_paths)
+
     for item in reversed(env_paths):
         env.prepend_path('PATH', item)
     env.set_path(SPACK_ENV_PATH, env_paths)
@@ -258,12 +260,14 @@ def set_build_environment_variables(pkg, env, dirty=False):
     # Prefixes of all of the package's dependencies go in SPACK_DEPENDENCIES
     dep_prefixes = [d.prefix for d in
                     pkg.spec.traverse(root=False, deptype=('build', 'link'))]
+    dep_prefixes = filter_system_paths(dep_prefixes)
     env.set_path(SPACK_DEPENDENCIES, dep_prefixes)
 
     # These variables control compiler wrapper behavior
-    env.set_path(SPACK_RPATH_DEPS, [d.prefix for d in get_rpath_deps(pkg)])
-    env.set_path(SPACK_LINK_DEPS, [
-        d.prefix for d in pkg.spec.traverse(root=False, deptype=('link'))])
+    env.set_path(SPACK_RPATH_DEPS, filter_system_paths([
+        d.prefix for d in get_rpath_deps(pkg)]))
+    env.set_path(SPACK_LINK_DEPS, filter_system_paths([
+        d.prefix for d in pkg.spec.traverse(root=False, deptype=('link'))]))
 
     # Add dependencies to CMAKE_PREFIX_PATH
     env.set_path('CMAKE_PREFIX_PATH', dep_prefixes)
@@ -298,6 +302,7 @@ def set_build_environment_variables(pkg, env, dirty=False):
     # Add bin directories from dependencies to the PATH for the build.
     bin_dirs = reversed(filter(os.path.isdir, [
         '%s/bin' % d.prefix for d in pkg.spec.dependencies(deptype='build')]))
+    bin_dirs = filter_system_bin_paths(bin_dirs)
     for item in bin_dirs:
         env.prepend_path('PATH', item)
 
diff --git a/lib/spack/spack/test/environment.py b/lib/spack/spack/test/environment.py
index c404433a56..2b499869c5 100644
--- a/lib/spack/spack/test/environment.py
+++ b/lib/spack/spack/test/environment.py
@@ -30,6 +30,7 @@
 from spack.environment import EnvironmentModifications
 from spack.environment import SetEnv, UnsetEnv
 from spack.environment import RemovePath, PrependPath, AppendPath
+from spack.util.environment import filter_system_paths, filter_system_bin_paths
 
 
 class EnvironmentTest(unittest.TestCase):
@@ -59,6 +60,41 @@ def test_unset(self):
         env.apply_modifications()
         self.assertRaises(KeyError, os.environ.__getitem__, 'UNSET_ME')
 
+    def test_filter_system_paths(self):
+        filtered = filter_system_paths([
+            '/usr/local/Cellar/gcc/5.3.0/lib',
+            '/usr/local/lib',
+            '/usr/local/include',
+            '/usr/local/lib64',
+            '/usr/local/opt/some-package/lib',
+            '/usr/opt/lib',
+            '/lib',
+            '/lib64',
+            '/include',
+            '/opt/some-package/include',
+        ])
+        self.assertEqual(filtered,
+                         ['/usr/local/Cellar/gcc/5.3.0/lib',
+                          '/usr/local/opt/some-package/lib',
+                          '/usr/opt/lib',
+                          '/opt/some-package/include'])
+
+        filtered = filter_system_bin_paths([
+            '/usr/local/Cellar/gcc/5.3.0/bin',
+            '/usr/local/bin',
+            '/usr/local/opt/some-package/bin',
+            '/usr/opt/bin',
+            '/bin',
+            '/opt/some-package/bin',
+        ])
+        self.assertEqual(filtered,
+                         ['/usr/local/bin',
+                          '/bin',
+                          '/usr/local/Cellar/gcc/5.3.0/bin',
+                          '/usr/local/opt/some-package/bin',
+                          '/usr/opt/bin',
+                          '/opt/some-package/bin'])
+
     def test_set_path(self):
         env = EnvironmentModifications()
         env.set_path('A', ['foo', 'bar', 'baz'])
diff --git a/lib/spack/spack/util/environment.py b/lib/spack/spack/util/environment.py
index f23110d2d9..15eb52d8e2 100644
--- a/lib/spack/spack/util/environment.py
+++ b/lib/spack/spack/util/environment.py
@@ -24,6 +24,24 @@
 ##############################################################################
 import os
 
+system_paths = ['/', '/usr/', '/usr/local']
+suffixes = ['lib', 'lib64', 'include']
+system_dirs = [os.path.join(p, s) for s in suffixes for p in system_paths]
+system_bins = [os.path.join(p, 'bin') for p in system_paths]
+
+
+def filter_system_paths(paths):
+    return [p for p in paths if p not in system_dirs]
+
+
+def filter_system_bin_paths(paths):
+    # Turn the iterable into a list. Assume it's a list from here on.
+    _paths = list(paths)
+    bins = [p for p in _paths if p in system_bins]
+    nobins = [p for p in _paths if p not in system_bins]
+    # put bins infront as PATH is set by: prepend_path('PATH', item)
+    return bins + nobins
+
 
 def get_path(name):
     path = os.environ.get(name, "").strip()
-- 
GitLab