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 |