Chromium Code Reviews| Index: pylib/gyp/generator/ninja.py |
| diff --git a/pylib/gyp/generator/ninja.py b/pylib/gyp/generator/ninja.py |
| index 79224331c336a79e2c10644e8032428cc697d170..123b76aee5eda6c8799f104a997aedbb8d47c9fd 100644 |
| --- a/pylib/gyp/generator/ninja.py |
| +++ b/pylib/gyp/generator/ninja.py |
| @@ -6,6 +6,7 @@ import copy |
| import gyp |
| import gyp.common |
| import gyp.msvs_emulation |
| +import gyp.MSVSVersion |
| import gyp.system_test |
| import gyp.xcode_emulation |
| import os.path |
| @@ -216,7 +217,11 @@ class NinjaWriter: |
| if self.flavor == 'win': |
| # Don't use os.path.normpath here. Callers pass in './foo' and expect |
| - # the result to be runnable, but normpath removes the prefix. |
| + # the result to be runnable, but normpath removes the prefix. If the |
| + # variable is $! prefixed on Windows, don't modify it (used for compiler |
| + # flags, etc.) |
| + if path.startswith('$!'): |
|
Nico
2012/02/27 16:23:30
This is just to prevent '/c' -> '\\c', right? Does
scottmg
2012/02/28 00:01:13
I'm using that as a "raw" prefix. For example, the
|
| + return path[2:] |
| return path.replace('/', '\\') |
| return path |
| @@ -303,10 +308,11 @@ class NinjaWriter: |
| self.target = Target(spec['type']) |
| self.is_mac_bundle = gyp.xcode_emulation.IsMacBundle(self.flavor, spec) |
| + self.xcode_settings = self.msvs_settings = None |
| if self.flavor == 'mac': |
| self.xcode_settings = gyp.xcode_emulation.XcodeSettings(spec) |
| - else: |
| - self.xcode_settings = None |
| + if self.flavor == 'win': |
| + self.msvs_settings = gyp.msvs_emulation.MsvsSettings(spec) |
| # Compute predepends for all rules. |
| # actions_depends is the dependencies this target depends on before running |
| @@ -583,6 +589,8 @@ class NinjaWriter: |
| self.ninja.variable('cxx', '$cxx_target') |
| self.ninja.variable('ld', '$ld_target') |
| + extra_includes = [] |
| + extra_defines = [] |
|
Nico
2012/02/27 16:23:30
Could you just add these to the GetCflags() output
scottmg
2012/02/28 00:01:13
Hmm, I'd have to duplicate the -D/-I and escaping
|
| if self.flavor == 'mac': |
| cflags = self.xcode_settings.GetCflags(config_name) |
| cflags_c = self.xcode_settings.GetCflagsC(config_name) |
| @@ -591,17 +599,25 @@ class NinjaWriter: |
| self.xcode_settings.GetCflagsObjC(config_name) |
| cflags_objcc = ['$cflags_cc'] + \ |
| self.xcode_settings.GetCflagsObjCC(config_name) |
| + elif self.flavor == 'win': |
| + cflags = self.msvs_settings.GetCflags(config_name) |
| + cflags_c = self.msvs_settings.GetCflagsC(config_name) |
| + cflags_cc = self.msvs_settings.GetCflagsCC(config_name) |
| + extra_includes = self.msvs_settings.GetSystemIncludes(config_name) |
| + extra_defines = self.msvs_settings.GetComputedDefines(config_name) |
| else: |
| cflags = config.get('cflags', []) |
| cflags_c = config.get('cflags_c', []) |
| cflags_cc = config.get('cflags_cc', []) |
| + defines = config.get('defines', []) + extra_defines |
| self.WriteVariableList('defines', |
| [QuoteShellArgument(ninja_syntax.escape('-D' + d), self.flavor) |
| - for d in config.get('defines', [])]) |
| + for d in defines]) |
| + include_dirs = config.get('include_dirs', []) + extra_includes |
| self.WriteVariableList('includes', |
| - ['-I' + self.GypPathToNinja(i) |
| - for i in config.get('include_dirs', [])]) |
| + [QuoteShellArgument('-I' + self.GypPathToNinja(i), self.flavor) |
| + for i in include_dirs]) |
| pch_commands = precompiled_header.GetGchBuildCommands() |
| if self.flavor == 'mac': |
| @@ -711,6 +727,10 @@ class NinjaWriter: |
| ldflags = self.xcode_settings.GetLdflags(config_name, |
| self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']), |
| self.GypPathToNinja) |
| + elif self.flavor == 'win': |
| + ldflags = self.msvs_settings.GetLdflags(config_name, |
| + self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']), |
| + self.GypPathToNinja) |
| else: |
| ldflags = config.get('ldflags', []) |
| self.WriteVariableList('ldflags', |
| @@ -1011,6 +1031,24 @@ def CalculateVariables(default_variables, params): |
| default_variables['STATIC_LIB_SUFFIX'] = '.lib' |
| default_variables['SHARED_LIB_PREFIX'] = '' |
| default_variables['SHARED_LIB_SUFFIX'] = '.dll' |
| + generator_flags = params.get('generator_flags', {}) |
| + msvs_version = gyp.MSVSVersion.SelectVisualStudioVersion( |
| + generator_flags.get('msvs_version', 'auto')) |
| + # Stash msvs_version for later (so we don't have to probe the system twice). |
| + params['msvs_version'] = msvs_version |
| + |
| + # Set a variable so conditions can be based on msvs_version. |
| + default_variables['MSVS_VERSION'] = msvs_version.ShortName() |
|
Nico
2012/02/27 16:23:30
Would it make sense to say "ninja works only with
scottmg
2012/02/28 00:01:13
I think just this bit of code right now. (I'm actu
|
| + |
| + # To determine processor word size on Windows, in addition to checking |
| + # PROCESSOR_ARCHITECTURE (which reflects the word size of the current |
| + # process), it is also necessary to check PROCESSOR_ARCITEW6432 (which |
|
Nico
2012/02/27 16:23:30
typo PROCESSOR_ARCHITEW6432
scottmg
2012/02/28 00:01:13
Done.
|
| + # contains the actual word size of the system when running thru WOW64). |
| + if (os.environ.get('PROCESSOR_ARCHITECTURE', '').find('64') >= 0 or |
|
Nico
2012/02/27 16:23:30
if ('64' in os.environ.get('PROCESSOR_ARCHITECTURE
scottmg
2012/02/28 00:01:13
Done.
|
| + os.environ.get('PROCESSOR_ARCHITEW6432', '').find('64') >= 0): |
| + default_variables['MSVS_OS_BITS'] = 64 |
| + else: |
| + default_variables['MSVS_OS_BITS'] = 32 |
| else: |
| operating_system = flavor |
| if flavor == 'android': |
| @@ -1106,7 +1144,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, |
| command=('cmd /c $cc /nologo /showIncludes ' |
| '$defines $includes $cflags $cflags_c ' |
| '$cflags_pch_c /c $in /Fo$out ' |
| - '| ninja-deplist-helper -f cl -o $out.dl'), |
| + '| ninja-deplist-helper -q -f cl -o $out.dl'), |
| deplist='$out.dl') |
| master_ninja.rule( |
| 'cxx', |
| @@ -1114,7 +1152,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, |
| command=('cmd /c $cxx /nologo /showIncludes ' |
| '$defines $includes $cflags $cflags_cc ' |
| '$cflags_pch_cc /c $in /Fo$out ' |
| - '| ninja-deplist-helper -f cl -o $out.dl'), |
| + '| ninja-deplist-helper -q -f cl -o $out.dl'), |
| deplist='$out.dl') |
| if flavor != 'mac' and flavor != 'win': |
| @@ -1145,15 +1183,17 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, |
| master_ninja.rule( |
| 'solink', |
| description='LINK(DLL) $dll', |
| - command=('$ld /nologo /IMPLIB:$implib /DLL $ldflags /OUT:$dll $in $libs')) |
| + command=('$ld /nologo /IMPLIB:$implib /DLL $ldflags /OUT:$dll ' |
| + '/PDB:$dll.pdb $in $libs')) |
|
Nico
2012/02/27 16:23:30
msdn says "The default file name for the PDB has t
scottmg
2012/02/28 00:01:13
Yeah, we currently make a bit of a mess of our pdb
|
| master_ninja.rule( |
| 'solink_module', |
| description='LINK(DLL) $dll', |
| - command=('$ld /nologo /IMPLIB:$implib /DLL $ldflags /OUT:$dll $in $libs')) |
| + command=('$ld /nologo /IMPLIB:$implib /DLL $ldflags /OUT:$dll ' |
| + '/PDB:$dll.pdb $in $libs')) |
| master_ninja.rule( |
| 'link', |
| description='LINK $out', |
| - command=('$ld /nologo $ldflags /OUT:$out $in $libs')) |
| + command=('$ld /nologo $ldflags /OUT:$out /PDB:$out.pdb $in $libs')) |
| else: |
| master_ninja.rule( |
| 'objc', |
| @@ -1209,11 +1249,11 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, |
| 'stamp', |
| description='STAMP $out', |
| command='cmd /c copy /y nul $out>nul') |
| - # TODO(scottmg): Copy fallback? |
| master_ninja.rule( |
| 'copy', |
| description='COPY $in $out', |
| - command='cmd /c mklink /h $out $in >nul || mklink /h /j $out $in >nul') |
| + command='cmd /c mklink /h $out $in >nul || mklink /h /j $out $in >nul || ' |
| + 'python gyp-win-tool recursive-mirror $in $out') |
|
Nico
2012/02/27 16:23:30
also needs an `svn up`
scottmg
2012/02/28 00:01:13
Done.
|
| else: |
| master_ninja.rule( |
| 'stamp', |
| @@ -1227,7 +1267,9 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, |
| all_targets = set() |
| for build_file in params['build_files']: |
| - for target in gyp.common.AllTargets(target_list, target_dicts, build_file): |
| + for target in gyp.common.AllTargets(target_list, |
| + target_dicts, |
| + os.path.normpath(build_file)): |
|
Nico
2012/02/27 16:23:30
this looks familiar as well
scottmg
2012/02/28 00:01:13
Done.
|
| all_targets.add(target) |
| all_outputs = set() |