From 613292e3ce1d5f28564fbc872eda82ad997e0568 Mon Sep 17 00:00:00 2001
From: Jack Nagel <jacknagel@gmail.com>
Date: Mon, 19 May 2014 14:18:23 -0500
Subject: [PATCH] Reorganize superenv include and library path setup

I found the dual use of CMAKE_*_PATH variables to make it difficult to
reason about this code. Now a separate set of variables are used to
communicate with the cc wrapper, and less work is performed in the
wrapper itself.

We no longer pass the SDK include path as a -isystem directory on
Xcode-only setups. Doing so is redundant with `--sysroot` and has other
side effects, namely changing the include path search order, which can
break compilation of some software (e.g. qemu).

On Xcode-only 10.9, we can additionally omit `--sysroot`, as the correct
paths are built into the tools.

A new variable, HOMEBREW_SYSROOT, is used to this information to the
wrapper. It will be unset on Xcode-only 10.9. HOMEBREW_SDKROOT will
continue to be set, as it is used for other things besides setting the
include search path.
---
 Library/ENV/4.3/cc                   | 68 ++++++++++------------------
 Library/Homebrew/extend/ENV/super.rb | 68 +++++++++++++++++++---------
 2 files changed, 71 insertions(+), 65 deletions(-)

diff --git a/Library/ENV/4.3/cc b/Library/ENV/4.3/cc
index 1c8db12382..aaf8360a40 100755
--- a/Library/ENV/4.3/cc
+++ b/Library/ENV/4.3/cc
@@ -26,14 +26,14 @@ end
 LOGGER = Logger.new
 
 class Cmd
-  attr_reader :brewfix, :brewtmp, :sdkroot
+  attr_reader :brewfix, :brewtmp, :sysroot
 
   def initialize path, args
     @arg0 = File.basename(path).freeze
     @args = args.freeze
     @brewfix = ENV['HOMEBREW_PREFIX']
     @brewtmp = ENV['HOMEBREW_TEMP']
-    @sdkroot = ENV['HOMEBREW_SDKROOT']
+    @sysroot = ENV['HOMEBREW_SYSROOT']
   end
 
   def mode
@@ -89,11 +89,11 @@ class Cmd
       args = refurbished_args
     end
 
-    if sdkroot
+    if sysroot
       if tool == "ld"
-        args << "-syslibroot" << sdkroot
+        args << "-syslibroot" << sysroot
       else
-        args << "--sysroot=#{sdkroot}"
+        args << "--sysroot=#{sysroot}"
       end
     end
 
@@ -118,8 +118,8 @@ class Cmd
   end
 
   def refurbished_args
-    @lset = Set.new(libpath + syslibpath)
-    @iset = Set.new(cpath.flatten)
+    @lset = Set.new(library_paths + system_library_paths)
+    @iset = Set.new(isystem_paths + include_paths)
 
     args = []
     enum = @args.each
@@ -241,40 +241,12 @@ class Cmd
     ENV["HOMEBREW_ARCHFLAGS"].split(" ")
   end
 
-  def syspath
-    if sdkroot
-      %W{#{sdkroot}/usr /usr/local}
-    else
-      %W{/usr /usr/local}
-    end
-  end
-
-  def syslibpath
-    # We reject brew's lib as we explicitly add this as a -L flag, thus it
-    # is given higher priority by cc, so it surpasses the system libpath.
-    # NOTE this only counts if Homebrew is installed at /usr/local
-    syspath.reject { |d| d == brewfix }.map! { |d| File.join(d, "lib") }
-  end
-
-  # Paths added as "-isystem<path>" and "-I<path>" flags
-  def cpath
-    cpath  = path_split("CMAKE_PREFIX_PATH").map! { |d| File.join(d, "include") }
-    cpath += path_split("CMAKE_INCLUDE_PATH")
-    opt = cpath.grep(%r{^#{Regexp.escape(brewfix)}/opt}o)
-    sys = cpath - opt
-    [sys, opt]
-  end
-
-  # Paths added as "-L<path>" flags
-  def libpath
-    libpath  = path_split("CMAKE_PREFIX_PATH").map! { |d| File.join(d, "lib") }
-    libpath += path_split("CMAKE_LIBRARY_PATH")
-    libpath -= syslibpath
-    libpath
+  def cppflags
+    path_flags("-isystem", isystem_paths) + path_flags("-I", include_paths)
   end
 
   def ldflags
-    args = path_flags("-L", libpath)
+    args = path_flags("-L", library_paths)
     case mode
     when :ld
       args << "-headerpad_max_install_names"
@@ -284,12 +256,20 @@ class Cmd
     args
   end
 
-  # Keg-only opt paths get the "-I" treatment since it has higher priority than
-  # "-isystem", and we want them to be searched before system directories as
-  # well as any directories added by the build system.
-  def cppflags
-    sys, opt = cpath
-    path_flags("-isystem", sys) + path_flags("-I", opt)
+  def isystem_paths
+    path_split("HOMEBREW_ISYSTEM_PATHS")
+  end
+
+  def include_paths
+    path_split("HOMEBREW_INCLUDE_PATHS")
+  end
+
+  def library_paths
+    path_split("HOMEBREW_LIBRARY_PATHS")
+  end
+
+  def system_library_paths
+    %W{#{sysroot}/usr/lib /usr/local/lib}
   end
 
   def make_fuss args
diff --git a/Library/Homebrew/extend/ENV/super.rb b/Library/Homebrew/extend/ENV/super.rb
index cb05ec9647..0c6d105473 100644
--- a/Library/Homebrew/extend/ENV/super.rb
+++ b/Library/Homebrew/extend/ENV/super.rb
@@ -66,6 +66,15 @@ module Superenv
     self['CMAKE_LIBRARY_PATH'] = determine_cmake_library_path
     self['ACLOCAL_PATH'] = determine_aclocal_path
     self['M4'] = MacOS.locate("m4") if deps.include? "autoconf"
+    self["HOMEBREW_ISYSTEM_PATHS"] = determine_isystem_paths
+    self["HOMEBREW_INCLUDE_PATHS"] = determine_include_paths
+    self["HOMEBREW_LIBRARY_PATHS"] = determine_library_paths
+
+    # On 10.9 the developer tools honor the correct sysroot by default.
+    # On 10.7 and 10.8 we need to set it ourselves.
+    if MacOS::Xcode.without_clt? && MacOS.version <= "10.8"
+      self["HOMEBREW_SYSROOT"] = effective_sysroot
+    end
 
     # On 10.9, the tools in /usr/bin proxy to the active developer directory.
     # This means we can use them for any combination of CLT and Xcode.
@@ -100,6 +109,10 @@ module Superenv
     self["HOMEBREW_CXX"] = super
   end
 
+  def effective_sysroot
+    if MacOS::Xcode.without_clt? then MacOS.sdk_path.to_s else "" end
+  end
+
   def determine_cc
     cc = compiler
     COMPILER_SYMBOL_MAP.invert.fetch(cc, cc)
@@ -159,40 +172,53 @@ module Superenv
     paths.to_path_s
   end
 
-  def determine_cmake_prefix_path
-    paths = keg_only_deps.map{|dep| "#{HOMEBREW_PREFIX}/opt/#{dep}" }
-    paths << HOMEBREW_PREFIX.to_s # put ourselves ahead of everything else
-    paths << "#{MacOS.sdk_path}/usr" if MacOS::Xcode.without_clt?
+  def determine_isystem_paths
+    paths = []
+    paths << "#{HOMEBREW_PREFIX}/include"
+    paths << "#{effective_sysroot}/usr/include/libxml2" unless deps.include? "libxml2"
+    paths << "#{effective_sysroot}/usr/include/apache2" if MacOS::Xcode.without_clt?
+    paths << "#{effective_sysroot}/System/Library/Frameworks/OpenGL.framework/Versions/Current/Headers"
+    paths << MacOS::X11.include.to_s << "#{MacOS::X11.include}/freetype2" if x11?
     paths.to_path_s
   end
 
-  def determine_cmake_frameworks_path
-    paths = deps.map{|dep| "#{HOMEBREW_PREFIX}/opt/#{dep}/Frameworks" }
-    paths << "#{MacOS.sdk_path}/System/Library/Frameworks" if MacOS::Xcode.without_clt?
+  def determine_include_paths
+    keg_only_deps.map { |dep| "#{HOMEBREW_PREFIX}/opt/#{dep}/include" }.to_path_s
+  end
+
+  def determine_library_paths
+    paths = keg_only_deps.map { |dep| "#{HOMEBREW_PREFIX}/opt/#{dep}/lib" }
+    paths << "#{HOMEBREW_PREFIX}/lib"
+    paths << "#{effective_sysroot}/System/Library/Frameworks/OpenGL.framework/Versions/Current/Libraries"
+    paths << MacOS::X11.lib.to_s if x11?
+    paths.to_path_s
+  end
+
+  def determine_cmake_prefix_path
+    paths = keg_only_deps.map { |dep| "#{HOMEBREW_PREFIX}/opt/#{dep}" }
+    paths << HOMEBREW_PREFIX.to_s
     paths.to_path_s
   end
 
   def determine_cmake_include_path
-    sdk = MacOS.sdk_path if MacOS::Xcode.without_clt?
     paths = []
-    paths << "#{sdk}/usr/include/libxml2" unless deps.include? 'libxml2'
-    paths << "#{sdk}/usr/include/apache2" if MacOS::Xcode.without_clt?
-    if x11?
-      paths << MacOS::X11.include << "#{MacOS::X11.include}/freetype2"
-    else
-      paths << "#{sdk}/System/Library/Frameworks/OpenGL.framework/Versions/Current/Headers"
-    end
+    paths << "#{effective_sysroot}/usr/include/libxml2" unless deps.include? "libxml2"
+    paths << "#{effective_sysroot}/usr/include/apache2" if MacOS::Xcode.without_clt?
+    paths << "#{effective_sysroot}/System/Library/Frameworks/OpenGL.framework/Versions/Current/Headers"
+    paths << MacOS::X11.include.to_s << "#{MacOS::X11.include}/freetype2" if x11?
     paths.to_path_s
   end
 
   def determine_cmake_library_path
-    sdk = MacOS.sdk_path if MacOS::Xcode.without_clt?
     paths = []
-    if x11?
-      paths << MacOS::X11.lib
-    else
-      paths << "#{sdk}/System/Library/Frameworks/OpenGL.framework/Versions/Current/Libraries"
-    end
+    paths << "#{effective_sysroot}/System/Library/Frameworks/OpenGL.framework/Versions/Current/Libraries"
+    paths << MacOS::X11.lib.to_s if x11?
+    paths.to_path_s
+  end
+
+  def determine_cmake_frameworks_path
+    paths = deps.map { |dep| "#{HOMEBREW_PREFIX}/opt/#{dep}/Frameworks" }
+    paths << "#{effective_sysroot}/System/Library/Frameworks" if MacOS::Xcode.without_clt?
     paths.to_path_s
   end
 
-- 
GitLab