| OLD | NEW |
| 1 # Copyright (c) 2012 Google Inc. All rights reserved. | 1 # Copyright (c) 2012 Google Inc. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 # Notes: | 5 # Notes: |
| 6 # | 6 # |
| 7 # This is all roughly based on the Makefile system used by the Linux | 7 # This is all roughly based on the Makefile system used by the Linux |
| 8 # kernel, but is a non-recursive make -- we put the entire dependency | 8 # kernel, but is a non-recursive make -- we put the entire dependency |
| 9 # graph in front of make and let it figure it out. | 9 # graph in front of make and let it figure it out. |
| 10 # | 10 # |
| 11 # The code below generates a separate .mk file for each target, but | 11 # The code below generates a separate .mk file for each target, but |
| 12 # all are sourced by the top-level Makefile. This means that all | 12 # all are sourced by the top-level Makefile. This means that all |
| 13 # variables in .mk-files clobber one another. Be careful to use := | 13 # variables in .mk-files clobber one another. Be careful to use := |
| 14 # where appropriate for immediate evaluation, and similarly to watch | 14 # where appropriate for immediate evaluation, and similarly to watch |
| 15 # that you're not relying on a variable value to last beween different | 15 # that you're not relying on a variable value to last beween different |
| 16 # .mk files. | 16 # .mk files. |
| 17 # | 17 # |
| 18 # TODOs: | 18 # TODOs: |
| 19 # | 19 # |
| 20 # Global settings and utility functions are currently stuffed in the | 20 # Global settings and utility functions are currently stuffed in the |
| 21 # toplevel Makefile. It may make sense to generate some .mk files on | 21 # toplevel Makefile. It may make sense to generate some .mk files on |
| 22 # the side to keep the the files readable. | 22 # the side to keep the the files readable. |
| 23 | 23 |
| 24 import os |
| 25 import re |
| 26 import sys |
| 24 import gyp | 27 import gyp |
| 25 import gyp.common | 28 import gyp.common |
| 26 import gyp.system_test | 29 import gyp.system_test |
| 27 import gyp.xcode_emulation | 30 import gyp.xcode_emulation |
| 28 import os | 31 from gyp.common import GetEnvironFallback |
| 29 import re | |
| 30 import sys | |
| 31 | 32 |
| 32 generator_default_variables = { | 33 generator_default_variables = { |
| 33 'EXECUTABLE_PREFIX': '', | 34 'EXECUTABLE_PREFIX': '', |
| 34 'EXECUTABLE_SUFFIX': '', | 35 'EXECUTABLE_SUFFIX': '', |
| 35 'STATIC_LIB_PREFIX': 'lib', | 36 'STATIC_LIB_PREFIX': 'lib', |
| 36 'SHARED_LIB_PREFIX': 'lib', | 37 'SHARED_LIB_PREFIX': 'lib', |
| 37 'STATIC_LIB_SUFFIX': '.a', | 38 'STATIC_LIB_SUFFIX': '.a', |
| 38 'INTERMEDIATE_DIR': '$(obj).$(TOOLSET)/$(TARGET)/geni', | 39 'INTERMEDIATE_DIR': '$(obj).$(TOOLSET)/$(TARGET)/geni', |
| 39 'SHARED_INTERMEDIATE_DIR': '$(obj)/gen', | 40 'SHARED_INTERMEDIATE_DIR': '$(obj)/gen', |
| 40 'PRODUCT_DIR': '$(builddir)', | 41 'PRODUCT_DIR': '$(builddir)', |
| (...skipping 12 matching lines...) Expand all Loading... |
| 53 generator_wants_sorted_dependencies = False | 54 generator_wants_sorted_dependencies = False |
| 54 | 55 |
| 55 # Placates pylint. | 56 # Placates pylint. |
| 56 generator_additional_non_configuration_keys = [] | 57 generator_additional_non_configuration_keys = [] |
| 57 generator_additional_path_sections = [] | 58 generator_additional_path_sections = [] |
| 58 generator_extra_sources_for_rules = [] | 59 generator_extra_sources_for_rules = [] |
| 59 | 60 |
| 60 | 61 |
| 61 def CalculateVariables(default_variables, params): | 62 def CalculateVariables(default_variables, params): |
| 62 """Calculate additional variables for use in the build (called by gyp).""" | 63 """Calculate additional variables for use in the build (called by gyp).""" |
| 63 cc_target = os.environ.get('CC.target', os.environ.get('CC', 'cc')) | |
| 64 flavor = gyp.common.GetFlavor(params) | 64 flavor = gyp.common.GetFlavor(params) |
| 65 if flavor == 'mac': | 65 if flavor == 'mac': |
| 66 default_variables.setdefault('OS', 'mac') | 66 default_variables.setdefault('OS', 'mac') |
| 67 default_variables.setdefault('SHARED_LIB_SUFFIX', '.dylib') | 67 default_variables.setdefault('SHARED_LIB_SUFFIX', '.dylib') |
| 68 default_variables.setdefault('SHARED_LIB_DIR', | 68 default_variables.setdefault('SHARED_LIB_DIR', |
| 69 generator_default_variables['PRODUCT_DIR']) | 69 generator_default_variables['PRODUCT_DIR']) |
| 70 default_variables.setdefault('LIB_DIR', | 70 default_variables.setdefault('LIB_DIR', |
| 71 generator_default_variables['PRODUCT_DIR']) | 71 generator_default_variables['PRODUCT_DIR']) |
| 72 | 72 |
| 73 # Copy additional generator configuration data from Xcode, which is shared | 73 # Copy additional generator configuration data from Xcode, which is shared |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 # | 248 # |
| 249 # Note: flock is used to seralize linking. Linking is a memory-intensive | 249 # Note: flock is used to seralize linking. Linking is a memory-intensive |
| 250 # process so running parallel links can often lead to thrashing. To disable | 250 # process so running parallel links can often lead to thrashing. To disable |
| 251 # the serialization, override LINK via an envrionment variable as follows: | 251 # the serialization, override LINK via an envrionment variable as follows: |
| 252 # | 252 # |
| 253 # export LINK=g++ | 253 # export LINK=g++ |
| 254 # | 254 # |
| 255 # This will allow make to invoke N linker processes as specified in -jN. | 255 # This will allow make to invoke N linker processes as specified in -jN. |
| 256 LINK ?= %(flock)s $(builddir)/linker.lock $(CXX) | 256 LINK ?= %(flock)s $(builddir)/linker.lock $(CXX) |
| 257 | 257 |
| 258 CC.target ?= $(CC) | 258 CC.target ?= %(CC.target)s |
| 259 CFLAGS.target ?= $(CFLAGS) | 259 CFLAGS.target ?= $(CFLAGS) |
| 260 CXX.target ?= $(CXX) | 260 CXX.target ?= %(CXX.target)s |
| 261 CXXFLAGS.target ?= $(CXXFLAGS) | 261 CXXFLAGS.target ?= $(CXXFLAGS) |
| 262 LINK.target ?= $(LINK) | 262 LINK.target ?= %(LINK.target)s |
| 263 LDFLAGS.target ?= $(LDFLAGS) | 263 LDFLAGS.target ?= $(LDFLAGS) |
| 264 AR.target ?= $(AR) | 264 AR.target ?= $(AR) |
| 265 ARFLAGS.target ?= %(ARFLAGS.target)s | 265 ARFLAGS.target ?= %(ARFLAGS.target)s |
| 266 | 266 |
| 267 # N.B.: the logic of which commands to run should match the computation done | 267 # N.B.: the logic of which commands to run should match the computation done |
| 268 # in gyp's make.py where ARFLAGS.host etc. is computed. | 268 # in gyp's make.py where ARFLAGS.host etc. is computed. |
| 269 # TODO(evan): move all cross-compilation logic to gyp-time so we don't need | 269 # TODO(evan): move all cross-compilation logic to gyp-time so we don't need |
| 270 # to replicate this environment fallback in make as well. | 270 # to replicate this environment fallback in make as well. |
| 271 CC.host ?= gcc | 271 CC.host ?= %(CC.host)s |
| 272 CFLAGS.host ?= | 272 CFLAGS.host ?= |
| 273 CXX.host ?= g++ | 273 CXX.host ?= %(CXX.host)s |
| 274 CXXFLAGS.host ?= | 274 CXXFLAGS.host ?= |
| 275 LINK.host ?= g++ | 275 LINK.host ?= %(LINK.host)s |
| 276 LDFLAGS.host ?= | 276 LDFLAGS.host ?= |
| 277 AR.host ?= ar | 277 AR.host ?= %(AR.host)s |
| 278 ARFLAGS.host := %(ARFLAGS.host)s | 278 ARFLAGS.host := %(ARFLAGS.host)s |
| 279 | 279 |
| 280 # Define a dir function that can handle spaces. | 280 # Define a dir function that can handle spaces. |
| 281 # http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions | 281 # http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions |
| 282 # "leading spaces cannot appear in the text of the first argument as written. | 282 # "leading spaces cannot appear in the text of the first argument as written. |
| 283 # These characters can be put into the argument value by variable substitution." | 283 # These characters can be put into the argument value by variable substitution." |
| 284 empty := | 284 empty := |
| 285 space := $(empty) $(empty) | 285 space := $(empty) $(empty) |
| 286 | 286 |
| 287 # http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-
with-spaces | 287 # http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-
with-spaces |
| (...skipping 1597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1885 """Run tests against the system to compute default settings for commands. | 1885 """Run tests against the system to compute default settings for commands. |
| 1886 | 1886 |
| 1887 Returns: | 1887 Returns: |
| 1888 dictionary of settings matching the block of command-lines used in | 1888 dictionary of settings matching the block of command-lines used in |
| 1889 SHARED_HEADER. E.g. the dictionary will contain a ARFLAGS.target | 1889 SHARED_HEADER. E.g. the dictionary will contain a ARFLAGS.target |
| 1890 key for the default ARFLAGS for the target ar command. | 1890 key for the default ARFLAGS for the target ar command. |
| 1891 """ | 1891 """ |
| 1892 # Compute flags used for building static archives. | 1892 # Compute flags used for building static archives. |
| 1893 # N.B.: this fallback logic should match the logic in SHARED_HEADER. | 1893 # N.B.: this fallback logic should match the logic in SHARED_HEADER. |
| 1894 # See comment there for more details. | 1894 # See comment there for more details. |
| 1895 ar_target = os.environ.get('AR.target', os.environ.get('AR', 'ar')) | 1895 ar_target = GetEnvironFallback(('AR_target', 'AR'), 'ar') |
| 1896 cc_target = os.environ.get('CC.target', os.environ.get('CC', 'cc')) | 1896 cc_target = GetEnvironFallback(('CC_target', 'CC'), 'cc') |
| 1897 arflags_target = 'crs' | 1897 arflags_target = 'crs' |
| 1898 # ar -T enables thin archives on Linux. OS X's ar supports a -T flag, but it | 1898 # ar -T enables thin archives on Linux. OS X's ar supports a -T flag, but it |
| 1899 # does something useless (it limits filenames in the archive to 15 chars). | 1899 # does something useless (it limits filenames in the archive to 15 chars). |
| 1900 if flavor != 'mac' and gyp.system_test.TestArSupportsT(ar_command=ar_target, | 1900 if flavor != 'mac' and gyp.system_test.TestArSupportsT(ar_command=ar_target, |
| 1901 cc_command=cc_target): | 1901 cc_command=cc_target): |
| 1902 arflags_target = 'crsT' | 1902 arflags_target = 'crsT' |
| 1903 | 1903 |
| 1904 ar_host = os.environ.get('AR.host', 'ar') | 1904 ar_host = os.environ.get('AR_host', 'ar') |
| 1905 cc_host = os.environ.get('CC.host', 'gcc') | 1905 cc_host = os.environ.get('CC_host', 'gcc') |
| 1906 arflags_host = 'crs' | 1906 arflags_host = 'crs' |
| 1907 # It feels redundant to compute this again given that most builds aren't | 1907 # It feels redundant to compute this again given that most builds aren't |
| 1908 # cross-compiles, but due to quirks of history CC.host defaults to 'gcc' | 1908 # cross-compiles, but due to quirks of history CC_host defaults to 'gcc' |
| 1909 # while CC.target defaults to 'cc', so the commands really are different | 1909 # while CC_target defaults to 'cc', so the commands really are different |
| 1910 # even though they're nearly guaranteed to run the same code underneath. | 1910 # even though they're nearly guaranteed to run the same code underneath. |
| 1911 if flavor != 'mac' and gyp.system_test.TestArSupportsT(ar_command=ar_host, | 1911 if flavor != 'mac' and gyp.system_test.TestArSupportsT(ar_command=ar_host, |
| 1912 cc_command=cc_host): | 1912 cc_command=cc_host): |
| 1913 arflags_host = 'crsT' | 1913 arflags_host = 'crsT' |
| 1914 | 1914 |
| 1915 return { 'ARFLAGS.target': arflags_target, | 1915 return { 'ARFLAGS.target': arflags_target, |
| 1916 'ARFLAGS.host': arflags_host } | 1916 'ARFLAGS.host': arflags_host } |
| 1917 | 1917 |
| 1918 | 1918 |
| 1919 def GenerateOutput(target_list, target_dicts, data, params): | 1919 def GenerateOutput(target_list, target_dicts, data, params): |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1988 elif flavor == 'solaris': | 1988 elif flavor == 'solaris': |
| 1989 header_params.update({ | 1989 header_params.update({ |
| 1990 'flock': './gyp-sun-tool flock', | 1990 'flock': './gyp-sun-tool flock', |
| 1991 'flock_index': 2, | 1991 'flock_index': 2, |
| 1992 'extra_commands': SHARED_HEADER_SUN_COMMANDS, | 1992 'extra_commands': SHARED_HEADER_SUN_COMMANDS, |
| 1993 }) | 1993 }) |
| 1994 elif flavor == 'freebsd': | 1994 elif flavor == 'freebsd': |
| 1995 header_params.update({ | 1995 header_params.update({ |
| 1996 'flock': 'lockf', | 1996 'flock': 'lockf', |
| 1997 }) | 1997 }) |
| 1998 |
| 1998 header_params.update(RunSystemTests(flavor)) | 1999 header_params.update(RunSystemTests(flavor)) |
| 2000 header_params.update({ |
| 2001 'CC.target': GetEnvironFallback(('CC_target', 'CC'), '$(CC)'), |
| 2002 'AR.target': GetEnvironFallback(('AR_target', 'AR'), '$(AR)'), |
| 2003 'CXX.target': GetEnvironFallback(('CXX_target', 'CXX'), '$(CXX)'), |
| 2004 'LINK.target': GetEnvironFallback(('LD_target', 'LD'), '$(LINK)'), |
| 2005 'CC.host': GetEnvironFallback(('CC_host',), 'gcc'), |
| 2006 'AR.host': GetEnvironFallback(('AR_host',), 'ar'), |
| 2007 'CXX.host': GetEnvironFallback(('CXX_host',), 'g++'), |
| 2008 'LINK.host': GetEnvironFallback(('LD_host',), 'g++'), |
| 2009 }) |
| 1999 | 2010 |
| 2000 build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0]) | 2011 build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0]) |
| 2001 make_global_settings_dict = data[build_file].get('make_global_settings', {}) | 2012 make_global_settings_array = data[build_file].get('make_global_settings', []) |
| 2002 make_global_settings = '' | 2013 make_global_settings = '' |
| 2003 for key, value in make_global_settings_dict: | 2014 for key, value in make_global_settings_array: |
| 2004 if value[0] != '$': | 2015 if value[0] != '$': |
| 2005 value = '$(abspath %s)' % value | 2016 value = '$(abspath %s)' % value |
| 2006 if key == 'LINK': | 2017 if key in ('LINK', 'LINK.host'): |
| 2007 make_global_settings += ('%s ?= %s $(builddir)/linker.lock %s\n' % | 2018 make_global_settings += ('%s ?= %s $(builddir)/linker.lock %s\n' % |
| 2008 (key, flock_command, value)) | 2019 (key, flock_command, value)) |
| 2009 elif key in ['CC', 'CXX']: | 2020 elif key in ('CC', 'CC.host', 'CXX', 'CXX.host'): |
| 2010 make_global_settings += ( | 2021 make_global_settings += ( |
| 2011 'ifneq (,$(filter $(origin %s), undefined default))\n' % key) | 2022 'ifneq (,$(filter $(origin %s), undefined default))\n' % key) |
| 2012 # Let gyp-time envvars win over global settings. | 2023 # Let gyp-time envvars win over global settings. |
| 2013 if key in os.environ: | 2024 if key in os.environ: |
| 2014 value = os.environ[key] | 2025 value = os.environ[key] |
| 2015 make_global_settings += ' %s = %s\n' % (key, value) | 2026 make_global_settings += ' %s = %s\n' % (key, value) |
| 2016 make_global_settings += 'endif\n' | 2027 make_global_settings += 'endif\n' |
| 2017 else: | 2028 else: |
| 2018 make_global_settings += '%s ?= %s\n' % (key, value) | 2029 make_global_settings += '%s ?= %s\n' % (key, value) |
| 2019 header_params['make_global_settings'] = make_global_settings | 2030 header_params['make_global_settings'] = make_global_settings |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2041 for build_file in params['build_files']: | 2052 for build_file in params['build_files']: |
| 2042 for target in gyp.common.AllTargets(target_list, target_dicts, build_file): | 2053 for target in gyp.common.AllTargets(target_list, target_dicts, build_file): |
| 2043 needed_targets.add(target) | 2054 needed_targets.add(target) |
| 2044 | 2055 |
| 2045 build_files = set() | 2056 build_files = set() |
| 2046 include_list = set() | 2057 include_list = set() |
| 2047 for qualified_target in target_list: | 2058 for qualified_target in target_list: |
| 2048 build_file, target, toolset = gyp.common.ParseQualifiedTarget( | 2059 build_file, target, toolset = gyp.common.ParseQualifiedTarget( |
| 2049 qualified_target) | 2060 qualified_target) |
| 2050 | 2061 |
| 2051 this_make_global_settings = data[build_file].get('make_global_settings', {}) | 2062 this_make_global_settings = data[build_file].get('make_global_settings', []) |
| 2052 assert make_global_settings_dict == this_make_global_settings, ( | 2063 assert make_global_settings_array == this_make_global_settings, ( |
| 2053 "make_global_settings needs to be the same for all targets.") | 2064 "make_global_settings needs to be the same for all targets.") |
| 2054 | 2065 |
| 2055 build_files.add(gyp.common.RelativePath(build_file, options.toplevel_dir)) | 2066 build_files.add(gyp.common.RelativePath(build_file, options.toplevel_dir)) |
| 2056 included_files = data[build_file]['included_files'] | 2067 included_files = data[build_file]['included_files'] |
| 2057 for included_file in included_files: | 2068 for included_file in included_files: |
| 2058 # The included_files entries are relative to the dir of the build file | 2069 # The included_files entries are relative to the dir of the build file |
| 2059 # that included them, so we have to undo that and then make them relative | 2070 # that included them, so we have to undo that and then make them relative |
| 2060 # to the root dir. | 2071 # to the root dir. |
| 2061 relative_include_file = gyp.common.RelativePath( | 2072 relative_include_file = gyp.common.RelativePath( |
| 2062 gyp.common.UnrelativePath(included_file, build_file), | 2073 gyp.common.UnrelativePath(included_file, build_file), |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2124 root_makefile.write(" include " + include_file + "\n") | 2135 root_makefile.write(" include " + include_file + "\n") |
| 2125 root_makefile.write("endif\n") | 2136 root_makefile.write("endif\n") |
| 2126 root_makefile.write('\n') | 2137 root_makefile.write('\n') |
| 2127 | 2138 |
| 2128 if generator_flags.get('auto_regeneration', True): | 2139 if generator_flags.get('auto_regeneration', True): |
| 2129 WriteAutoRegenerationRule(params, root_makefile, makefile_name, build_files) | 2140 WriteAutoRegenerationRule(params, root_makefile, makefile_name, build_files) |
| 2130 | 2141 |
| 2131 root_makefile.write(SHARED_FOOTER) | 2142 root_makefile.write(SHARED_FOOTER) |
| 2132 | 2143 |
| 2133 root_makefile.close() | 2144 root_makefile.close() |
| OLD | NEW |