1b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org# Copyright (c) 2012 Google Inc. All rights reserved. 2b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org# Use of this source code is governed by a BSD-style license that can be 3b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org# found in the LICENSE file. 4b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 5b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org"""GYP backend that generates Eclipse CDT settings files. 6b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 7b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgThis backend DOES NOT generate Eclipse CDT projects. Instead, it generates XML 8b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgfiles that can be imported into an Eclipse CDT project. The XML file contains a 9b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orglist of include paths and symbols (i.e. defines). 10b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 11b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgBecause a full .cproject definition is not created by this generator, it's not 12b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgpossible to properly define the include dirs and symbols for each file 13b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgindividually. Instead, one set of includes/symbols is generated for the entire 14b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgproject. This works fairly well (and is a vast improvement in general), but may 15b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgstill result in a few indexer issues here and there. 16b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 17b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgThis generator has no automated tests, so expect it to be broken. 18b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org""" 19b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 204051c257283eb3ca07dfdedefa34d7e2cd8c1975thakis@chromium.orgfrom xml.sax.saxutils import escape 21b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgimport os.path 22b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgimport subprocess 23b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgimport gyp 24b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgimport gyp.common 259820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.orgimport gyp.msvs_emulation 26b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgimport shlex 27b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 28b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orggenerator_wants_static_library_dependencies_adjusted = False 29b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 30b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orggenerator_default_variables = { 31b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org} 32b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 33b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgfor dirname in ['INTERMEDIATE_DIR', 'PRODUCT_DIR', 'LIB_DIR', 'SHARED_LIB_DIR']: 34b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org # Some gyp steps fail if these are empty(!). 35b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org generator_default_variables[dirname] = 'dir' 36b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 37b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgfor unused in ['RULE_INPUT_PATH', 'RULE_INPUT_ROOT', 'RULE_INPUT_NAME', 38b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 'RULE_INPUT_DIRNAME', 'RULE_INPUT_EXT', 39b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 'EXECUTABLE_PREFIX', 'EXECUTABLE_SUFFIX', 40b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 'STATIC_LIB_PREFIX', 'STATIC_LIB_SUFFIX', 414051c257283eb3ca07dfdedefa34d7e2cd8c1975thakis@chromium.org 'SHARED_LIB_PREFIX', 'SHARED_LIB_SUFFIX', 424051c257283eb3ca07dfdedefa34d7e2cd8c1975thakis@chromium.org 'CONFIGURATION_NAME']: 43b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org generator_default_variables[unused] = '' 44b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 45061b1ecd71abd3060d5646a84a7105e571516202thakis@chromium.org# Include dirs will occasionally use the SHARED_INTERMEDIATE_DIR variable as 46b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org# part of the path when dealing with generated headers. This value will be 47b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org# replaced dynamically for each configuration. 48b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orggenerator_default_variables['SHARED_INTERMEDIATE_DIR'] = \ 49061b1ecd71abd3060d5646a84a7105e571516202thakis@chromium.org '$SHARED_INTERMEDIATE_DIR' 50b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 51b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 52b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgdef CalculateVariables(default_variables, params): 53b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org generator_flags = params.get('generator_flags', {}) 54b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org for key, val in generator_flags.items(): 55b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org default_variables.setdefault(key, val) 569820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org flavor = gyp.common.GetFlavor(params) 579820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org default_variables.setdefault('OS', flavor) 589820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org if flavor == 'win': 599820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org # Copy additional generator configuration data from VS, which is shared 609820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org # by the Eclipse generator. 619820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org import gyp.generator.msvs as msvs_generator 629820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org generator_additional_non_configuration_keys = getattr(msvs_generator, 639820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org 'generator_additional_non_configuration_keys', []) 649820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org generator_additional_path_sections = getattr(msvs_generator, 659820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org 'generator_additional_path_sections', []) 669820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org 67d298d5f26cc170b170ccb42a913dddb401581e27scottmg@chromium.org gyp.msvs_emulation.CalculateCommonVariables(default_variables, params) 68b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 69b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 70b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgdef CalculateGeneratorInputInfo(params): 71b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org """Calculate the generator specific info that gets fed to input (called by 72b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org gyp).""" 73b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org generator_flags = params.get('generator_flags', {}) 74b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org if generator_flags.get('adjust_static_libraries', False): 75b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org global generator_wants_static_library_dependencies_adjusted 76b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org generator_wants_static_library_dependencies_adjusted = True 77b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 78b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 79b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgdef GetAllIncludeDirectories(target_list, target_dicts, 804a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org shared_intermediate_dirs, config_name, params, 814a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org compiler_path): 82b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org """Calculate the set of include directories to be used. 83b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 84b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org Returns: 85b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org A list including all the include_dir's specified for every target followed 86b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org by any include directories that were added as cflag compiler options. 87b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org """ 88b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 89b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org gyp_includes_set = set() 90b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org compiler_includes_list = [] 91b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 924a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org # Find compiler's default include dirs. 934a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org if compiler_path: 944a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org command = shlex.split(compiler_path) 954a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org command.extend(['-E', '-xc++', '-v', '-']) 964a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org proc = subprocess.Popen(args=command, stdin=subprocess.PIPE, 974a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org stdout=subprocess.PIPE, stderr=subprocess.PIPE) 984a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org output = proc.communicate()[1] 994a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org # Extract the list of include dirs from the output, which has this format: 1004a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org # ... 1014a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org # #include "..." search starts here: 1024a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org # #include <...> search starts here: 1034a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org # /usr/include/c++/4.6 1044a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org # /usr/local/include 1054a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org # End of search list. 1064a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org # ... 1074a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org in_include_list = False 1084a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org for line in output.splitlines(): 1094a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org if line.startswith('#include'): 1104a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org in_include_list = True 1114a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org continue 1124a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org if line.startswith('End of search list.'): 1134a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org break 1144a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org if in_include_list: 1154a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org include_dir = line.strip() 1164a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org if include_dir not in compiler_includes_list: 1174a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org compiler_includes_list.append(include_dir) 1184a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org 1199820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org flavor = gyp.common.GetFlavor(params) 1209820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org if flavor == 'win': 1219820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org generator_flags = params.get('generator_flags', {}) 122b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org for target_name in target_list: 123b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org target = target_dicts[target_name] 124b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org if config_name in target['configurations']: 125b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org config = target['configurations'][config_name] 126b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 127b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org # Look for any include dirs that were explicitly added via cflags. This 128b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org # may be done in gyp files to force certain includes to come at the end. 129b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org # TODO(jgreenwald): Change the gyp files to not abuse cflags for this, and 130b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org # remove this. 1319820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org if flavor == 'win': 1329820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org msvs_settings = gyp.msvs_emulation.MsvsSettings(target, generator_flags) 1339820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org cflags = msvs_settings.GetCflags(config_name) 1349820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org else: 1359820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org cflags = config['cflags'] 136b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org for cflag in cflags: 137b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org if cflag.startswith('-I'): 138b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org include_dir = cflag[2:] 1394a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org if include_dir not in compiler_includes_list: 1404a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org compiler_includes_list.append(include_dir) 141b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 142b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org # Find standard gyp include dirs. 143b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org if config.has_key('include_dirs'): 144b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org include_dirs = config['include_dirs'] 145061b1ecd71abd3060d5646a84a7105e571516202thakis@chromium.org for shared_intermediate_dir in shared_intermediate_dirs: 146061b1ecd71abd3060d5646a84a7105e571516202thakis@chromium.org for include_dir in include_dirs: 147061b1ecd71abd3060d5646a84a7105e571516202thakis@chromium.org include_dir = include_dir.replace('$SHARED_INTERMEDIATE_DIR', 148061b1ecd71abd3060d5646a84a7105e571516202thakis@chromium.org shared_intermediate_dir) 149061b1ecd71abd3060d5646a84a7105e571516202thakis@chromium.org if not os.path.isabs(include_dir): 150061b1ecd71abd3060d5646a84a7105e571516202thakis@chromium.org base_dir = os.path.dirname(target_name) 151b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 152061b1ecd71abd3060d5646a84a7105e571516202thakis@chromium.org include_dir = base_dir + '/' + include_dir 153061b1ecd71abd3060d5646a84a7105e571516202thakis@chromium.org include_dir = os.path.abspath(include_dir) 154b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 1554a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org gyp_includes_set.add(include_dir) 156b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 157b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org # Generate a list that has all the include dirs. 158b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org all_includes_list = list(gyp_includes_set) 159b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org all_includes_list.sort() 160b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org for compiler_include in compiler_includes_list: 161b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org if not compiler_include in gyp_includes_set: 162b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org all_includes_list.append(compiler_include) 163b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 164b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org # All done. 165b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org return all_includes_list 166b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 167b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 168c2f33dbfd5b14c40f8c344788f2966fae3a764dathakis@chromium.orgdef GetCompilerPath(target_list, data, options): 169b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org """Determine a command that can be used to invoke the compiler. 170b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 171b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org Returns: 172b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org If this is a gyp project that has explicit make settings, try to determine 173b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org the compiler from that. Otherwise, see if a compiler was specified via the 174b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org CC_target environment variable. 175b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org """ 176b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org # First, see if the compiler is configured in make's settings. 177b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0]) 178b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org make_global_settings_dict = data[build_file].get('make_global_settings', {}) 179b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org for key, value in make_global_settings_dict: 180b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org if key in ['CC', 'CXX']: 181c2f33dbfd5b14c40f8c344788f2966fae3a764dathakis@chromium.org return os.path.join(options.toplevel_dir, value) 182b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 183b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org # Check to see if the compiler was specified as an environment variable. 184b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org for key in ['CC_target', 'CC', 'CXX']: 185b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org compiler = os.environ.get(key) 186b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org if compiler: 187b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org return compiler 188b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 189b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org return 'gcc' 190b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 191b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 1924a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.orgdef GetAllDefines(target_list, target_dicts, data, config_name, params, 1934a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org compiler_path): 194b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org """Calculate the defines for a project. 195b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 196b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org Returns: 197b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org A dict that includes explict defines declared in gyp files along with all of 198b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org the default defines that the compiler uses. 199b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org """ 200b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 201b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org # Get defines declared in the gyp files. 202b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org all_defines = {} 2039820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org flavor = gyp.common.GetFlavor(params) 2049820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org if flavor == 'win': 2059820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org generator_flags = params.get('generator_flags', {}) 206b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org for target_name in target_list: 207b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org target = target_dicts[target_name] 208b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 2099820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org if flavor == 'win': 2109820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org msvs_settings = gyp.msvs_emulation.MsvsSettings(target, generator_flags) 2119820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org extra_defines = msvs_settings.GetComputedDefines(config_name) 2129820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org else: 2139820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org extra_defines = [] 214b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org if config_name in target['configurations']: 215b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org config = target['configurations'][config_name] 2169820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org target_defines = config['defines'] 2179820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org else: 2189820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org target_defines = [] 2199820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org for define in target_defines + extra_defines: 2209820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org split_define = define.split('=', 1) 2219820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org if len(split_define) == 1: 2229820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org split_define.append('1') 2239820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org if split_define[0].strip() in all_defines: 2249820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org # Already defined 2259820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org continue 2269820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org all_defines[split_define[0].strip()] = split_define[1].strip() 227b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org # Get default compiler defines (if possible). 2289820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org if flavor == 'win': 2299820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org return all_defines # Default defines already processed in the loop above. 2304a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org if compiler_path: 2314a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org command = shlex.split(compiler_path) 232b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org command.extend(['-E', '-dM', '-']) 233b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org cpp_proc = subprocess.Popen(args=command, cwd='.', 234b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org stdin=subprocess.PIPE, stdout=subprocess.PIPE) 235b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org cpp_output = cpp_proc.communicate()[0] 236b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org cpp_lines = cpp_output.split('\n') 237b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org for cpp_line in cpp_lines: 238b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org if not cpp_line.strip(): 239b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org continue 240b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org cpp_line_parts = cpp_line.split(' ', 2) 241b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org key = cpp_line_parts[1] 242b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org if len(cpp_line_parts) >= 3: 243b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org val = cpp_line_parts[2] 244b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org else: 245b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org val = '1' 246b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org all_defines[key] = val 247b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 248b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org return all_defines 249b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 250b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 251b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgdef WriteIncludePaths(out, eclipse_langs, include_dirs): 252b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org """Write the includes section of a CDT settings export file.""" 253b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 254b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org out.write(' <section name="org.eclipse.cdt.internal.ui.wizards.' \ 255b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 'settingswizards.IncludePaths">\n') 256b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org out.write(' <language name="holder for library settings"></language>\n') 257b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org for lang in eclipse_langs: 258b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org out.write(' <language name="%s">\n' % lang) 259b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org for include_dir in include_dirs: 260b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org out.write(' <includepath workspace_path="false">%s</includepath>\n' % 261b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org include_dir) 262b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org out.write(' </language>\n') 263b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org out.write(' </section>\n') 264b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 265b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 266b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgdef WriteMacros(out, eclipse_langs, defines): 267b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org """Write the macros section of a CDT settings export file.""" 268b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 269b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org out.write(' <section name="org.eclipse.cdt.internal.ui.wizards.' \ 270b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 'settingswizards.Macros">\n') 271b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org out.write(' <language name="holder for library settings"></language>\n') 272b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org for lang in eclipse_langs: 273b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org out.write(' <language name="%s">\n' % lang) 274b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org for key in sorted(defines.iterkeys()): 275b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org out.write(' <macro><name>%s</name><value>%s</value></macro>\n' % 2764051c257283eb3ca07dfdedefa34d7e2cd8c1975thakis@chromium.org (escape(key), escape(defines[key]))) 277b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org out.write(' </language>\n') 278b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org out.write(' </section>\n') 279b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 280b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 281b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgdef GenerateOutputForConfig(target_list, target_dicts, data, params, 282b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org config_name): 283b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org options = params['options'] 284b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org generator_flags = params.get('generator_flags', {}) 285b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 286b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org # build_dir: relative path from source root to our output files. 287b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org # e.g. "out/Debug" 288b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org build_dir = os.path.join(generator_flags.get('output_dir', 'out'), 289b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org config_name) 290b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 291b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org toplevel_build = os.path.join(options.toplevel_dir, build_dir) 292061b1ecd71abd3060d5646a84a7105e571516202thakis@chromium.org # Ninja uses out/Debug/gen while make uses out/Debug/obj/gen as the 293061b1ecd71abd3060d5646a84a7105e571516202thakis@chromium.org # SHARED_INTERMEDIATE_DIR. Include both possible locations. 294061b1ecd71abd3060d5646a84a7105e571516202thakis@chromium.org shared_intermediate_dirs = [os.path.join(toplevel_build, 'obj', 'gen'), 295061b1ecd71abd3060d5646a84a7105e571516202thakis@chromium.org os.path.join(toplevel_build, 'gen')] 296b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 297b5a494899379867f5445f29db21fb2b8e5e8e03ethakis@chromium.org out_name = os.path.join(toplevel_build, 'eclipse-cdt-settings.xml') 298b5a494899379867f5445f29db21fb2b8e5e8e03ethakis@chromium.org gyp.common.EnsureDirExists(out_name) 299b5a494899379867f5445f29db21fb2b8e5e8e03ethakis@chromium.org out = open(out_name, 'w') 300b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 301b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org out.write('<?xml version="1.0" encoding="UTF-8"?>\n') 302b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org out.write('<cdtprojectproperties>\n') 303b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 304b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org eclipse_langs = ['C++ Source File', 'C Source File', 'Assembly Source File', 305b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 'GNU C++', 'GNU C', 'Assembly'] 306c2f33dbfd5b14c40f8c344788f2966fae3a764dathakis@chromium.org compiler_path = GetCompilerPath(target_list, data, options) 307b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org include_dirs = GetAllIncludeDirectories(target_list, target_dicts, 3089820176fbe19ce21858882df0d3024bf47fc7455thakis@chromium.org shared_intermediate_dirs, config_name, 3094a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org params, compiler_path) 310b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org WriteIncludePaths(out, eclipse_langs, include_dirs) 3114a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org defines = GetAllDefines(target_list, target_dicts, data, config_name, params, 3124a8a15f6333b72b02ca919825a1d0881d3ed1dbbthakis@chromium.org compiler_path) 313b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org WriteMacros(out, eclipse_langs, defines) 314b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 315b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org out.write('</cdtprojectproperties>\n') 316b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org out.close() 317b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 318b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 319b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.orgdef GenerateOutput(target_list, target_dicts, data, params): 320b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org """Generate an XML settings file that can be imported into a CDT project.""" 321b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 322b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org if params['options'].generator_output: 323b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org raise NotImplementedError, "--generator_output not implemented for eclipse" 324b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 325b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org user_config = params.get('generator_flags', {}).get('config', None) 326b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org if user_config: 327b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org GenerateOutputForConfig(target_list, target_dicts, data, params, 328b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org user_config) 329b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org else: 330b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org config_names = target_dicts[target_list[0]]['configurations'].keys() 331b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org for config_name in config_names: 332b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org GenerateOutputForConfig(target_list, target_dicts, data, params, 333b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org config_name) 334b9227b4de8268024460b3ff08a2abac964b18a8dthakis@chromium.org 335