Eclipse generator now uses compiler's default include dirs.

This adds support to the Eclipse gyp generator for detecting the
compiler's default include directories and adding them to the list of
include dirs. This finally fixes a long-standing bug where size_t was
not defined in the Android Eclipse setup.

BUG=336982
Review URL: https://codereview.chromium.org/145363002/

Patch from Newton Allen <newt@chromium.org>!


git-svn-id: http://gyp.googlecode.com/svn/trunk@1844 78cadc50-ecff-11dd-a971-7dbc132099af
diff --git a/pylib/gyp/generator/eclipse.py b/pylib/gyp/generator/eclipse.py
index 84380b0..8d08f57 100644
--- a/pylib/gyp/generator/eclipse.py
+++ b/pylib/gyp/generator/eclipse.py
@@ -77,7 +77,8 @@
 
 
 def GetAllIncludeDirectories(target_list, target_dicts,
-                             shared_intermediate_dirs, config_name, params):
+                             shared_intermediate_dirs, config_name, params,
+                             compiler_path):
   """Calculate the set of include directories to be used.
 
   Returns:
@@ -88,6 +89,33 @@
   gyp_includes_set = set()
   compiler_includes_list = []
 
+  # Find compiler's default include dirs.
+  if compiler_path:
+    command = shlex.split(compiler_path)
+    command.extend(['-E', '-xc++', '-v', '-'])
+    proc = subprocess.Popen(args=command, stdin=subprocess.PIPE,
+                            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    output = proc.communicate()[1]
+    # Extract the list of include dirs from the output, which has this format:
+    #   ...
+    #   #include "..." search starts here:
+    #   #include <...> search starts here:
+    #    /usr/include/c++/4.6
+    #    /usr/local/include
+    #   End of search list.
+    #   ...
+    in_include_list = False
+    for line in output.splitlines():
+      if line.startswith('#include'):
+        in_include_list = True
+        continue
+      if line.startswith('End of search list.'):
+        break
+      if in_include_list:
+        include_dir = line.strip()
+        if include_dir not in compiler_includes_list:
+          compiler_includes_list.append(include_dir)
+
   flavor = gyp.common.GetFlavor(params)
   if flavor == 'win':
     generator_flags = params.get('generator_flags', {})
@@ -106,11 +134,10 @@
       else:
         cflags = config['cflags']
       for cflag in cflags:
-        include_dir = ''
         if cflag.startswith('-I'):
           include_dir = cflag[2:]
-        if include_dir and not include_dir in compiler_includes_list:
-          compiler_includes_list.append(include_dir)
+          if include_dir not in compiler_includes_list:
+            compiler_includes_list.append(include_dir)
 
       # Find standard gyp include dirs.
       if config.has_key('include_dirs'):
@@ -125,9 +152,7 @@
               include_dir = base_dir + '/' + include_dir
               include_dir = os.path.abspath(include_dir)
 
-            if not include_dir in gyp_includes_set:
-              gyp_includes_set.add(include_dir)
-
+            gyp_includes_set.add(include_dir)
 
   # Generate a list that has all the include dirs.
   all_includes_list = list(gyp_includes_set)
@@ -140,7 +165,7 @@
   return all_includes_list
 
 
-def GetCompilerPath(target_list, target_dicts, data):
+def GetCompilerPath(target_list, data):
   """Determine a command that can be used to invoke the compiler.
 
   Returns:
@@ -165,7 +190,8 @@
   return 'gcc'
 
 
-def GetAllDefines(target_list, target_dicts, data, config_name, params):
+def GetAllDefines(target_list, target_dicts, data, config_name, params,
+                  compiler_path):
   """Calculate the defines for a project.
 
   Returns:
@@ -202,9 +228,8 @@
   # Get default compiler defines (if possible).
   if flavor == 'win':
     return all_defines  # Default defines already processed in the loop above.
-  cc_target = GetCompilerPath(target_list, target_dicts, data)
-  if cc_target:
-    command = shlex.split(cc_target)
+  if compiler_path:
+    command = shlex.split(compiler_path)
     command.extend(['-E', '-dM', '-'])
     cpp_proc = subprocess.Popen(args=command, cwd='.',
                                 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
@@ -279,11 +304,13 @@
 
   eclipse_langs = ['C++ Source File', 'C Source File', 'Assembly Source File',
                    'GNU C++', 'GNU C', 'Assembly']
+  compiler_path = GetCompilerPath(target_list, data)
   include_dirs = GetAllIncludeDirectories(target_list, target_dicts,
                                           shared_intermediate_dirs, config_name,
-                                          params)
+                                          params, compiler_path)
   WriteIncludePaths(out, eclipse_langs, include_dirs)
-  defines = GetAllDefines(target_list, target_dicts, data, config_name, params)
+  defines = GetAllDefines(target_list, target_dicts, data, config_name, params,
+                          compiler_path)
   WriteMacros(out, eclipse_langs, defines)
 
   out.write('</cdtprojectproperties>\n')