1 | # -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:filetype=tcl:et:sw=4:ts=4:sts=4 |
---|
2 | # |
---|
3 | # Copyright (c) 2007 - 2015 The MacPorts Project |
---|
4 | # Copyright (c) 2007 Markus W. Weissmann <mww@macports.org> |
---|
5 | # Copyright (c) 2002 - 2003 Apple Inc. |
---|
6 | # All rights reserved. |
---|
7 | # |
---|
8 | # Redistribution and use in source and binary forms, with or without |
---|
9 | # modification, are permitted provided that the following conditions |
---|
10 | # are met: |
---|
11 | # 1. Redistributions of source code must retain the above copyright |
---|
12 | # notice, this list of conditions and the following disclaimer. |
---|
13 | # 2. Redistributions in binary form must reproduce the above copyright |
---|
14 | # notice, this list of conditions and the following disclaimer in the |
---|
15 | # documentation and/or other materials provided with the distribution. |
---|
16 | # 3. Neither the name of Apple Inc. nor the names of its contributors |
---|
17 | # may be used to endorse or promote products derived from this software |
---|
18 | # without specific prior written permission. |
---|
19 | # |
---|
20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
---|
21 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
22 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
23 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
---|
24 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
---|
25 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
---|
26 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
---|
27 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
---|
28 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
---|
29 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
---|
30 | # POSSIBILITY OF SUCH DAMAGE. |
---|
31 | # |
---|
32 | |
---|
33 | package provide portconfigure 1.0 |
---|
34 | package require portutil 1.0 |
---|
35 | |
---|
36 | set org.macports.configure [target_new org.macports.configure portconfigure::configure_main] |
---|
37 | target_provides ${org.macports.configure} configure |
---|
38 | target_requires ${org.macports.configure} main fetch checksum extract patch |
---|
39 | target_prerun ${org.macports.configure} portconfigure::configure_start |
---|
40 | |
---|
41 | namespace eval portconfigure { |
---|
42 | } |
---|
43 | |
---|
44 | |
---|
45 | # ********** BEGIN C++ / OBJECTIVE-C++ ********** |
---|
46 | |
---|
47 | options configure.cxx \ |
---|
48 | configure.cxx_archflags \ |
---|
49 | configure.cxx_stdlib \ |
---|
50 | configure.cxxflags \ |
---|
51 | configure.objcxx \ |
---|
52 | configure.objcxx_archflags \ |
---|
53 | configure.objcxxflags \ |
---|
54 | configure.universal_cxxflags \ |
---|
55 | configure.universal_objcxxflags |
---|
56 | |
---|
57 | default configure.cxx {[portconfigure::configure_get_compiler cxx]} |
---|
58 | default configure.cxx_archflags {[portconfigure::configure_get_archflags cxx]} |
---|
59 | default configure.cxx_stdlib {$cxx_stdlib} |
---|
60 | default configure.cxxflags \ |
---|
61 | {[portconfigure::construct_cxxflags ${configure.optflags}]} |
---|
62 | default configure.objcxx {[portconfigure::configure_get_compiler objcxx]} |
---|
63 | default configure.objcxx_archflags {[portconfigure::configure_get_archflags objcxx]} |
---|
64 | # No current reason for OBJCXXFLAGS to differ from CXXFLAGS. |
---|
65 | default configure.objcxxflags {${configure.cxxflags}} |
---|
66 | default configure.universal_cxxflags {[portconfigure::configure_get_universal_cflags]} |
---|
67 | default configure.universal_objcxxflags {${configure.universal_cxxflags}} |
---|
68 | |
---|
69 | # Don't let Portfiles trash "-stdlib"; if they want to remove it, they |
---|
70 | # should clear configure.cxx_stdlib. |
---|
71 | option_proc configure.cxxflags portconfigure::stdlib_trace |
---|
72 | option_proc configure.objcxxflags portconfigure::stdlib_trace |
---|
73 | |
---|
74 | proc portconfigure::should_add_stdlib {} { |
---|
75 | set has_stdlib [expr {[option configure.cxx_stdlib] ne ""}] |
---|
76 | set is_clang [string match *clang* [option configure.cxx]] |
---|
77 | return [expr {$has_stdlib && $is_clang}] |
---|
78 | } |
---|
79 | proc portconfigure::construct_cxxflags {flags} { |
---|
80 | if {[portconfigure::should_add_stdlib]} { |
---|
81 | lappend flags -stdlib=[option configure.cxx_stdlib] |
---|
82 | } |
---|
83 | return $flags |
---|
84 | } |
---|
85 | proc portconfigure::stdlib_trace {opt action args} { |
---|
86 | foreach flag [lsearch -all -inline [option $opt] -stdlib=*] { |
---|
87 | $opt-delete $flag |
---|
88 | } |
---|
89 | if {$action eq "read" && [portconfigure::should_add_stdlib]} { |
---|
90 | $opt-append -stdlib=[option configure.cxx_stdlib] |
---|
91 | } |
---|
92 | return |
---|
93 | } |
---|
94 | |
---|
95 | # ********** END C++ / OBJECTIVE-C++ ********** |
---|
96 | |
---|
97 | |
---|
98 | # define options |
---|
99 | commands configure autoreconf automake autoconf xmkmf |
---|
100 | # defaults |
---|
101 | default configure.env "" |
---|
102 | default configure.pre_args {--prefix=${prefix}} |
---|
103 | default configure.cmd ./configure |
---|
104 | default configure.nice {${buildnicevalue}} |
---|
105 | default configure.dir {${worksrcpath}} |
---|
106 | default autoreconf.dir {${worksrcpath}} |
---|
107 | default autoreconf.args {{--install --verbose}} |
---|
108 | default autoconf.dir {${worksrcpath}} |
---|
109 | default autoconf.args {--verbose} |
---|
110 | default automake.dir {${worksrcpath}} |
---|
111 | default automake.args {--verbose} |
---|
112 | default xmkmf.cmd xmkmf |
---|
113 | default xmkmf.dir {${worksrcpath}} |
---|
114 | default use_configure yes |
---|
115 | |
---|
116 | option_proc use_autoreconf portconfigure::set_configure_type |
---|
117 | option_proc use_automake portconfigure::set_configure_type |
---|
118 | option_proc use_autoconf portconfigure::set_configure_type |
---|
119 | option_proc use_xmkmf portconfigure::set_configure_type |
---|
120 | |
---|
121 | option_proc autoreconf.cmd portconfigure::set_configure_type |
---|
122 | option_proc automake.cmd portconfigure::set_configure_type |
---|
123 | option_proc autoconf.cmd portconfigure::set_configure_type |
---|
124 | option_proc xmkmf.cmd portconfigure::set_configure_type |
---|
125 | |
---|
126 | ## |
---|
127 | # Local helper proc |
---|
128 | proc portconfigure::add_build_dep { type dep } { |
---|
129 | global ${type}.cmd option_defaults |
---|
130 | |
---|
131 | if {![info exists ${type}.cmd] || ( |
---|
132 | ([info exists option_defaults(${type}.cmd)] && [set ${type}.cmd] eq $option_defaults(${type}.cmd)) || |
---|
133 | (![info exists option_defaults(${type}.cmd)] && [set ${type}.cmd] eq ${type}) |
---|
134 | )} { |
---|
135 | # Add dependencies if they are not already in the list |
---|
136 | depends_build-delete {*}$dep |
---|
137 | depends_build-append {*}$dep |
---|
138 | } |
---|
139 | } |
---|
140 | |
---|
141 | ## |
---|
142 | # Adds dependencies for the binaries which will be called, but only if it is |
---|
143 | # the default. If .cmd was overwritten the port has to care for deps itself. |
---|
144 | proc portconfigure::set_configure_type {option action args} { |
---|
145 | global autoreconf.cmd automake.cmd autoconf.cmd xmkmf.cmd |
---|
146 | |
---|
147 | array set configure_map { |
---|
148 | autoconf {port:autoconf port:automake port:libtool} |
---|
149 | xmkmf port:imake |
---|
150 | } |
---|
151 | |
---|
152 | if {$action eq "set"} { |
---|
153 | switch $option { |
---|
154 | autoreconf.cmd - |
---|
155 | automake.cmd - |
---|
156 | autoconf.cmd { |
---|
157 | depends_build-delete {*}$configure_map(autoconf) |
---|
158 | } |
---|
159 | xmkmf.cmd { |
---|
160 | depends_build-delete {*}$configure_map(xmkmf) |
---|
161 | } |
---|
162 | use_xmkmf { |
---|
163 | if {[tbool args]} { |
---|
164 | depends_build-append {*}$configure_map(xmkmf) |
---|
165 | } |
---|
166 | } |
---|
167 | default { |
---|
168 | # strip "use_" |
---|
169 | set type [string range $option 4 end] |
---|
170 | if {[tbool args]} { |
---|
171 | add_build_dep $type $configure_map(autoconf) |
---|
172 | } |
---|
173 | } |
---|
174 | } |
---|
175 | } |
---|
176 | } |
---|
177 | |
---|
178 | options configure.asroot |
---|
179 | default configure.asroot no |
---|
180 | |
---|
181 | # Configure special environment variables. |
---|
182 | # We could have m32/m64/march/mtune be global configurable at some point. |
---|
183 | options configure.m32 configure.m64 configure.march configure.mtune |
---|
184 | default configure.march {} |
---|
185 | default configure.mtune {} |
---|
186 | # We could have debug/optimizations be global configurable at some point. |
---|
187 | options configure.optflags \ |
---|
188 | configure.cflags \ |
---|
189 | configure.objcflags \ |
---|
190 | configure.cppflags configure.ldflags configure.libs \ |
---|
191 | configure.fflags configure.f90flags configure.fcflags \ |
---|
192 | configure.classpath |
---|
193 | # compiler flags section |
---|
194 | default configure.optflags {-Os} |
---|
195 | default configure.cflags {${configure.optflags}} |
---|
196 | default configure.objcflags {${configure.optflags}} |
---|
197 | default configure.cppflags {-I${prefix}/include} |
---|
198 | default configure.ldflags {"-L${prefix}/lib -Wl,-headerpad_max_install_names"} |
---|
199 | default configure.libs {} |
---|
200 | default configure.fflags {${configure.optflags}} |
---|
201 | default configure.f90flags {${configure.optflags}} |
---|
202 | default configure.fcflags {${configure.optflags}} |
---|
203 | default configure.classpath {} |
---|
204 | |
---|
205 | # tools section |
---|
206 | options configure.perl configure.python configure.ruby \ |
---|
207 | configure.install configure.awk configure.bison \ |
---|
208 | configure.pkg_config configure.pkg_config_path |
---|
209 | default configure.perl {} |
---|
210 | default configure.python {} |
---|
211 | default configure.ruby {} |
---|
212 | default configure.install {${portutil::autoconf::install_command}} |
---|
213 | default configure.awk {} |
---|
214 | default configure.bison {} |
---|
215 | default configure.pkg_config {} |
---|
216 | default configure.pkg_config_path {} |
---|
217 | |
---|
218 | options configure.build_arch configure.ld_archflags \ |
---|
219 | configure.sdk_version configure.sdkroot |
---|
220 | default configure.build_arch {[portconfigure::choose_supported_archs ${build_arch}]} |
---|
221 | default configure.ld_archflags {[portconfigure::configure_get_ld_archflags]} |
---|
222 | default configure.sdk_version {$macosx_sdk_version} |
---|
223 | default configure.sdkroot {[portconfigure::configure_get_sdkroot ${configure.sdk_version}]} |
---|
224 | foreach tool {cc objc f77 f90 fc} { |
---|
225 | options configure.${tool}_archflags |
---|
226 | default configure.${tool}_archflags "\[portconfigure::configure_get_archflags $tool\]" |
---|
227 | } |
---|
228 | |
---|
229 | options configure.universal_archs configure.universal_args \ |
---|
230 | configure.universal_cflags \ |
---|
231 | configure.universal_objcflags \ |
---|
232 | configure.universal_cppflags configure.universal_ldflags |
---|
233 | default configure.universal_archs {[portconfigure::choose_supported_archs ${universal_archs}]} |
---|
234 | default configure.universal_args {--disable-dependency-tracking} |
---|
235 | default configure.universal_cflags {[portconfigure::configure_get_universal_cflags]} |
---|
236 | default configure.universal_objcflags {${configure.universal_cflags}} |
---|
237 | default configure.universal_cppflags {} |
---|
238 | default configure.universal_ldflags {[portconfigure::configure_get_universal_ldflags]} |
---|
239 | |
---|
240 | # Select a distinct compiler (C, C preprocessor, C++) |
---|
241 | options configure.ccache configure.distcc configure.pipe configure.cc \ |
---|
242 | configure.cpp configure.objc configure.f77 \ |
---|
243 | configure.f90 configure.fc configure.javac configure.compiler \ |
---|
244 | compiler.blacklist compiler.whitelist compiler.fallback |
---|
245 | default configure.ccache {${configureccache}} |
---|
246 | default configure.distcc {${configuredistcc}} |
---|
247 | default configure.pipe {${configurepipe}} |
---|
248 | foreach tool {cc objc cpp f77 f90 fc javac} { |
---|
249 | default configure.$tool "\[portconfigure::configure_get_compiler $tool\]" |
---|
250 | } |
---|
251 | default configure.compiler {[portconfigure::configure_get_default_compiler]} |
---|
252 | default compiler.fallback {[portconfigure::get_compiler_fallback]} |
---|
253 | default compiler.blacklist {} |
---|
254 | default compiler.whitelist {} |
---|
255 | |
---|
256 | set_ui_prefix |
---|
257 | |
---|
258 | proc portconfigure::configure_start {args} { |
---|
259 | global UI_PREFIX |
---|
260 | |
---|
261 | ui_notice "$UI_PREFIX [format [msgcat::mc "Configuring %s"] [option subport]]" |
---|
262 | |
---|
263 | set compiler [option configure.compiler] |
---|
264 | set valid_compilers { |
---|
265 | {^apple-gcc-(4\.[02])$} {MacPorts Apple GCC %s} |
---|
266 | {^cc$} {System cc} |
---|
267 | {^clang$} {Xcode Clang} |
---|
268 | {^gcc$} {System GCC} |
---|
269 | {^gcc-(3\.3|4\.[02])$} {Xcode GCC %s} |
---|
270 | {^llvm-gcc-4\.2$} {Xcode LLVM-GCC 4.2} |
---|
271 | {^macports-clang$} {MacPorts Clang (port select)} |
---|
272 | {^macports-clang-(\d+\.\d+)$} {MacPorts Clang %s} |
---|
273 | {^macports-dragonegg-(\d+\.\d+)$} {MacPorts DragonEgg %s} |
---|
274 | {^macports-dragonegg-(\d+\.\d+)-gcc-(\d+\.\d+)$} |
---|
275 | {MacPorts DragonEgg %s with GCC %s} |
---|
276 | {^macports-gcc$} {MacPorts GCC (port select)} |
---|
277 | {^macports-gcc-(\d+(?:\.\d+)?)$} {MacPorts GCC %s} |
---|
278 | {^macports-llvm-gcc-4\.2$} {MacPorts LLVM-GCC 4.2} |
---|
279 | } |
---|
280 | foreach {re fmt} $valid_compilers { |
---|
281 | if {[set matches [regexp -inline $re $compiler]] ne ""} { |
---|
282 | set compiler_name [format $fmt {*}[lrange $matches 1 end]] |
---|
283 | break |
---|
284 | } |
---|
285 | } |
---|
286 | if {![info exists compiler_name]} { |
---|
287 | return -code error "Invalid value for configure.compiler: $compiler" |
---|
288 | } |
---|
289 | ui_debug "Preferred compilers: [option compiler.fallback]" |
---|
290 | ui_debug "Using compiler '$compiler_name'" |
---|
291 | |
---|
292 | # Additional ccache directory setup |
---|
293 | global configure.ccache ccache_dir ccache_size macportsuser |
---|
294 | if {${configure.ccache}} { |
---|
295 | # Create ccache directory with correct permissions with root privileges |
---|
296 | elevateToRoot "configure ccache" |
---|
297 | if {[catch { |
---|
298 | file mkdir ${ccache_dir} |
---|
299 | file attributes ${ccache_dir} -owner ${macportsuser} -permissions 0755 |
---|
300 | } result]} { |
---|
301 | ui_warn "ccache_dir ${ccache_dir} could not be created; disabling ccache: $result" |
---|
302 | set configure.ccache no |
---|
303 | } |
---|
304 | dropPrivileges |
---|
305 | |
---|
306 | # Initialize ccache directory with the given maximum size |
---|
307 | if {${configure.ccache}} { |
---|
308 | if {[catch { |
---|
309 | exec ccache -M ${ccache_size} >/dev/null |
---|
310 | } result]} { |
---|
311 | ui_warn "ccache_dir ${ccache_dir} could not be initialized; disabling ccache: $result" |
---|
312 | set configure.ccache no |
---|
313 | } |
---|
314 | } |
---|
315 | } |
---|
316 | } |
---|
317 | |
---|
318 | # internal function to choose the default configure.build_arch and |
---|
319 | # configure.universal_archs based on supported_archs and build_arch or |
---|
320 | # universal_archs |
---|
321 | proc portconfigure::choose_supported_archs {archs} { |
---|
322 | global supported_archs |
---|
323 | if {$supported_archs eq ""} { |
---|
324 | return $archs |
---|
325 | } |
---|
326 | set ret {} |
---|
327 | foreach arch $archs { |
---|
328 | if {$arch in $supported_archs} { |
---|
329 | set add_arch $arch |
---|
330 | } elseif {$arch eq "x86_64" && "i386" in $supported_archs} { |
---|
331 | set add_arch "i386" |
---|
332 | } elseif {$arch eq "ppc64" && "ppc" in $supported_archs} { |
---|
333 | set add_arch "ppc" |
---|
334 | } else { |
---|
335 | continue |
---|
336 | } |
---|
337 | if {$add_arch ni $ret} { |
---|
338 | lappend ret $add_arch |
---|
339 | } |
---|
340 | } |
---|
341 | return $ret |
---|
342 | } |
---|
343 | |
---|
344 | # internal function to determine the compiler flags to select an arch |
---|
345 | proc portconfigure::configure_get_archflags {tool} { |
---|
346 | global configure.build_arch configure.m32 configure.m64 configure.compiler |
---|
347 | set flags "" |
---|
348 | if {[tbool configure.m64]} { |
---|
349 | set flags "-m64" |
---|
350 | } elseif {[tbool configure.m32]} { |
---|
351 | set flags "-m32" |
---|
352 | } elseif {${configure.build_arch} ne ""} { |
---|
353 | if {[arch_flag_supported ${configure.compiler}] && |
---|
354 | [regexp {^(?:cc|cxx|objc|objcxx)$} $tool] |
---|
355 | } then { |
---|
356 | set flags "-arch ${configure.build_arch}" |
---|
357 | } elseif {${configure.build_arch} eq "x86_64" || ${configure.build_arch} eq "ppc64"} { |
---|
358 | set flags "-m64" |
---|
359 | } elseif {${configure.compiler} ne "gcc-3.3"} { |
---|
360 | set flags "-m32" |
---|
361 | } |
---|
362 | } |
---|
363 | return $flags |
---|
364 | } |
---|
365 | |
---|
366 | # internal function to determine the ld flags to select an arch |
---|
367 | # Unfortunately there's no consistent way to do this when the compiler |
---|
368 | # doesn't support -arch, because it could be used to link rather than using |
---|
369 | # ld directly. So we punt and let portfiles deal with that case. |
---|
370 | proc portconfigure::configure_get_ld_archflags {} { |
---|
371 | global configure.build_arch configure.compiler |
---|
372 | if {${configure.build_arch} ne "" && [arch_flag_supported ${configure.compiler}]} { |
---|
373 | return "-arch ${configure.build_arch}" |
---|
374 | } else { |
---|
375 | return "" |
---|
376 | } |
---|
377 | } |
---|
378 | |
---|
379 | proc portconfigure::configure_get_sdkroot {sdk_version} { |
---|
380 | global developer_dir macosx_version xcodeversion os.arch os.platform |
---|
381 | if {${os.platform} eq "darwin" && ($sdk_version ne $macosx_version |
---|
382 | || (${os.arch} eq "powerpc" && $macosx_version eq "10.4" && [variant_exists universal] && [variant_isset universal]))} { |
---|
383 | if {[vercmp $xcodeversion 4.3] < 0} { |
---|
384 | set sdks_dir ${developer_dir}/SDKs |
---|
385 | } else { |
---|
386 | set sdks_dir ${developer_dir}/Platforms/MacOSX.platform/Developer/SDKs |
---|
387 | } |
---|
388 | if {$sdk_version eq "10.4"} { |
---|
389 | set sdk ${sdks_dir}/MacOSX10.4u.sdk |
---|
390 | } else { |
---|
391 | set sdk ${sdks_dir}/MacOSX${sdk_version}.sdk |
---|
392 | } |
---|
393 | if {[file exists $sdk]} { |
---|
394 | return $sdk |
---|
395 | } |
---|
396 | } |
---|
397 | return {} |
---|
398 | } |
---|
399 | |
---|
400 | # internal function to determine the "-arch xy" flags for the compiler |
---|
401 | proc portconfigure::configure_get_universal_archflags {} { |
---|
402 | global configure.universal_archs |
---|
403 | set flags "" |
---|
404 | foreach arch ${configure.universal_archs} { |
---|
405 | if {$flags eq ""} { |
---|
406 | set flags "-arch $arch" |
---|
407 | } else { |
---|
408 | append flags " -arch $arch" |
---|
409 | } |
---|
410 | } |
---|
411 | return $flags |
---|
412 | } |
---|
413 | |
---|
414 | # internal function to determine the CFLAGS for the compiler |
---|
415 | proc portconfigure::configure_get_universal_cflags {} { |
---|
416 | return [configure_get_universal_archflags] |
---|
417 | } |
---|
418 | |
---|
419 | # internal function to determine the LDFLAGS for the compiler |
---|
420 | proc portconfigure::configure_get_universal_ldflags {} { |
---|
421 | return [configure_get_universal_archflags] |
---|
422 | } |
---|
423 | |
---|
424 | # internal proc to determine if the compiler supports -arch |
---|
425 | proc portconfigure::arch_flag_supported {compiler} { |
---|
426 | return [regexp {^gcc-4|llvm|apple|clang} $compiler] |
---|
427 | } |
---|
428 | |
---|
429 | proc portconfigure::compiler_port_name {compiler} { |
---|
430 | set valid_compiler_ports { |
---|
431 | {^apple-gcc-(\d+)\.(\d+)$} {apple-gcc%s%s} |
---|
432 | {^macports-clang-(\d+\.\d+)$} {clang-%s} |
---|
433 | {^macports-dragonegg-(\d+\.\d+)(-gcc-\d+\.\d+)?$} {dragonegg-%s%s} |
---|
434 | {^macports-(llvm-)?gcc-(\d+)(?:\.(\d+))?$} {%sgcc%s%s} |
---|
435 | } |
---|
436 | foreach {re fmt} $valid_compiler_ports { |
---|
437 | if {[set matches [regexp -inline $re $compiler]] ne ""} { |
---|
438 | return [format $fmt {*}[lrange $matches 1 end]] |
---|
439 | } |
---|
440 | } |
---|
441 | return {} |
---|
442 | } |
---|
443 | |
---|
444 | proc portconfigure::compiler_is_port {compiler} { |
---|
445 | return [expr {[portconfigure::compiler_port_name ${compiler}] ne ""}] |
---|
446 | } |
---|
447 | |
---|
448 | # internal function to determine the default compiler |
---|
449 | proc portconfigure::configure_get_default_compiler {} { |
---|
450 | if {[option compiler.whitelist] ne ""} { |
---|
451 | set search_list [option compiler.whitelist] |
---|
452 | } else { |
---|
453 | set search_list [option compiler.fallback] |
---|
454 | } |
---|
455 | foreach compiler $search_list { |
---|
456 | set allowed yes |
---|
457 | foreach pattern [option compiler.blacklist] { |
---|
458 | if {[string match $pattern $compiler]} { |
---|
459 | set allowed no |
---|
460 | break |
---|
461 | } |
---|
462 | } |
---|
463 | if {$allowed && |
---|
464 | ([file executable [configure_get_compiler cc $compiler]] || |
---|
465 | [compiler_is_port $compiler]) |
---|
466 | } then { |
---|
467 | return $compiler |
---|
468 | } |
---|
469 | } |
---|
470 | ui_warn "All compilers are either blacklisted or unavailable; defaulting to first fallback option" |
---|
471 | return [lindex [option compiler.fallback] 0] |
---|
472 | } |
---|
473 | |
---|
474 | # internal function to choose compiler fallback list based on platform |
---|
475 | proc portconfigure::get_compiler_fallback {} { |
---|
476 | global xcodeversion macosx_deployment_target default_compilers configure.sdkroot configure.cxx_stdlib os.major |
---|
477 | |
---|
478 | # Check our override |
---|
479 | if {[info exists default_compilers]} { |
---|
480 | return $default_compilers |
---|
481 | } |
---|
482 | |
---|
483 | # Check for platforms without Xcode |
---|
484 | if {$xcodeversion eq "none" || $xcodeversion eq ""} { |
---|
485 | return {cc} |
---|
486 | } |
---|
487 | |
---|
488 | # Legacy cases |
---|
489 | if {[vercmp $xcodeversion 4.0] < 0} { |
---|
490 | if {[vercmp $xcodeversion 3.2] >= 0} { |
---|
491 | if {[string match *10.4u* ${configure.sdkroot}]} { |
---|
492 | return {gcc-4.0} |
---|
493 | } |
---|
494 | } elseif {[vercmp $xcodeversion 3.0] >= 0} { |
---|
495 | return {gcc-4.2 apple-gcc-4.2 gcc-4.0 macports-clang-3.4 macports-clang-3.3} |
---|
496 | } else { |
---|
497 | return {apple-gcc-4.2 gcc-4.0 gcc-3.3 macports-clang-3.3} |
---|
498 | } |
---|
499 | } |
---|
500 | |
---|
501 | set compilers {} |
---|
502 | |
---|
503 | # Set our preferred Xcode-provided compilers |
---|
504 | if {[vercmp $xcodeversion 5.0] >= 0} { |
---|
505 | lappend compilers clang |
---|
506 | } elseif {[vercmp $xcodeversion 4.3] >= 0} { |
---|
507 | lappend compilers clang llvm-gcc-4.2 |
---|
508 | } elseif {[vercmp $xcodeversion 4.0] >= 0} { |
---|
509 | lappend compilers llvm-gcc-4.2 clang |
---|
510 | } else { |
---|
511 | lappend compilers gcc-4.2 clang llvm-gcc-4.2 |
---|
512 | } |
---|
513 | |
---|
514 | # Determine which versions of clang we prefer |
---|
515 | if {${configure.cxx_stdlib} eq "libc++"} { |
---|
516 | # clang-3.5+ require libc++ |
---|
517 | lappend compilers macports-clang-4.0 |
---|
518 | |
---|
519 | if {${os.major} < 17} { |
---|
520 | # The High Sierra SDK requires a toolchain that can apply nullability to uuid_t |
---|
521 | lappend compilers macports-clang-3.9 |
---|
522 | } |
---|
523 | |
---|
524 | if {${os.major} < 16} { |
---|
525 | # The Sierra SDK requires a toolchain that supports class properties |
---|
526 | lappend compilers macports-clang-3.8 macports-clang-3.7 |
---|
527 | } |
---|
528 | } |
---|
529 | |
---|
530 | if {${os.major} < 16} { |
---|
531 | # We dropped support for these compilers on Sierra |
---|
532 | lappend compilers macports-clang-3.4 macports-llvm-gcc-4.2 apple-gcc-4.2 |
---|
533 | } |
---|
534 | |
---|
535 | return $compilers |
---|
536 | } |
---|
537 | |
---|
538 | # Find a developer tool |
---|
539 | proc portconfigure::find_developer_tool {name} { |
---|
540 | global developer_dir |
---|
541 | |
---|
542 | # first try /usr/bin since this doesn't move around |
---|
543 | set toolpath "/usr/bin/${name}" |
---|
544 | if {[file executable $toolpath]} { |
---|
545 | return $toolpath |
---|
546 | } |
---|
547 | |
---|
548 | # Use xcode's xcrun to find the named tool. |
---|
549 | if {![catch {exec [findBinary xcrun $portutil::autoconf::xcrun_path] -find ${name}} toolpath]} { |
---|
550 | return ${toolpath} |
---|
551 | } |
---|
552 | |
---|
553 | # If xcrun failed to find the tool, return a path from |
---|
554 | # the developer_dir. |
---|
555 | # The tool may not be there, but we'll leave it up to |
---|
556 | # the invoking code to figure out that it doesn't have |
---|
557 | # a valid compiler |
---|
558 | return "${developer_dir}/usr/bin/${name}" |
---|
559 | } |
---|
560 | |
---|
561 | |
---|
562 | # internal function to find correct compilers |
---|
563 | proc portconfigure::configure_get_compiler {type {compiler {}}} { |
---|
564 | global configure.compiler prefix |
---|
565 | if {$compiler eq ""} { |
---|
566 | set compiler ${configure.compiler} |
---|
567 | } |
---|
568 | # Tcl 8.4's switch doesn't support -matchvar. |
---|
569 | if {[regexp {^apple-gcc(-4\.[02])$} $compiler -> suffix]} { |
---|
570 | switch $type { |
---|
571 | cc - |
---|
572 | objc { return ${prefix}/bin/gcc-apple${suffix} } |
---|
573 | cxx - |
---|
574 | objcxx { |
---|
575 | if {$suffix eq "-4.2"} { |
---|
576 | return ${prefix}/bin/g++-apple${suffix} |
---|
577 | } |
---|
578 | } |
---|
579 | cpp { return ${prefix}/bin/cpp-apple${suffix} } |
---|
580 | } |
---|
581 | } elseif {[regexp {^clang$} $compiler]} { |
---|
582 | switch $type { |
---|
583 | cc - |
---|
584 | objc { return [find_developer_tool clang] } |
---|
585 | cxx - |
---|
586 | objcxx { |
---|
587 | set clangpp [find_developer_tool clang++] |
---|
588 | if {[file executable $clangpp]} { |
---|
589 | return $clangpp |
---|
590 | } |
---|
591 | return [find_developer_tool llvm-g++-4.2] |
---|
592 | } |
---|
593 | } |
---|
594 | } elseif {[regexp {^gcc(-3\.3|-4\.[02])?$} $compiler -> suffix]} { |
---|
595 | switch $type { |
---|
596 | cc - |
---|
597 | objc { return [find_developer_tool "gcc${suffix}"] } |
---|
598 | cxx - |
---|
599 | objcxx { return [find_developer_tool "g++${suffix}"] } |
---|
600 | cpp { return [find_developer_tool "cpp${suffix}"] } |
---|
601 | } |
---|
602 | } elseif {[regexp {^llvm-gcc-4\.2$} $compiler]} { |
---|
603 | switch $type { |
---|
604 | cc - |
---|
605 | objc { return [find_developer_tool llvm-gcc-4.2] } |
---|
606 | cxx - |
---|
607 | objcxx { return [find_developer_tool llvm-g++-4.2] } |
---|
608 | cpp { return [find_developer_tool llvm-cpp-4.2] } |
---|
609 | } |
---|
610 | } elseif {[regexp {^macports-clang(-\d+\.\d+)?$} $compiler -> suffix]} { |
---|
611 | if {$suffix ne ""} { |
---|
612 | set suffix "-mp${suffix}" |
---|
613 | } |
---|
614 | switch $type { |
---|
615 | cc - |
---|
616 | objc { return ${prefix}/bin/clang${suffix} } |
---|
617 | cxx - |
---|
618 | objcxx { return ${prefix}/bin/clang++${suffix} } |
---|
619 | } |
---|
620 | } elseif {[regexp {^macports-dragonegg(-\d+\.\d+)(?:-gcc(-\d+\.\d+))?$} $compiler \ |
---|
621 | -> infix suffix]} { |
---|
622 | if {$suffix ne ""} { |
---|
623 | set suffix "-mp${suffix}" |
---|
624 | } |
---|
625 | switch $type { |
---|
626 | cc - |
---|
627 | objc { return ${prefix}/bin/dragonegg${infix}-gcc${suffix} } |
---|
628 | cxx - |
---|
629 | objcxx { return ${prefix}/bin/dragonegg${infix}-g++${suffix} } |
---|
630 | cpp { return ${prefix}/bin/dragonegg${infix}-cpp${suffix} } |
---|
631 | fc - |
---|
632 | f77 - |
---|
633 | f90 { return ${prefix}/bin/dragonegg${infix}-gfortran${suffix} } |
---|
634 | } |
---|
635 | } elseif {[regexp {^macports-gcc(-\d+(?:\.\d+)?)?$} $compiler -> suffix]} { |
---|
636 | if {$suffix ne ""} { |
---|
637 | set suffix "-mp${suffix}" |
---|
638 | } |
---|
639 | switch $type { |
---|
640 | cc - |
---|
641 | objc { return ${prefix}/bin/gcc${suffix} } |
---|
642 | cxx - |
---|
643 | objcxx { return ${prefix}/bin/g++${suffix} } |
---|
644 | cpp { return ${prefix}/bin/cpp${suffix} } |
---|
645 | fc - |
---|
646 | f77 - |
---|
647 | f90 { return ${prefix}/bin/gfortran${suffix} } |
---|
648 | } |
---|
649 | } elseif {[regexp {^macports-llvm-gcc-4\.2$} $compiler]} { |
---|
650 | switch $type { |
---|
651 | cc - |
---|
652 | objc { return ${prefix}/bin/llvm-gcc-4.2 } |
---|
653 | cxx - |
---|
654 | objcxx { return ${prefix}/bin/llvm-g++-4.2 } |
---|
655 | cpp { return ${prefix}/bin/llvm-cpp-4.2 } |
---|
656 | } |
---|
657 | } |
---|
658 | # Fallbacks |
---|
659 | switch $type { |
---|
660 | cc - |
---|
661 | objc { return [find_developer_tool cc] } |
---|
662 | cxx - |
---|
663 | objcxx { return [find_developer_tool c++] } |
---|
664 | cpp { return [find_developer_tool cpp] } |
---|
665 | } |
---|
666 | return "" |
---|
667 | } |
---|
668 | |
---|
669 | # Automatically called from macports1.0 after evaluating the Portfile |
---|
670 | # Some of the compilers we use are provided by MacPorts itself; ensure we |
---|
671 | # automatically add a dependency when needed |
---|
672 | proc portconfigure::add_automatic_compiler_dependencies {} { |
---|
673 | global configure.compiler configure.compiler.add_deps |
---|
674 | |
---|
675 | if {!${configure.compiler.add_deps}} { |
---|
676 | return |
---|
677 | } |
---|
678 | |
---|
679 | # The default value requires substitution before use. |
---|
680 | set compiler [subst ${configure.compiler}] |
---|
681 | if {![compiler_is_port $compiler]} { |
---|
682 | return |
---|
683 | } |
---|
684 | |
---|
685 | ui_debug "Chosen compiler ${compiler} is provided by a port, adding dependency" |
---|
686 | |
---|
687 | set compiler_port [portconfigure::compiler_port_name ${compiler}] |
---|
688 | set deptype "build" |
---|
689 | if {[string first "macports-gcc-" $compiler] == 0} { |
---|
690 | set deptype "lib" |
---|
691 | } |
---|
692 | ui_debug "Adding depends_${deptype} port:$compiler_port" |
---|
693 | depends_${deptype}-delete port:$compiler_port |
---|
694 | depends_${deptype}-append port:$compiler_port |
---|
695 | |
---|
696 | if {[arch_flag_supported $compiler]} { |
---|
697 | ui_debug "Adding depends_skip_archcheck $compiler_port" |
---|
698 | depends_skip_archcheck-delete $compiler_port |
---|
699 | depends_skip_archcheck-append $compiler_port |
---|
700 | } |
---|
701 | } |
---|
702 | # Register the above procedure as a callback after Portfile evaluation |
---|
703 | port::register_callback portconfigure::add_automatic_compiler_dependencies |
---|
704 | # and an option to turn it off if required |
---|
705 | options configure.compiler.add_deps |
---|
706 | default configure.compiler.add_deps yes |
---|
707 | |
---|
708 | proc portconfigure::configure_main {args} { |
---|
709 | global [info globals] |
---|
710 | global worksrcpath use_configure use_autoreconf use_autoconf use_automake use_xmkmf \ |
---|
711 | configure.env configure.pipe configure.libs configure.classpath configure.universal_args \ |
---|
712 | configure.perl configure.python configure.ruby configure.install configure.awk configure.bison \ |
---|
713 | configure.pkg_config configure.pkg_config_path \ |
---|
714 | configure.ccache configure.distcc configure.cpp configure.javac configure.sdkroot \ |
---|
715 | configure.march configure.mtune configure.cxx_stdlib \ |
---|
716 | os.platform os.major |
---|
717 | foreach tool {cc cxx objc objcxx f77 f90 fc ld} { |
---|
718 | global configure.${tool} configure.${tool}_archflags |
---|
719 | } |
---|
720 | foreach flags {cflags cppflags cxxflags objcflags objcxxflags ldflags fflags f90flags fcflags} { |
---|
721 | global configure.${flags} configure.universal_${flags} |
---|
722 | } |
---|
723 | |
---|
724 | if {[tbool use_autoreconf]} { |
---|
725 | if {[catch {command_exec autoreconf} result]} { |
---|
726 | return -code error "[format [msgcat::mc "%s failure: %s"] autoreconf $result]" |
---|
727 | } |
---|
728 | } |
---|
729 | |
---|
730 | if {[tbool use_automake]} { |
---|
731 | if {[catch {command_exec automake} result]} { |
---|
732 | return -code error "[format [msgcat::mc "%s failure: %s"] automake $result]" |
---|
733 | } |
---|
734 | } |
---|
735 | |
---|
736 | if {[tbool use_autoconf]} { |
---|
737 | if {[catch {command_exec autoconf} result]} { |
---|
738 | return -code error "[format [msgcat::mc "%s failure: %s"] autoconf $result]" |
---|
739 | } |
---|
740 | } |
---|
741 | |
---|
742 | if {[tbool use_xmkmf]} { |
---|
743 | parse_environment xmkmf |
---|
744 | if {[catch {command_exec xmkmf} result]} { |
---|
745 | return -code error "[format [msgcat::mc "%s failure: %s"] xmkmf $result]" |
---|
746 | } |
---|
747 | |
---|
748 | parse_environment xmkmf |
---|
749 | if {[catch {command_exec "cd ${worksrcpath} && make Makefiles" -varprefix xmkmf} result]} { |
---|
750 | return -code error "[format [msgcat::mc "%s failure: %s"] "make Makefiles" $result]" |
---|
751 | } |
---|
752 | } elseif {[tbool use_configure]} { |
---|
753 | # Merge (ld|c|cpp|cxx)flags into the environment variable. |
---|
754 | parse_environment configure |
---|
755 | |
---|
756 | # Set pre-compiler filter to use (ccache/distcc), if any. |
---|
757 | if {[tbool configure.ccache] && [tbool configure.distcc]} { |
---|
758 | set filter ccache |
---|
759 | append_to_environment_value configure "CCACHE_PREFIX" "distcc" |
---|
760 | } elseif {[tbool configure.ccache]} { |
---|
761 | set filter ccache |
---|
762 | } elseif {[tbool configure.distcc]} { |
---|
763 | set filter distcc |
---|
764 | } else { |
---|
765 | set filter "" |
---|
766 | } |
---|
767 | foreach env_var {CC CXX OBJC OBJCXX} { |
---|
768 | append_to_environment_value configure $env_var $filter |
---|
769 | } |
---|
770 | |
---|
771 | # Set flags controlling the kind of compiler output. |
---|
772 | if {[tbool configure.pipe]} { |
---|
773 | set output -pipe |
---|
774 | } else { |
---|
775 | set output "" |
---|
776 | } |
---|
777 | foreach env_var {CFLAGS CXXFLAGS OBJCFLAGS OBJCXXFLAGS FFLAGS F90FLAGS FCFLAGS} { |
---|
778 | append_to_environment_value configure $env_var $output |
---|
779 | } |
---|
780 | |
---|
781 | # Append configure flags. |
---|
782 | foreach env_var { \ |
---|
783 | CC CXX OBJC OBJCXX FC F77 F90 JAVAC \ |
---|
784 | CFLAGS CPPFLAGS CXXFLAGS OBJCFLAGS OBJCXXFLAGS \ |
---|
785 | FFLAGS F90FLAGS FCFLAGS LDFLAGS LIBS CLASSPATH \ |
---|
786 | PERL PYTHON RUBY INSTALL AWK BISON PKG_CONFIG PKG_CONFIG_PATH \ |
---|
787 | } { |
---|
788 | set value [option configure.[string tolower $env_var]] |
---|
789 | append_to_environment_value configure $env_var {*}$value |
---|
790 | } |
---|
791 | |
---|
792 | # https://trac.macports.org/ticket/34221 |
---|
793 | if {${os.platform} eq "darwin" && ${os.major} == 12} { |
---|
794 | append_to_environment_value configure "__CFPREFERENCES_AVOID_DAEMON" 1 |
---|
795 | } |
---|
796 | |
---|
797 | # add SDK flags if cross-compiling (or universal on ppc tiger) |
---|
798 | if {${configure.sdkroot} ne ""} { |
---|
799 | foreach env_var {CPPFLAGS CFLAGS CXXFLAGS OBJCFLAGS OBJCXXFLAGS} { |
---|
800 | append_to_environment_value configure $env_var -isysroot${configure.sdkroot} |
---|
801 | } |
---|
802 | append_to_environment_value configure "LDFLAGS" -Wl,-syslibroot,${configure.sdkroot} |
---|
803 | } |
---|
804 | |
---|
805 | # add extra flags that are conditional on whether we're building universal |
---|
806 | append_to_environment_value configure CFLAGS {*}[get_canonical_archflags cc] |
---|
807 | foreach tool {cxx objc objcxx cpp f77 f90 fc ld} { |
---|
808 | if {[catch {get_canonical_archflags $tool} flags]} { |
---|
809 | continue |
---|
810 | } |
---|
811 | set env_var [string toupper $tool]FLAGS |
---|
812 | append_to_environment_value configure $env_var {*}$flags |
---|
813 | } |
---|
814 | if {[variant_exists universal] && [variant_isset universal]} { |
---|
815 | configure.pre_args-append {*}${configure.universal_args} |
---|
816 | } else { |
---|
817 | foreach env_var {CFLAGS CXXFLAGS OBJCFLAGS OBJCXXFLAGS FFLAGS F90FLAGS FCFLAGS LDFLAGS} { |
---|
818 | if {${configure.march} ne ""} { |
---|
819 | append_to_environment_value configure $env_var -march=${configure.march} |
---|
820 | } |
---|
821 | if {${configure.mtune} ne ""} { |
---|
822 | append_to_environment_value configure $env_var -mtune=${configure.mtune} |
---|
823 | } |
---|
824 | } |
---|
825 | } |
---|
826 | |
---|
827 | # Execute the command (with the new environment). |
---|
828 | if {[catch {command_exec configure} result]} { |
---|
829 | global configure.dir |
---|
830 | if {[file exists ${configure.dir}/config.log]} { |
---|
831 | ui_error "[format [msgcat::mc "Failed to configure %s, consult %s/config.log"] [option subport] ${configure.dir}]" |
---|
832 | } |
---|
833 | return -code error "[format [msgcat::mc "%s failure: %s"] configure $result]" |
---|
834 | } |
---|
835 | } |
---|
836 | return 0 |
---|
837 | } |
---|