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 gyp | 24 import gyp |
25 import gyp.common | 25 import gyp.common |
26 import gyp.system_test | |
27 import gyp.xcode_emulation | 26 import gyp.xcode_emulation |
28 import os | 27 import os |
29 import re | 28 import re |
30 import sys | 29 import sys |
31 | 30 |
32 generator_default_variables = { | 31 generator_default_variables = { |
33 'EXECUTABLE_PREFIX': '', | 32 'EXECUTABLE_PREFIX': '', |
34 'EXECUTABLE_SUFFIX': '', | 33 'EXECUTABLE_SUFFIX': '', |
35 'STATIC_LIB_PREFIX': 'lib', | 34 'STATIC_LIB_PREFIX': 'lib', |
36 'SHARED_LIB_PREFIX': 'lib', | 35 'SHARED_LIB_PREFIX': 'lib', |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 # file for | 115 # file for |
117 # Chromium\ Framework.framework/foo | 116 # Chromium\ Framework.framework/foo |
118 # is for example | 117 # is for example |
119 # out/Release/.deps/out/Release/Chromium?Framework.framework/foo | 118 # out/Release/.deps/out/Release/Chromium?Framework.framework/foo |
120 # This is the replacement character. | 119 # This is the replacement character. |
121 SPACE_REPLACEMENT = '?' | 120 SPACE_REPLACEMENT = '?' |
122 | 121 |
123 | 122 |
124 LINK_COMMANDS_LINUX = """\ | 123 LINK_COMMANDS_LINUX = """\ |
125 quiet_cmd_alink = AR($(TOOLSET)) $@ | 124 quiet_cmd_alink = AR($(TOOLSET)) $@ |
126 cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) $(ARFLAGS.$(TOOLSET)) $@ $(filter %.o,$
^) | 125 cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^) |
127 | 126 |
128 # Due to circular dependencies between libraries :(, we wrap the | 127 # Due to circular dependencies between libraries :(, we wrap the |
129 # special "figure out circular dependencies" flags around the entire | 128 # special "figure out circular dependencies" flags around the entire |
130 # input list during linking. | 129 # input list during linking. |
131 quiet_cmd_link = LINK($(TOOLSET)) $@ | 130 quiet_cmd_link = LINK($(TOOLSET)) $@ |
132 cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--s
tart-group $(LD_INPUTS) -Wl,--end-group $(LIBS) | 131 cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--s
tart-group $(LD_INPUTS) -Wl,--end-group $(LIBS) |
133 | 132 |
134 # We support two kinds of shared objects (.so): | 133 # We support two kinds of shared objects (.so): |
135 # 1) shared_library, which is just bundling together many dependent libraries | 134 # 1) shared_library, which is just bundling together many dependent libraries |
136 # into a link line. | 135 # into a link line. |
(...skipping 30 matching lines...) Expand all Loading... |
167 cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o
"$@" $(LD_INPUTS) $(LIBS) | 166 cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o
"$@" $(LD_INPUTS) $(LIBS) |
168 | 167 |
169 # TODO(thakis): The solink_module rule is likely wrong. Xcode seems to pass | 168 # TODO(thakis): The solink_module rule is likely wrong. Xcode seems to pass |
170 # -bundle -single_module here (for osmesa.so). | 169 # -bundle -single_module here (for osmesa.so). |
171 quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ | 170 quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ |
172 cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSE
T)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS) | 171 cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSE
T)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS) |
173 """ | 172 """ |
174 | 173 |
175 LINK_COMMANDS_ANDROID = """\ | 174 LINK_COMMANDS_ANDROID = """\ |
176 quiet_cmd_alink = AR($(TOOLSET)) $@ | 175 quiet_cmd_alink = AR($(TOOLSET)) $@ |
177 cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) $(ARFLAGS.$(TOOLSET)) $@ $(filter %.o,$
^) | 176 cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^) |
178 | 177 |
179 # Due to circular dependencies between libraries :(, we wrap the | 178 # Due to circular dependencies between libraries :(, we wrap the |
180 # special "figure out circular dependencies" flags around the entire | 179 # special "figure out circular dependencies" flags around the entire |
181 # input list during linking. | 180 # input list during linking. |
182 quiet_cmd_link = LINK($(TOOLSET)) $@ | 181 quiet_cmd_link = LINK($(TOOLSET)) $@ |
183 quiet_cmd_link_host = LINK($(TOOLSET)) $@ | 182 quiet_cmd_link_host = LINK($(TOOLSET)) $@ |
184 cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--s
tart-group $(LD_INPUTS) -Wl,--end-group $(LIBS) | 183 cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--s
tart-group $(LD_INPUTS) -Wl,--end-group $(LIBS) |
185 cmd_link_host = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(
LD_INPUTS) $(LIBS) | 184 cmd_link_host = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(
LD_INPUTS) $(LIBS) |
186 | 185 |
187 # Other shared-object link notes: | 186 # Other shared-object link notes: |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 # This will allow make to invoke N linker processes as specified in -jN. | 252 # This will allow make to invoke N linker processes as specified in -jN. |
254 LINK ?= %(flock)s $(builddir)/linker.lock $(CXX) | 253 LINK ?= %(flock)s $(builddir)/linker.lock $(CXX) |
255 | 254 |
256 CC.target ?= $(CC) | 255 CC.target ?= $(CC) |
257 CFLAGS.target ?= $(CFLAGS) | 256 CFLAGS.target ?= $(CFLAGS) |
258 CXX.target ?= $(CXX) | 257 CXX.target ?= $(CXX) |
259 CXXFLAGS.target ?= $(CXXFLAGS) | 258 CXXFLAGS.target ?= $(CXXFLAGS) |
260 LINK.target ?= $(LINK) | 259 LINK.target ?= $(LINK) |
261 LDFLAGS.target ?= $(LDFLAGS) | 260 LDFLAGS.target ?= $(LDFLAGS) |
262 AR.target ?= $(AR) | 261 AR.target ?= $(AR) |
263 ARFLAGS.target ?= %(ARFLAGS.target)s | |
264 | 262 |
265 # N.B.: the logic of which commands to run should match the computation done | |
266 # in gyp's make.py where ARFLAGS.host etc. is computed. | |
267 # TODO(evan): move all cross-compilation logic to gyp-time so we don't need | 263 # TODO(evan): move all cross-compilation logic to gyp-time so we don't need |
268 # to replicate this environment fallback in make as well. | 264 # to replicate this environment fallback in make as well. |
269 CC.host ?= gcc | 265 CC.host ?= gcc |
270 CFLAGS.host ?= | 266 CFLAGS.host ?= |
271 CXX.host ?= g++ | 267 CXX.host ?= g++ |
272 CXXFLAGS.host ?= | 268 CXXFLAGS.host ?= |
273 LINK.host ?= g++ | 269 LINK.host ?= g++ |
274 LDFLAGS.host ?= | 270 LDFLAGS.host ?= |
275 AR.host ?= ar | 271 AR.host ?= ar |
276 ARFLAGS.host := %(ARFLAGS.host)s | |
277 | 272 |
278 # Define a dir function that can handle spaces. | 273 # Define a dir function that can handle spaces. |
279 # http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions | 274 # http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions |
280 # "leading spaces cannot appear in the text of the first argument as written. | 275 # "leading spaces cannot appear in the text of the first argument as written. |
281 # These characters can be put into the argument value by variable substitution." | 276 # These characters can be put into the argument value by variable substitution." |
282 empty := | 277 empty := |
283 space := $(empty) $(empty) | 278 space := $(empty) $(empty) |
284 | 279 |
285 # http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-
with-spaces | 280 # http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-
with-spaces |
286 replace_spaces = $(subst $(space),""" + SPACE_REPLACEMENT + """,$1) | 281 replace_spaces = $(subst $(space),""" + SPACE_REPLACEMENT + """,$1) |
(...skipping 1585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1872 "%(makefile_name)s: %(deps)s\n" | 1867 "%(makefile_name)s: %(deps)s\n" |
1873 "\t$(call do_cmd,regen_makefile)\n\n" % { | 1868 "\t$(call do_cmd,regen_makefile)\n\n" % { |
1874 'makefile_name': makefile_name, | 1869 'makefile_name': makefile_name, |
1875 'deps': ' '.join(map(Sourceify, build_files)), | 1870 'deps': ' '.join(map(Sourceify, build_files)), |
1876 'cmd': gyp.common.EncodePOSIXShellList( | 1871 'cmd': gyp.common.EncodePOSIXShellList( |
1877 [gyp_binary, '-fmake'] + | 1872 [gyp_binary, '-fmake'] + |
1878 gyp.RegenerateFlags(options) + | 1873 gyp.RegenerateFlags(options) + |
1879 build_files_args)}) | 1874 build_files_args)}) |
1880 | 1875 |
1881 | 1876 |
1882 def RunSystemTests(flavor): | |
1883 """Run tests against the system to compute default settings for commands. | |
1884 | |
1885 Returns: | |
1886 dictionary of settings matching the block of command-lines used in | |
1887 SHARED_HEADER. E.g. the dictionary will contain a ARFLAGS.target | |
1888 key for the default ARFLAGS for the target ar command. | |
1889 """ | |
1890 # Compute flags used for building static archives. | |
1891 # N.B.: this fallback logic should match the logic in SHARED_HEADER. | |
1892 # See comment there for more details. | |
1893 ar_target = os.environ.get('AR.target', os.environ.get('AR', 'ar')) | |
1894 cc_target = os.environ.get('CC.target', os.environ.get('CC', 'cc')) | |
1895 arflags_target = 'crs' | |
1896 # ar -T enables thin archives on Linux. OS X's ar supports a -T flag, but it | |
1897 # does something useless (it limits filenames in the archive to 15 chars). | |
1898 if flavor != 'mac' and gyp.system_test.TestArSupportsT(ar_command=ar_target, | |
1899 cc_command=cc_target): | |
1900 arflags_target = 'crsT' | |
1901 | |
1902 ar_host = os.environ.get('AR.host', 'ar') | |
1903 cc_host = os.environ.get('CC.host', 'gcc') | |
1904 arflags_host = 'crs' | |
1905 # It feels redundant to compute this again given that most builds aren't | |
1906 # cross-compiles, but due to quirks of history CC.host defaults to 'gcc' | |
1907 # while CC.target defaults to 'cc', so the commands really are different | |
1908 # even though they're nearly guaranteed to run the same code underneath. | |
1909 if flavor != 'mac' and gyp.system_test.TestArSupportsT(ar_command=ar_host, | |
1910 cc_command=cc_host): | |
1911 arflags_host = 'crsT' | |
1912 | |
1913 return { 'ARFLAGS.target': arflags_target, | |
1914 'ARFLAGS.host': arflags_host } | |
1915 | |
1916 | |
1917 def GenerateOutput(target_list, target_dicts, data, params): | 1877 def GenerateOutput(target_list, target_dicts, data, params): |
1918 options = params['options'] | 1878 options = params['options'] |
1919 flavor = gyp.common.GetFlavor(params) | 1879 flavor = gyp.common.GetFlavor(params) |
1920 generator_flags = params.get('generator_flags', {}) | 1880 generator_flags = params.get('generator_flags', {}) |
1921 builddir_name = generator_flags.get('output_dir', 'out') | 1881 builddir_name = generator_flags.get('output_dir', 'out') |
1922 android_ndk_version = generator_flags.get('android_ndk_version', None) | 1882 android_ndk_version = generator_flags.get('android_ndk_version', None) |
1923 default_target = generator_flags.get('default_target', 'all') | 1883 default_target = generator_flags.get('default_target', 'all') |
1924 | 1884 |
1925 def CalculateMakefilePath(build_file, base_name): | 1885 def CalculateMakefilePath(build_file, base_name): |
1926 """Determine where to write a Makefile for a given gyp file.""" | 1886 """Determine where to write a Makefile for a given gyp file.""" |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1986 elif flavor == 'solaris': | 1946 elif flavor == 'solaris': |
1987 header_params.update({ | 1947 header_params.update({ |
1988 'flock': './gyp-sun-tool flock', | 1948 'flock': './gyp-sun-tool flock', |
1989 'flock_index': 2, | 1949 'flock_index': 2, |
1990 'extra_commands': SHARED_HEADER_SUN_COMMANDS, | 1950 'extra_commands': SHARED_HEADER_SUN_COMMANDS, |
1991 }) | 1951 }) |
1992 elif flavor == 'freebsd': | 1952 elif flavor == 'freebsd': |
1993 header_params.update({ | 1953 header_params.update({ |
1994 'flock': 'lockf', | 1954 'flock': 'lockf', |
1995 }) | 1955 }) |
1996 header_params.update(RunSystemTests(flavor)) | |
1997 | 1956 |
1998 build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0]) | 1957 build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0]) |
1999 make_global_settings_dict = data[build_file].get('make_global_settings', {}) | 1958 make_global_settings_dict = data[build_file].get('make_global_settings', {}) |
2000 make_global_settings = '' | 1959 make_global_settings = '' |
2001 for key, value in make_global_settings_dict: | 1960 for key, value in make_global_settings_dict: |
2002 if value[0] != '$': | 1961 if value[0] != '$': |
2003 value = '$(abspath %s)' % value | 1962 value = '$(abspath %s)' % value |
2004 if key == 'LINK': | 1963 if key == 'LINK': |
2005 make_global_settings += ('%s ?= %s $(builddir)/linker.lock %s\n' % | 1964 make_global_settings += ('%s ?= %s $(builddir)/linker.lock %s\n' % |
2006 (key, flock_command, value)) | 1965 (key, flock_command, value)) |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2140 # Add a check to make sure we tried to process all the .d files. | 2099 # Add a check to make sure we tried to process all the .d files. |
2141 all_deps += """ | 2100 all_deps += """ |
2142 ifneq ($(word %(last)d,$(d_files)),) | 2101 ifneq ($(word %(last)d,$(d_files)),) |
2143 $(error Found unprocessed dependency files (gyp didn't generate enough rules
!)) | 2102 $(error Found unprocessed dependency files (gyp didn't generate enough rules
!)) |
2144 endif | 2103 endif |
2145 """ % { 'last': ((num_outputs / 1000) + 1) * 1000 + 1 } | 2104 """ % { 'last': ((num_outputs / 1000) + 1) * 1000 + 1 } |
2146 | 2105 |
2147 root_makefile.write(SHARED_FOOTER % { 'generate_all_deps': all_deps }) | 2106 root_makefile.write(SHARED_FOOTER % { 'generate_all_deps': all_deps }) |
2148 | 2107 |
2149 root_makefile.close() | 2108 root_makefile.close() |
OLD | NEW |