source: trunk/dports/_resources/port1.0/group/compilers-1.0.tcl @ 116304

Last change on this file since 116304 was 116304, checked in by sean@…, 6 years ago

compilers-1.0: add fortran_active_variant_name proc

File size: 16.5 KB
Line 
1# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
2# $Id$
3#
4# Copyright (c) 2012 The MacPorts Project
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions are
9# met:
10#
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 The MacPorts Project nor the names of its
17#    contributors may be used to endorse or promote products derived from
18#    this software without specific prior written permission.
19#
20# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31#
32#
33# This PortGroup sets up default variants for projects that want m
34#
35# Usage:
36#
37#   PortGroup               compilers 1.0
38
39options compilers.variants compilers.gcc_variants
40default compilers.variants {}
41default compilers.fortran_variants {}
42default compilers.gcc_variants {}
43default compilers.clang_variants {}
44default compilers.dragonegg_variants {}
45default compilers.require_fortran 0
46default compilers.setup_done 0
47
48set compilers.list {cc cxx cpp objc fc f77 f90}
49
50# build database of gcc 4{4..9} compiler attributes
51set gcc_versions {4 5 6 7 8 9}
52foreach v ${gcc_versions} {
53    lappend compilers.gcc_variants gcc4$v
54    set cdb(gcc4$v,variant)  gcc4$v
55    set cdb(gcc4$v,compiler) macports-gcc-4.$v
56    set cdb(gcc4$v,descrip)  "MacPorts gcc 4.$v"
57    set cdb(gcc4$v,depends)  port:gcc4$v
58    set cdb(gcc4$v,dependsl) path:lib/libgcc/libgcc_s.1.dylib:libgcc
59    set cdb(gcc4$v,dependsd) port:g95
60    set cdb(gcc4$v,dependsa) gcc4$v
61    set cdb(gcc4$v,conflict) "gfortran g95"
62    set cdb(gcc4$v,flags)    {
63        {{"-PIC"} {"-fPIC"}}
64    }
65    set cdb(gcc4$v,cc)       ${prefix}/bin/gcc-mp-4.$v
66    set cdb(gcc4$v,cxx)      ${prefix}/bin/g++-mp-4.$v
67    set cdb(gcc4$v,cpp)      ${prefix}/bin/cpp-mp-4.$v
68    set cdb(gcc4$v,objc)     ${prefix}/bin/gcc-mp-4.$v
69    set cdb(gcc4$v,fc)       ${prefix}/bin/gfortran-mp-4.$v
70    set cdb(gcc4$v,f77)      ${prefix}/bin/gfortran-mp-4.$v
71    set cdb(gcc4$v,f90)      ${prefix}/bin/gfortran-mp-4.$v
72}
73
74set clang_versions {0 1 2 3 4 5}
75foreach v ${clang_versions} {
76    lappend compilers.clang_variants clang3$v
77    set cdb(clang3$v,variant)  clang3$v
78    set cdb(clang3$v,compiler) macports-clang-3.$v
79    set cdb(clang3$v,descrip)  "MacPorts clang 3.$v"
80    set cdb(clang3$v,depends)  port:clang-3.$v
81    set cdb(clang3$v,dependsl) ""
82    set cdb(clang3$v,dependsd) ""
83    set cdb(clang3$v,dependsa) clang-3.$v
84    set cdb(clang3$v,conflict) ""
85    set cdb(clang3$v,flags)    {
86        {{"-PIC"} {"-fPIC"}}
87    }
88    set cdb(clang3$v,cc)       ${prefix}/bin/clang-mp-3.$v
89    set cdb(clang3$v,cxx)      ${prefix}/bin/clang++-mp-3.$v
90    set cdb(clang3$v,cpp)      "${prefix}/bin/clang-mp-3.$v -E"
91    set cdb(clang3$v,objc)     ""
92    set cdb(clang3$v,fc)       ""
93    set cdb(clang3$v,f77)      ""
94    set cdb(clang3$v,f90)      ""
95}
96
97# dragonegg versions will always match the corresponding clang version
98foreach v ${clang_versions} {
99    lappend compilers.dragonegg_variants dragonegg3$v
100    set cdb(dragonegg3$v,variant)  dragonegg3$v
101    set cdb(dragonegg3$v,compiler) macports-dragonegg-3.$v
102    set cdb(dragonegg3$v,descrip)  "MacPorts dragonegg 3.$v"
103    set cdb(dragonegg3$v,depends)  path:bin/dragonegg-3.$v-gcc:dragonegg-3.$v
104    set cdb(dragonegg3$v,dependsl) path:lib/libgcc/libgcc_s.1.dylib:libgcc
105    set cdb(dragonegg3$v,dependsd) port:g95
106    set cdb(dragonegg3$v,dependsa) dragonegg-3.$v
107    set cdb(dragonegg3$v,conflict) "gfortran g95"
108    set cdb(dragonegg3$v,flags)    {
109        {{"-PIC"} {"-fPIC"}}
110    }
111    set cdb(dragonegg3$v,cc)       ${prefix}/bin/dragonegg-3.$v-gcc
112    set cdb(dragonegg3$v,cxx)      ${prefix}/bin/dragonegg-3.$v-g++
113    set cdb(dragonegg3$v,cpp)      ${prefix}/bin/dragonegg-3.$v-cpp
114    set cdb(dragonegg3$v,objc)     ""
115    set cdb(dragonegg3$v,fc)       ${prefix}/bin/dragonegg-3.$v-gfortran
116    set cdb(dragonegg3$v,f77)      ${prefix}/bin/dragonegg-3.$v-gfortran
117    set cdb(dragonegg3$v,f90)      ${prefix}/bin/dragonegg-3.$v-gfortran
118}
119
120set cdb(llvm,variant)  llvm
121set cdb(llvm,compiler) llvm-gcc-4.2
122set cdb(llvm,descrip)  "Apple native llvm-gcc 4.2"
123set cdb(llvm,depends)  bin:llvm-gcc-4.2:llvm-gcc42
124set cdb(llvm,dependsl) ""
125set cdb(llvm,dependsd) ""
126set cdb(llvm,dependsa) ""
127set cdb(llvm,conflict) ""
128set cdb(llvm,flags)    {
129    {{"-fPIC"} {"-PIC"}}
130}
131set cdb(llvm,cc)       llvm-gcc-4.2
132set cdb(llvm,cxx)      llvm-g++-4.2
133set cdb(llvm,cpp)      llvm-cpp-4.2
134set cdb(llvm,objc)     llvm-gcc-4.2
135set cdb(llvm,fc)       ""
136set cdb(llvm,f77)      ""
137set cdb(llvm,f90)      ""
138
139# and lastly we add a gfortran and g95 variant for use with clang*; note that
140# we don't need gfortran when we are in an "only-fortran" mode
141set cdb(gfortran,variant)  gfortran
142set cdb(gfortran,compiler) gfortran
143set cdb(gfortran,descrip)  "Fortran compiler from gcc48"
144set cdb(gfortran,depends)  port:gcc48
145set cdb(gfortran,dependsl) path:lib/libgcc/libgcc_s.1.dylib:libgcc
146set cdb(gfortran,dependsd) ""
147set cdb(gfortran,dependsa) ""
148set cdb(gfortran,conflict) ""
149set cdb(gfortran,flags)    {
150    {{"-fPIC"} {"-PIC"}}
151}
152set cdb(gfortran,cc)       ""
153set cdb(gfortran,cxx)      ""
154set cdb(gfortran,cpp)      ""
155set cdb(gfortran,objc)     ""
156set cdb(gfortran,fc)       ${prefix}/bin/gfortran-mp-4.8
157set cdb(gfortran,f77)      ${prefix}/bin/gfortran-mp-4.8
158set cdb(gfortran,f90)      ${prefix}/bin/gfortran-mp-4.8
159
160set cdb(g95,variant)  g95
161set cdb(g95,compiler) g95
162set cdb(g95,descrip)  "Fortran compiler from g95"
163set cdb(g95,depends)  port:g95
164set cdb(g95,dependsl) ""
165set cdb(g95,dependsd) ""
166set cdb(g95,dependsa) g95
167set cdb(g95,conflict) ""
168set cdb(g95,flags)    {
169    {{"-fPIC"} {"-PIC"}}
170}
171set cdb(g95,cc)       ""
172set cdb(g95,cxx)      ""
173set cdb(g95,cpp)      ""
174set cdb(g95,objc)     ""
175set cdb(g95,fc)       ${prefix}/bin/g95
176set cdb(g95,f77)      ${prefix}/bin/g95
177set cdb(g95,f90)      ${prefix}/bin/g95
178
179foreach name [array names cdb *,variant] {
180    lappend compilers.variants $cdb($name)
181}
182
183foreach variant ${compilers.variants} {
184    if {$cdb($variant,f77) ne ""} {
185        lappend compilers.fortran_variants $variant
186    }
187}
188
189proc compilers.setup_variants {args} {
190    global cdb compilers.variants compilers.clang_variants compilers.gcc_variants
191    global compilers.dragonegg_variants compilers.fortran_variants compilers.list
192
193    foreach variant [split $args] {
194        if {$cdb($variant,f77) ne ""} {
195            lappend compilers.fortran_variants $variant
196        }
197
198        if {[variant_exists $variant]} {
199            ui_debug "$variant variant already exists, so not adding the default one"
200        } else {
201            set i [lsearch -exact ${compilers.variants} $variant]
202            set c [lreplace ${compilers.variants} $i $i]
203
204            # fortran doesn't conflict with clang
205            if {$variant eq "gfortran" || $variant eq "g95"} {
206                foreach clangcomp ${compilers.clang_variants} {
207                    set i [lsearch -exact $c $clangcomp]
208                    set c [lreplace $c $i $i]
209                }
210            } elseif {[string match clang* $variant]} {
211                set i [lsearch -exact $c gfortran]
212                set c [lreplace $c $i $i]
213                set i [lsearch -exact $c g95]
214                set c [lreplace $c $i $i]
215            }
216
217            # for each pair of flags (old,new), build a string of if statements to
218            # replace old with new
219            set f ""
220            foreach flag $cdb($variant,flags) {
221                foreach {old new} $flag {
222                    append f [subst {
223                        if {\[string first $old \${configure.cflags}\] > -1} {
224                            configure.cflags-delete $old
225                            configure.cflags-append $new
226                        }
227                    }]
228                }
229            }
230
231            foreach flag $cdb($variant,flags) {
232                foreach {old new} $flag {
233                    append f [subst {
234                        if {\[string first $old \${configure.cxxflags}\] > -1} {
235                            configure.cxxflags-delete $old
236                            configure.cxxflags-append $new
237                        }
238                    }]
239                }
240            }
241
242            # for each compiler, set the value if not empty; we can't use
243            # configure.compiler because of dragonegg and possibly other new
244            # compilers that aren't in macports portconfigure.tcl
245            set comp ""
246            foreach compiler ${compilers.list} {
247                if {$cdb($variant,$compiler) ne ""} {
248                    append comp [subst {
249                        configure.$compiler $cdb($variant,$compiler)
250
251                        # disable archflags
252                        if {"[info command configure.${compiler}_archflags]" ne ""} {
253                            configure.${compiler}_archflags
254                            configure.ld_archflags
255                        }
256                    }]
257                }
258            }
259
260            eval [subst {
261                variant ${variant} description \
262                    {Build using the $cdb($variant,descrip) compiler} \
263                    conflicts $c $cdb($variant,conflict) {
264
265                    depends_build-append   $cdb($variant,depends)
266                    depends_lib-append     $cdb($variant,dependsl)
267                    depends_lib-delete     $cdb($variant,dependsd)
268                    depends_skip_archcheck $cdb($variant,dependsa)
269
270                    $comp
271
272                    $f
273                }
274            }]
275        }
276    }
277}
278
279foreach variant ${compilers.gcc_variants} {
280    if {[variant_isset $variant]} {
281        depends_lib-delete      port:g95
282        break
283    }
284}
285
286proc c_active_variant_name {depspec} {
287    global compilers.variants compilers.fortran_variants
288    set c_list [remove_from_list ${compilers.variants} {gfortran g95}]
289
290    foreach c $c_list {
291        if {![catch {set result [active_variants $depspec $c ""]}]} {
292            if {$result} {
293                return $c
294            }
295        }
296    }
297
298    return ""
299}
300
301proc c_variant_name {} {
302    global compilers.variants compilers.fortran_variants
303    set c_list [remove_from_list ${compilers.variants} {gfortran g95}]
304
305    foreach cc $c_list {
306        if {[variant_isset $cc]} {
307            return $cc
308        }
309    }
310
311    return ""
312}
313
314proc fortran_active_variant_name {depspec} {
315    global compilers.fortran_variants
316
317    foreach fc ${compilers.fortran_variants} {
318        if {![catch {set result [active_variants $depspec $fc ""]}]} {
319            if {$result} {
320                return $fc
321            }
322        }
323    }
324
325    return ""
326}
327
328proc fortran_variant_name {} {
329    global compilers.fortran_variants
330
331    foreach fc ${compilers.fortran_variants} {
332        if {[variant_isset $fc]} {
333            return $fc
334        }
335    }
336
337    return ""
338}
339
340proc clang_variant_name {} {
341    global compilers.clang_variants compilers.dragonegg_variants
342
343    foreach c ${compilers.clang_variants} {
344        if {[variant_isset $c]} {
345            return $c
346        }
347    }
348
349    foreach c ${compilers.dragonegg_variants} {
350        if {[variant_isset $c]} {
351            return $c
352        }
353    }
354
355    return ""
356}
357
358proc clang_variant_isset {} {
359    return [expr {[clang_variant_name] ne ""}]
360}
361
362proc avx_compiler_isset {} {
363    global configure.cc
364
365    if {[string match *clang* ${configure.cc}]} {
366        return 1
367    }
368
369    return 0
370}
371
372proc fortran_variant_isset {} {
373    return [expr {[fortran_variant_name] ne ""}]
374}
375
376# remove all elements in R from L
377proc remove_from_list {L R} {
378    foreach e $R {
379        set idx [lsearch $L $e]
380        set L [lreplace $L $idx $idx]
381    }
382    return $L
383}
384
385# add all elements in R from L
386proc add_from_list {L A} {
387    return [concat $L $A]
388}
389
390proc compilers.choose {args} {
391    global compilers.list
392
393    # zero out the variable before and append args
394    set compilers.list {}
395    foreach v $args {
396        lappend compilers.list $v
397    }
398}
399
400proc compilers.is_fortran_only {} {
401    global compilers.list
402
403    foreach c {cc cxx cpp objc} {
404        if {[lsearch -exact ${compilers.list} $c] >= 0} {
405            return 0
406        }
407    }
408
409    return 1
410}
411
412proc compilers.is_c_only {} {
413    global compilers.list
414
415    foreach c {f77 f90 fc} {
416        if {[lsearch -exact ${compilers.list} $c] >= 0} {
417            return 0
418        }
419    }
420
421    return 1
422}
423
424proc compilers.setup {args} {
425    global cdb compilers.variants compilers.clang_variants compilers.gcc_variants
426    global compilers.dragonegg_variants compilers.fortran_variants
427    global compilers.require_fortran compilers.setup_done compilers.list
428
429    if {!${compilers.setup_done}} {
430        set add_list {}
431        set remove_list ${compilers.variants}
432
433        # if we are only setting fortran compilers, then we are in "only fortran
434        # mode", i.e. we just need +gccXY and +dragoneggXY for the fortran
435        # compilers so we remove +clangXY and +llvm
436        if {[compilers.is_fortran_only]} {
437            # remove gfortran since that only exists to "complete" clang/llvm
438            set remove_list [remove_from_list ${compilers.fortran_variants} gfortran]
439        } elseif {[compilers.is_c_only]} {
440            # remove gfortran and g95 since those are purely for fortran
441            set remove_list [remove_from_list ${compilers.variants} {gfortran g95}]
442        }
443
444        foreach v $args {
445            # if any negated compiler (e.g. -gcc47) is specified then we are
446            # removing from the default, complete list
447            set mode add
448            if {[string first - $v] == 0} {
449                set mode remove
450
451                #strip the beginning '-' character
452                set v [string range $v 1 end]
453            }
454
455            # handle special cases, such as 'gcc' -> all gcc variants
456            switch -exact $v {
457                gcc {
458                    set ${mode}_list [${mode}_from_list [expr $${mode}_list] ${compilers.gcc_variants}]
459                }
460                dragonegg {
461                    set ${mode}_list [${mode}_from_list [expr $${mode}_list] ${compilers.dragonegg_variants}]
462                }
463                fortran {
464                    # here we just check gfortran and g95, not every fortran
465                    # compatible variant since it makes more sense to specify
466                    # 'fortran' to mean add just the +gfortran and +g95 variants
467                    set ${mode}_list [${mode}_from_list [expr $${mode}_list] {gfortran g95}]
468
469                }
470                clang {
471                    set ${mode}_list [${mode}_from_list [expr $${mode}_list] ${compilers.clang_variants}]
472                }
473                require_fortran {
474                    # this signals that fortran is required and not optional
475                    set compilers.require_fortran 1
476                }
477                default {
478                    if {[info exists cdb($v,variant)] == 0} {
479                        return -code error "no such compiler: $v"
480                    }
481                    set ${mode}_list [${mode}_from_list [expr $${mode}_list] $cdb($v,variant)]
482                }
483            }
484        }
485
486        # remove duplicates
487        set duplicates {}
488        foreach foo $remove_list {
489            if {[lsearch $add_list $foo] != -1} {
490                lappend duplicates $foo
491            }
492        }
493
494        set compilers.variants [lsort [concat [remove_from_list $remove_list $duplicates] $add_list]]
495        eval compilers.setup_variants ${compilers.variants}
496
497        set compilers.setup_done 1
498    }
499}
500
501pre-fetch {
502    if {${compilers.require_fortran} && [fortran_variant_name] eq ""} {
503        return -code error "must set at least one fortran variant"
504    }
505}
Note: See TracBrowser for help on using the repository browser.