]>
Commit | Line | Data |
---|---|---|
1 | # Copyright 2003 Christopher Currie | |
2 | # Copyright 2006 Dave Abrahams | |
3 | # Copyright 2003, 2004, 2005, 2006 Vladimir Prus | |
4 | # Copyright 2005-2007 Mat Marcus | |
5 | # Copyright 2005-2007 Adobe Systems Incorporated | |
6 | # Copyright 2007-2010 Rene Rivera | |
7 | # Distributed under the Boost Software License, Version 1.0. | |
8 | # (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt) | |
9 | ||
10 | # Please see http://article.gmane.org/gmane.comp.lib.boost.build/3389/ | |
11 | # for explanation why it's a separate toolset. | |
12 | ||
13 | import feature : feature ; | |
14 | import toolset : flags ; | |
15 | import type ; | |
16 | import common ; | |
17 | import generators ; | |
18 | import path : basename ; | |
19 | import version ; | |
20 | import property-set ; | |
21 | import regex ; | |
22 | import errors ; | |
23 | ||
24 | ## Use a framework. | |
25 | feature framework : : free ; | |
26 | ||
27 | ## The MacOSX version to compile for, which maps to the SDK to use (sysroot). | |
28 | feature macosx-version : : propagated link-incompatible symmetric optional ; | |
29 | ||
30 | ## The minimal MacOSX version to target. | |
31 | feature macosx-version-min : : propagated optional ; | |
32 | ||
33 | ## A dependency, that is forced to be included in the link. | |
34 | feature force-load : : free dependency incidental ; | |
35 | ||
36 | ############################################################################# | |
37 | ||
38 | _ = " " ; | |
39 | ||
40 | if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ] | |
41 | { | |
42 | .debug-configuration = true ; | |
43 | } | |
44 | ||
45 | feature.extend toolset : darwin ; | |
46 | import gcc ; | |
47 | toolset.inherit-generators darwin : gcc : gcc.mingw.link gcc.mingw.link.dll ; | |
48 | ||
49 | generators.override darwin.prebuilt : builtin.prebuilt ; | |
50 | generators.override darwin.searched-lib-generator : searched-lib-generator ; | |
51 | ||
52 | # Override default do-nothing generators. | |
53 | generators.override darwin.compile.c.pch : pch.default-c-pch-generator ; | |
54 | generators.override darwin.compile.c++.pch : pch.default-cpp-pch-generator ; | |
55 | ||
56 | type.set-generated-target-suffix PCH : <toolset>darwin : gch ; | |
57 | ||
58 | toolset.inherit-rules darwin : gcc : localize ; | |
59 | toolset.inherit-flags darwin : gcc | |
60 | : <runtime-link>static | |
61 | <architecture>arm/<address-model>32 | |
62 | <architecture>arm/<address-model>64 | |
63 | <architecture>arm/<instruction-set> | |
64 | <architecture>x86/<address-model>32 | |
65 | <architecture>x86/<address-model>64 | |
66 | <architecture>x86/<instruction-set> | |
67 | <architecture>power/<address-model>32 | |
68 | <architecture>power/<address-model>64 | |
69 | <architecture>power/<instruction-set> | |
70 | <inlining>full ; | |
71 | ||
72 | # Options: | |
73 | # | |
74 | # <root>PATH | |
75 | # Platform root path. The common autodetection will set this to | |
76 | # "/Developer". And when a command is given it will be set to | |
77 | # the corresponding "*.platform/Developer" directory. | |
78 | # | |
79 | rule init ( version ? : command * : options * : requirement * ) | |
80 | { | |
81 | # First time around, figure what is host OSX version | |
82 | if ! $(.host-osx-version) | |
83 | { | |
84 | .host-osx-version = [ MATCH "^([0-9.]+)" | |
85 | : [ SHELL "/usr/bin/sw_vers -productVersion" ] ] ; | |
86 | if $(.debug-configuration) | |
87 | { | |
88 | ECHO notice\: OSX version on this machine is $(.host-osx-version) ; | |
89 | } | |
90 | } | |
91 | ||
92 | # - The root directory of the tool install. | |
93 | local root = [ feature.get-values <root> : $(options) ] ; | |
94 | ||
95 | # - The bin directory where to find the commands to execute. | |
96 | local bin ; | |
97 | ||
98 | # - The configured compile driver command. | |
99 | local command = [ common.get-invocation-command darwin : g++ : $(command) ] ; | |
100 | ||
101 | # The version as reported by the compiler | |
102 | local real-version ; | |
103 | ||
104 | # - Autodetect the root and bin dir if not given. | |
105 | if $(command) | |
106 | { | |
107 | bin ?= [ common.get-absolute-tool-path $(command[1]) ] ; | |
108 | if $(bin) = "/usr/bin" | |
109 | { | |
110 | root ?= /Developer ; | |
111 | } | |
112 | else | |
113 | { | |
114 | local r = $(bin:D) ; | |
115 | r = $(r:D) ; | |
116 | root ?= $(r) ; | |
117 | } | |
118 | } | |
119 | ||
120 | # - Autodetect the version if not given. | |
121 | if $(command) | |
122 | { | |
123 | # - The 'command' variable can have multiple elements. When calling | |
124 | # the SHELL builtin we need a single string. | |
125 | local command-string = $(command:J=" ") ; | |
126 | real-version = [ MATCH "^([0-9.]+)" | |
127 | : [ SHELL "$(command-string) -dumpversion" ] ] ; | |
128 | version ?= $(real-version) ; | |
129 | } | |
130 | ||
131 | .real-version.$(version) = $(real-version) ; | |
132 | ||
133 | # - Define the condition for this toolset instance. | |
134 | local condition = | |
135 | [ common.check-init-parameters darwin $(requirement) : version $(version) ] ; | |
136 | ||
137 | # - Set the toolset generic common options. | |
138 | common.handle-options darwin : $(condition) : $(command) : $(options) ; | |
139 | ||
140 | real-version = [ regex.split $(real-version) \\. ] ; | |
141 | # - GCC 4.0 and higher in Darwin does not have -fcoalesce-templates. | |
142 | if [ version.version-less $(real-version) : 4 0 ] | |
143 | { | |
144 | flags darwin.compile.c++ OPTIONS $(condition) : -fcoalesce-templates ; | |
145 | } | |
146 | # - GCC 4.2 and higher in Darwin does not have -Wno-long-double. | |
147 | if [ version.version-less $(real-version) : 4 2 ] | |
148 | { | |
149 | flags darwin.compile OPTIONS $(condition) : -Wno-long-double ; | |
150 | } | |
151 | # - GCC on Darwin with -pedantic, suppress unsupported long long warning | |
152 | flags darwin.compile OPTIONS $(condition)/<warnings>pedantic : -Wno-long-long ; | |
153 | ||
154 | # - GCC on El Capitan (10.11) does not support -finline-functions | |
155 | if "10.11.0" <= $(.host-osx-version) | |
156 | { | |
157 | flags darwin.compile OPTIONS $(condition)/<inlining>full : -Wno-inline ; | |
158 | } | |
159 | ||
160 | # - The symbol strip program. | |
161 | local strip ; | |
162 | if <striper> in $(options) | |
163 | { | |
164 | # We can turn off strip by specifying it as empty. In which | |
165 | # case we switch to using the linker to do the strip. | |
166 | flags darwin.link.dll OPTIONS | |
167 | $(condition)/<main-target-type>LIB/<link>shared/<address-model>32/<strip>on : -Wl,-x ; | |
168 | flags darwin.link.dll OPTIONS | |
169 | $(condition)/<main-target-type>LIB/<link>shared/<address-model>/<strip>on : -Wl,-x ; | |
170 | flags darwin.link OPTIONS | |
171 | $(condition)/<main-target-type>EXE/<address-model>32/<strip>on : -s ; | |
172 | flags darwin.link OPTIONS | |
173 | $(condition)/<main-target-type>EXE/<address-model>/<strip>on : -s ; | |
174 | } | |
175 | else | |
176 | { | |
177 | # Otherwise we need to find a strip program to use. And hence | |
178 | # also tell the link action that we need to use a strip | |
179 | # post-process. | |
180 | flags darwin.link NEED_STRIP $(condition)/<strip>on : "" ; | |
181 | strip = | |
182 | [ common.get-invocation-command darwin | |
183 | : strip : [ feature.get-values <striper> : $(options) ] : $(bin) : search-path ] ; | |
184 | flags darwin.link .STRIP $(condition) : $(strip[1]) ; | |
185 | if $(.debug-configuration) | |
186 | { | |
187 | ECHO notice\: using strip for $(condition) at $(strip[1]) ; | |
188 | } | |
189 | } | |
190 | ||
191 | # - The archive builder (libtool is the default as creating | |
192 | # archives in darwin is complicated. | |
193 | local archiver = | |
194 | [ common.get-invocation-command darwin | |
195 | : libtool : [ feature.get-values <archiver> : $(options) ] : $(bin) : search-path ] ; | |
196 | flags darwin.archive .LIBTOOL $(condition) : $(archiver[1]) ; | |
197 | if $(.debug-configuration) | |
198 | { | |
199 | ECHO notice\: using archiver for $(condition) at $(archiver[1]) ; | |
200 | } | |
201 | ||
202 | # - Initialize the SDKs available in the root for this tool. | |
203 | local sdks = [ init-available-sdk-versions $(condition) : $(root) ] ; | |
204 | ||
205 | #~ ECHO --- ; | |
206 | #~ ECHO --- bin :: $(bin) ; | |
207 | #~ ECHO --- root :: $(root) ; | |
208 | #~ ECHO --- version :: $(version) ; | |
209 | #~ ECHO --- condition :: $(condition) ; | |
210 | #~ ECHO --- strip :: $(strip) ; | |
211 | #~ ECHO --- archiver :: $(archiver) ; | |
212 | #~ ECHO --- sdks :: $(sdks) ; | |
213 | #~ ECHO --- ; | |
214 | #~ EXIT ; | |
215 | } | |
216 | ||
217 | # Add and set options for a discovered SDK version. | |
218 | local rule init-sdk ( condition * : root ? : version + : version-feature ? ) | |
219 | { | |
220 | local rule version-to-feature ( version + ) | |
221 | { | |
222 | switch $(version[1]) | |
223 | { | |
224 | case appletv* : | |
225 | { | |
226 | return $(version[1])-$(version[2-]:J=.) ; | |
227 | } | |
228 | case iphone* : | |
229 | { | |
230 | return $(version[1])-$(version[2-]:J=.) ; | |
231 | } | |
232 | case mac* : | |
233 | { | |
234 | return $(version[2-]:J=.) ; | |
235 | } | |
236 | case * : | |
237 | { | |
238 | return $(version:J=.) ; | |
239 | } | |
240 | } | |
241 | } | |
242 | ||
243 | if $(version-feature) | |
244 | { | |
245 | if $(.debug-configuration) | |
246 | { | |
247 | ECHO notice\: available sdk for $(condition)/<macosx-version>$(version-feature) at $(root) ; | |
248 | } | |
249 | ||
250 | # Add the version to the features for specifying them. | |
251 | if ! $(version-feature) in [ feature.values macosx-version ] | |
252 | { | |
253 | feature.extend macosx-version : $(version-feature) ; | |
254 | } | |
255 | if ! $(version-feature) in [ feature.values macosx-version-min ] | |
256 | { | |
257 | feature.extend macosx-version-min : $(version-feature) ; | |
258 | } | |
259 | ||
260 | # Set the flags the version needs to compile with, first | |
261 | # generic options. | |
262 | flags darwin.compile OPTIONS $(condition)/<macosx-version>$(version-feature) | |
263 | : -isysroot $(root) ; | |
264 | flags darwin.link OPTIONS $(condition)/<macosx-version>$(version-feature) | |
265 | : -isysroot $(root) ; | |
266 | ||
267 | # Then device variation options. | |
268 | switch $(version[1]) | |
269 | { | |
270 | case appletvsim* : | |
271 | { | |
272 | local N = $(version[2]) ; | |
273 | if ! $(version[3]) { N += 00 ; } | |
274 | else if [ regex.match (..) : $(version[3]) ] { N += $(version[3]) ; } | |
275 | else { N += 0$(version[3]) ; } | |
276 | if ! $(version[4]) { N += 00 ; } | |
277 | else if [ regex.match (..) : $(version[4]) ] { N += $(version[4]) ; } | |
278 | else { N += 0$(version[4]) ; } | |
279 | N = $(N:J=) ; | |
280 | flags darwin.compile OPTIONS <macosx-version-min>$(version-feature) | |
281 | : -D__IPHONE_OS_VERSION_MIN_REQUIRED=$(N) ; | |
282 | flags darwin.link OPTIONS <macosx-version-min>$(version-feature) | |
283 | : -D__IPHONE_OS_VERSION_MIN_REQUIRED=$(N) ; | |
284 | } | |
285 | ||
286 | case appletv* : | |
287 | { | |
288 | flags darwin.compile OPTIONS <macosx-version-min>$(version-feature) | |
289 | : -mtvos-version-min=$(version[2-]:J=.) ; | |
290 | flags darwin.link OPTIONS <macosx-version-min>$(version-feature) | |
291 | : -mtvos-version-min=$(version[2-]:J=.) ; | |
292 | } | |
293 | ||
294 | case iphonesim* : | |
295 | { | |
296 | local N = $(version[2]) ; | |
297 | if ! $(version[3]) { N += 00 ; } | |
298 | else if [ regex.match (..) : $(version[3]) ] { N += $(version[3]) ; } | |
299 | else { N += 0$(version[3]) ; } | |
300 | if ! $(version[4]) { N += 00 ; } | |
301 | else if [ regex.match (..) : $(version[4]) ] { N += $(version[4]) ; } | |
302 | else { N += 0$(version[4]) ; } | |
303 | N = $(N:J=) ; | |
304 | flags darwin.compile OPTIONS <macosx-version-min>$(version-feature) | |
305 | : -D__IPHONE_OS_VERSION_MIN_REQUIRED=$(N) ; | |
306 | flags darwin.link OPTIONS <macosx-version-min>$(version-feature) | |
307 | : -D__IPHONE_OS_VERSION_MIN_REQUIRED=$(N) ; | |
308 | } | |
309 | ||
310 | case iphone* : | |
311 | { | |
312 | flags darwin.compile OPTIONS <macosx-version-min>$(version-feature) | |
313 | : -miphoneos-version-min=$(version[2-]:J=.) ; | |
314 | flags darwin.link OPTIONS <macosx-version-min>$(version-feature) | |
315 | : -miphoneos-version-min=$(version[2-]:J=.) ; | |
316 | } | |
317 | ||
318 | case mac* : | |
319 | { | |
320 | flags darwin.compile OPTIONS <macosx-version-min>$(version-feature) | |
321 | : -mmacosx-version-min=$(version[2-]:J=.) ; | |
322 | flags darwin.link OPTIONS <macosx-version-min>$(version-feature) | |
323 | : -mmacosx-version-min=$(version[2-]:J=.) ; | |
324 | } | |
325 | } | |
326 | ||
327 | if $(version[3]) > 0 | |
328 | { | |
329 | # We have a minor version of an SDK. We want to set up | |
330 | # previous minor versions, plus the current minor version. | |
331 | # So we recurse to set up the previous minor versions, up to | |
332 | # the current version. | |
333 | local minor-minus-1 = [ CALC $(version[3]) - 1 ] ; | |
334 | return | |
335 | [ init-sdk $(condition) : $(root) | |
336 | : $(version[1-2]) $(minor-minus-1) : [ version-to-feature $(version[1-2]) $(minor-minus-1) ] ] | |
337 | $(version-feature) ; | |
338 | } | |
339 | else | |
340 | { | |
341 | return $(version-feature) ; | |
342 | } | |
343 | } | |
344 | else if $(version[4]) | |
345 | { | |
346 | # We have a patch version of an SDK. We want to set up | |
347 | # both the specific patch version, and the minor version. | |
348 | # So we recurse to set up the patch version. Plus the minor version. | |
349 | return | |
350 | [ init-sdk $(condition) : $(root) | |
351 | : $(version[1-3]) : [ version-to-feature $(version[1-3]) ] ] | |
352 | [ init-sdk $(condition) : $(root) | |
353 | : $(version) : [ version-to-feature $(version) ] ] ; | |
354 | } | |
355 | else | |
356 | { | |
357 | # Yes, this is intentionally recursive. | |
358 | return | |
359 | [ init-sdk $(condition) : $(root) | |
360 | : $(version) : [ version-to-feature $(version) ] ] ; | |
361 | } | |
362 | } | |
363 | ||
364 | # Determine the MacOSX SDK versions installed and their locations. | |
365 | local rule init-available-sdk-versions ( condition * : root ? ) | |
366 | { | |
367 | root ?= /Developer ; | |
368 | local sdks-root = $(root)/SDKs ; | |
369 | local sdks = [ GLOB $(sdks-root) : MacOSX*.sdk AppleTVOS*.sdk AppleTVSimulator*.sdk iPhoneOS*.sdk iPhoneSimulator*.sdk ] ; | |
370 | local result ; | |
371 | for local sdk in $(sdks) | |
372 | { | |
373 | local sdk-match = [ MATCH "([^0-9]+)([0-9]+)[.]([0-9x]+)[.]?([0-9x]+)?" : $(sdk:D=) ] ; | |
374 | local sdk-platform = $(sdk-match[1]:L) ; | |
375 | local sdk-version = $(sdk-match[2-]) ; | |
376 | if $(sdk-version) | |
377 | { | |
378 | switch $(sdk-platform) | |
379 | { | |
380 | case macosx : | |
381 | { | |
382 | sdk-version = mac $(sdk-version) ; | |
383 | } | |
384 | case appletvos : | |
385 | { | |
386 | sdk-version = appletv $(sdk-version) ; | |
387 | } | |
388 | case appletvsimulator : | |
389 | { | |
390 | sdk-version = appletvsim $(sdk-version) ; | |
391 | } | |
392 | case iphoneos : | |
393 | { | |
394 | sdk-version = iphone $(sdk-version) ; | |
395 | } | |
396 | case iphonesimulator : | |
397 | { | |
398 | sdk-version = iphonesim $(sdk-version) ; | |
399 | } | |
400 | case * : | |
401 | { | |
402 | sdk-version = $(sdk-version:J=-) ; | |
403 | } | |
404 | } | |
405 | result += [ init-sdk $(condition) : $(sdk) : $(sdk-version) ] ; | |
406 | } | |
407 | } | |
408 | return $(result) ; | |
409 | } | |
410 | ||
411 | rule compile.m ( targets * : sources * : properties * ) | |
412 | { | |
413 | LANG on $(<) = "-x objective-c" ; | |
414 | gcc.set-fpic-options $(targets) : $(sources) : $(properties) ; | |
415 | } | |
416 | ||
417 | actions compile.m | |
418 | { | |
419 | "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" | |
420 | } | |
421 | ||
422 | rule compile.mm ( targets * : sources * : properties * ) | |
423 | { | |
424 | LANG on $(<) = "-x objective-c++" ; | |
425 | gcc.set-fpic-options $(targets) : $(sources) : $(properties) ; | |
426 | } | |
427 | ||
428 | actions compile.mm | |
429 | { | |
430 | "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" | |
431 | } | |
432 | ||
433 | # Set the max header padding to allow renaming of libs for installation. | |
434 | flags darwin.link.dll OPTIONS : -headerpad_max_install_names ; | |
435 | ||
436 | # To link the static runtime we need to link to all the core runtime libraries. | |
437 | flags darwin.link OPTIONS <runtime-link>static | |
438 | : -nodefaultlibs -shared-libgcc -lstdc++-static -lgcc_eh -lgcc -lSystem ; | |
439 | ||
440 | # Strip as much as possible when optimizing. | |
441 | flags darwin.link OPTIONS <optimization>speed : -Wl,-dead_strip -no_dead_strip_inits_and_terms ; | |
442 | flags darwin.link OPTIONS <optimization>space : -Wl,-dead_strip -no_dead_strip_inits_and_terms ; | |
443 | ||
444 | # Dynamic/shared linking. | |
445 | flags darwin.compile OPTIONS <link>shared : -dynamic ; | |
446 | ||
447 | # Misc options. | |
448 | flags darwin.compile OPTIONS : -gdwarf-2 -fexceptions ; | |
449 | #~ flags darwin.link OPTIONS : -fexceptions ; | |
450 | ||
451 | # Add the framework names to use. | |
452 | flags darwin.link FRAMEWORK <framework> ; | |
453 | ||
454 | # | |
455 | flags darwin.link FORCE_LOAD <force-load> ; | |
456 | ||
457 | # This is flag is useful for debugging the link step | |
458 | # uncomment to see what libtool is doing under the hood | |
459 | #~ flags darwin.link.dll OPTIONS : -Wl,-v ; | |
460 | ||
461 | # set up the -F option to include the paths to any frameworks used. | |
462 | local rule prepare-framework-path ( target + ) | |
463 | { | |
464 | # The -framework option only takes basename of the framework. | |
465 | # The -F option specifies the directories where a framework | |
466 | # is searched for. So, if we find <framework> feature | |
467 | # with some path, we need to generate property -F option. | |
468 | local framework-paths = [ on $(target) return $(FRAMEWORK:D) ] ; | |
469 | ||
470 | # Be sure to generate no -F if there's no path. | |
471 | for local framework-path in $(framework-paths) | |
472 | { | |
473 | if $(framework-path) != "" | |
474 | { | |
475 | FRAMEWORK_PATH on $(target) += -F$(framework-path) ; | |
476 | } | |
477 | } | |
478 | } | |
479 | ||
480 | rule link ( targets * : sources * : properties * ) | |
481 | { | |
482 | DEPENDS $(targets) : [ on $(targets) return $(FORCE_LOAD) ] ; | |
483 | prepare-framework-path $(<) ; | |
484 | } | |
485 | ||
486 | # Note that using strip without any options was reported to result in broken | |
487 | # binaries, at least on OS X 10.5.5, see: | |
488 | # http://svn.boost.org/trac/boost/ticket/2347 | |
489 | # So we pass -S -x. | |
490 | actions link bind LIBRARIES FORCE_LOAD | |
491 | { | |
492 | "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -o "$(<)" "$(>)" -Wl,-force_load$(_)"$(FORCE_LOAD)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(FRAMEWORK_PATH) -framework$(_)$(FRAMEWORK:D=:S=) $(OPTIONS) $(USER_OPTIONS) | |
493 | $(NEED_STRIP)"$(.STRIP)" $(NEED_STRIP)-S $(NEED_STRIP)-x $(NEED_STRIP)"$(<)" | |
494 | } | |
495 | ||
496 | rule link.dll ( targets * : sources * : properties * ) | |
497 | { | |
498 | prepare-framework-path $(<) ; | |
499 | } | |
500 | ||
501 | actions link.dll bind LIBRARIES | |
502 | { | |
503 | "$(CONFIG_COMMAND)" -dynamiclib -Wl,-single_module -install_name "$(<:B)$(<:S)" -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(FRAMEWORK_PATH) -framework$(_)$(FRAMEWORK:D=:S=) $(OPTIONS) $(USER_OPTIONS) | |
504 | } | |
505 | ||
506 | # We use libtool instead of ar to support universal binary linking | |
507 | # TODO: Find a way to use the underlying tools, i.e. lipo, to do this. | |
508 | actions piecemeal archive | |
509 | { | |
510 | "$(.LIBTOOL)" -static -o "$(<:T)" $(ARFLAGS) "$(>:T)" | |
511 | } | |
512 | ||
513 | # This is a temporary solution for doing combined architecture builds on macOS. | |
514 | flags darwin | |
515 | OPTIONS <target-os>darwin/<architecture>arm+x86/<address-model>64 | |
516 | : "-arch arm64" "-arch x86_64" ; |