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

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

compilers-1.0: remove assumption about clang 3.x version; no behavioral change

File size: 20.8 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) 2014 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
39PortGroup active_variants 1.1
40
41options compilers.variants compilers.gcc_variants
42default compilers.variants {}
43default compilers.fortran_variants {}
44default compilers.gcc_variants {}
45default compilers.clang_variants {}
46default compilers.dragonegg_variants {}
47default compilers.require_fortran 0
48default compilers.setup_done 0
49default compilers.required_c {}
50default compilers.required_f {}
51
52set compilers.list {cc cxx cpp objc fc f77 f90}
53
54# build database of gcc 4{4..9} compiler attributes
55set gcc_versions {44 45 46 47 48 49}
56foreach v ${gcc_versions} {
57    # if the string is more than one character insert a '.' into it: e.g 49 -> 4.9
58    set version $v
59    if {[string length $v] > 1} {
60        set version [string index $v 0].[string index $v 1]
61    }
62    lappend compilers.gcc_variants gcc$v
63    set cdb(gcc$v,variant)  gcc$v
64    set cdb(gcc$v,compiler) macports-gcc-$version
65    set cdb(gcc$v,descrip)  "MacPorts gcc $version"
66    set cdb(gcc$v,depends)  port:gcc$v
67    set cdb(gcc$v,dependsl) path:lib/libgcc/libgcc_s.1.dylib:libgcc
68    set cdb(gcc$v,dependsd) port:g95
69    set cdb(gcc$v,dependsa) gcc$v
70    set cdb(gcc$v,conflict) "gfortran g95"
71    set cdb(gcc$v,cc)       ${prefix}/bin/gcc-mp-$version
72    set cdb(gcc$v,cxx)      ${prefix}/bin/g++-mp-$version
73    set cdb(gcc$v,cpp)      ${prefix}/bin/cpp-mp-$version
74    set cdb(gcc$v,objc)     ${prefix}/bin/gcc-mp-$version
75    set cdb(gcc$v,fc)       ${prefix}/bin/gfortran-mp-$version
76    set cdb(gcc$v,f77)      ${prefix}/bin/gfortran-mp-$version
77    set cdb(gcc$v,f90)      ${prefix}/bin/gfortran-mp-$version
78}
79
80set clang_versions {30 31 32 33 34 35}
81foreach v ${clang_versions} {
82    # if the string is more than one character insert a '.' into it: e.g 33 -> 3.3
83    set version $v
84    if {[string length $v] > 1} {
85        set version [string index $v 0].[string index $v 1]
86    }
87    lappend compilers.clang_variants clang$v
88    set cdb(clang$v,variant)  clang$v
89    set cdb(clang$v,compiler) macports-clang-$version
90    set cdb(clang$v,descrip)  "MacPorts clang $version"
91    set cdb(clang$v,depends)  port:clang-$version
92    set cdb(clang$v,dependsl) ""
93    set cdb(clang$v,dependsd) ""
94    set cdb(clang$v,dependsa) clang-$version
95    set cdb(clang$v,conflict) ""
96    set cdb(clang$v,cc)       ${prefix}/bin/clang-mp-$version
97    set cdb(clang$v,cxx)      ${prefix}/bin/clang++-mp-$version
98    set cdb(clang$v,cpp)      "${prefix}/bin/clang-mp-$version -E"
99    set cdb(clang$v,objc)     ""
100    set cdb(clang$v,fc)       ""
101    set cdb(clang$v,f77)      ""
102    set cdb(clang$v,f90)      ""
103}
104
105# dragonegg versions match the corresponding clang version until 3.5
106set dragonegg_versions {3 4}
107foreach v ${dragonegg_versions} {
108    lappend compilers.dragonegg_variants dragonegg3$v
109    set cdb(dragonegg3$v,variant)  dragonegg3$v
110    set cdb(dragonegg3$v,compiler) macports-dragonegg-3.$v
111    set cdb(dragonegg3$v,descrip)  "MacPorts dragonegg 3.$v"
112    set cdb(dragonegg3$v,depends)  path:bin/dragonegg-3.$v-gcc:dragonegg-3.$v
113    set cdb(dragonegg3$v,dependsl) path:lib/libgcc/libgcc_s.1.dylib:libgcc
114    set cdb(dragonegg3$v,dependsd) port:g95
115    set cdb(dragonegg3$v,dependsa) dragonegg-3.$v
116    set cdb(dragonegg3$v,conflict) "gfortran g95"
117    set cdb(dragonegg3$v,cc)       ${prefix}/bin/dragonegg-3.$v-gcc
118    set cdb(dragonegg3$v,cxx)      ${prefix}/bin/dragonegg-3.$v-g++
119    set cdb(dragonegg3$v,cpp)      ${prefix}/bin/dragonegg-3.$v-cpp
120    set cdb(dragonegg3$v,objc)     ""
121    set cdb(dragonegg3$v,fc)       ${prefix}/bin/dragonegg-3.$v-gfortran
122    set cdb(dragonegg3$v,f77)      ${prefix}/bin/dragonegg-3.$v-gfortran
123    set cdb(dragonegg3$v,f90)      ${prefix}/bin/dragonegg-3.$v-gfortran
124}
125
126set cdb(llvm,variant)  llvm
127set cdb(llvm,compiler) llvm-gcc-4.2
128set cdb(llvm,descrip)  "Apple native llvm-gcc 4.2"
129set cdb(llvm,depends)  bin:llvm-gcc-4.2:llvm-gcc42
130set cdb(llvm,dependsl) ""
131set cdb(llvm,dependsd) ""
132set cdb(llvm,dependsa) ""
133set cdb(llvm,conflict) ""
134set cdb(llvm,cc)       llvm-gcc-4.2
135set cdb(llvm,cxx)      llvm-g++-4.2
136set cdb(llvm,cpp)      llvm-cpp-4.2
137set cdb(llvm,objc)     llvm-gcc-4.2
138set cdb(llvm,fc)       ""
139set cdb(llvm,f77)      ""
140set cdb(llvm,f90)      ""
141
142# and lastly we add a gfortran and g95 variant for use with clang*; note that
143# we don't need gfortran when we are in an "only-fortran" mode
144set compilers.gfortran_equiv    gcc49
145set cdb(gfortran,variant)  gfortran
146set cdb(gfortran,compiler) $cdb(${compilers.gfortran_equiv},compiler)
147set cdb(gfortran,descrip)  $cdb(${compilers.gfortran_equiv},descrip)
148set cdb(gfortran,depends)  $cdb(${compilers.gfortran_equiv},depends)
149set cdb(gfortran,dependsl) $cdb(${compilers.gfortran_equiv},dependsl)
150set cdb(gfortran,dependsd) $cdb(${compilers.gfortran_equiv},dependsd)
151set cdb(gfortran,dependsa) $cdb(${compilers.gfortran_equiv},dependsa)
152set cdb(gfortran,conflict) $cdb(${compilers.gfortran_equiv},conflict)
153set cdb(gfortran,cc)       $cdb(${compilers.gfortran_equiv},cc)
154set cdb(gfortran,cxx)      $cdb(${compilers.gfortran_equiv},cxx)
155set cdb(gfortran,cpp)      $cdb(${compilers.gfortran_equiv},cpp)
156set cdb(gfortran,objc)     $cdb(${compilers.gfortran_equiv},objc)
157set cdb(gfortran,fc)       $cdb(${compilers.gfortran_equiv},fc)
158set cdb(gfortran,f77)      $cdb(${compilers.gfortran_equiv},f77)
159set cdb(gfortran,f90)      $cdb(${compilers.gfortran_equiv},f90)
160
161set cdb(g95,variant)  g95
162set cdb(g95,compiler) g95
163set cdb(g95,descrip)  "Fortran compiler from g95"
164set cdb(g95,depends)  port:g95
165set cdb(g95,dependsl) ""
166set cdb(g95,dependsd) ""
167set cdb(g95,dependsa) g95
168set cdb(g95,conflict) ""
169set cdb(g95,cc)       ""
170set cdb(g95,cxx)      ""
171set cdb(g95,cpp)      ""
172set cdb(g95,objc)     ""
173set cdb(g95,fc)       ${prefix}/bin/g95
174set cdb(g95,f77)      ${prefix}/bin/g95
175set cdb(g95,f90)      ${prefix}/bin/g95
176
177foreach cname [array names cdb *,variant] {
178    lappend compilers.variants $cdb($cname)
179}
180
181foreach variant ${compilers.variants} {
182    if {$cdb($variant,f77) ne ""} {
183        lappend compilers.fortran_variants $variant
184    }
185}
186
187proc compilers.setup_variants {args} {
188    global cdb compilers.variants compilers.clang_variants compilers.gcc_variants
189    global compilers.dragonegg_variants compilers.fortran_variants compilers.list
190
191    foreach variant [split $args] {
192        if {$cdb($variant,f77) ne ""} {
193            lappend compilers.fortran_variants $variant
194        }
195
196        if {[variant_exists $variant]} {
197            ui_debug "$variant variant already exists, so not adding the default one"
198        } else {
199            set i [lsearch -exact ${compilers.variants} $variant]
200            set c [lreplace ${compilers.variants} $i $i]
201
202            # fortran doesn't conflict with clang
203            if {$variant eq "gfortran" || $variant eq "g95"} {
204                foreach clangcomp ${compilers.clang_variants} {
205                    set i [lsearch -exact $c $clangcomp]
206                    set c [lreplace $c $i $i]
207                }
208            } elseif {[string match clang* $variant]} {
209                set i [lsearch -exact $c gfortran]
210                set c [lreplace $c $i $i]
211                set i [lsearch -exact $c g95]
212                set c [lreplace $c $i $i]
213            }
214
215            # only add conflicts from the compiler database (set above) if we
216            # actually have the compiler in the list of allowed variants
217            foreach j $cdb($variant,conflict) {
218                if {[lsearch -exact $j ${compilers.variants}] > -1} {
219                    lappend c $j
220                }
221            }
222
223            # for each compiler, set the value if not empty; we can't use
224            # configure.compiler because of dragonegg and possibly other new
225            # compilers that aren't in macports portconfigure.tcl
226            set comp ""
227            foreach compiler ${compilers.list} {
228                if {$cdb($variant,$compiler) ne ""} {
229                    append comp [subst {
230                        configure.$compiler $cdb($variant,$compiler)
231
232                        # disable archflags
233                        if {"[info command configure.${compiler}_archflags]" ne ""} {
234                            configure.${compiler}_archflags
235                            configure.ld_archflags
236                        }
237                    }]
238                }
239            }
240
241            eval [subst {
242                variant ${variant} description \
243                    {Build using the $cdb($variant,descrip) compiler} \
244                    conflicts $c {
245
246                    depends_build-append   $cdb($variant,depends)
247                    depends_lib-append     $cdb($variant,dependsl)
248                    depends_lib-delete     $cdb($variant,dependsd)
249                    depends_skip_archcheck $cdb($variant,dependsa)
250
251                    $comp
252                }
253            }]
254        }
255    }
256}
257
258foreach variant ${compilers.gcc_variants} {
259    # we need to check the default_variants so we can't use variant_isset
260    if {[info exists variations($variant)] && $variations($variant) eq "+"} {
261        depends_lib-delete      port:g95
262        break
263    }
264}
265
266proc c_active_variant_name {depspec} {
267    global compilers.variants compilers.fortran_variants
268    set c_list [remove_from_list ${compilers.variants} {gfortran g95}]
269
270    foreach c $c_list {
271        if {![catch {set result [active_variants $depspec $c ""]}]} {
272            if {$result} {
273                return $c
274            }
275        }
276    }
277
278    return ""
279}
280
281proc c_variant_name {} {
282    global compilers.variants compilers.fortran_variants
283    set c_list [remove_from_list ${compilers.variants} {gfortran g95}]
284
285    foreach cc $c_list {
286        if {[variant_isset $cc]} {
287            return $cc
288        }
289    }
290
291    return ""
292}
293
294proc fortran_active_variant_name {depspec} {
295    global compilers.fortran_variants
296
297    foreach fc ${compilers.fortran_variants} {
298        if {![catch {set result [active_variants $depspec $fc ""]}]} {
299            if {$result} {
300                return $fc
301            }
302        }
303    }
304
305    return ""
306}
307
308proc fortran_variant_name {} {
309    global compilers.fortran_variants variations
310
311    foreach fc ${compilers.fortran_variants} {
312        # we need to check the default_variants so we can't use variant_isset
313        if {[info exists variations($fc)] && $variations($fc) eq "+"} {
314            return $fc
315        }
316    }
317
318    return ""
319}
320
321proc clang_variant_name {} {
322    global compilers.clang_variants compilers.dragonegg_variants variations
323
324    foreach c ${compilers.clang_variants} {
325        # we need to check the default_variants so we can't use variant_isset
326        if {[info exists variations($c)] && $variations($c) eq "+"} {
327            return $c
328        }
329    }
330
331    foreach c ${compilers.dragonegg_variants} {
332        # we need to check the default_variants so we can't use variant_isset
333        if {[info exists variations($c)] && $variations($c) eq "+"} {
334            return $c
335        }
336    }
337
338    return ""
339}
340
341proc clang_variant_isset {} {
342    return [expr {[clang_variant_name] ne ""}]
343}
344
345proc gcc_variant_name {} {
346    global compilers.gcc_variants variations
347
348    foreach c ${compilers.gcc_variants} {
349        # we need to check the default_variants so we can't use variant_isset
350        if {[info exists variations($c)] && $variations($c) eq "+"} {
351            return $c
352        }
353    }
354
355    return ""
356}
357
358proc gcc_variant_isset {} {
359    return [expr {[gcc_variant_name] ne ""}]
360}
361
362proc avx_compiler_isset {} {
363    global configure.cc
364
365    set cc ${configure.cc}
366
367    # check for mpi
368    if {[string match *mpi* $cc]} {
369        set cc [exec ${configure.cc} -show]
370    }
371
372    if {[string match *clang* $cc]} {
373        return 1
374    }
375
376    return 0
377}
378
379proc fortran_variant_isset {} {
380    return [expr {[fortran_variant_name] ne ""}]
381}
382
383# remove all elements in R from L
384proc remove_from_list {L R} {
385    foreach e $R {
386        set idx [lsearch $L $e]
387        set L [lreplace $L $idx $idx]
388    }
389    return $L
390}
391
392# add all elements in R from L
393proc add_from_list {L A} {
394    return [concat $L $A]
395}
396
397proc compilers.choose {args} {
398    global compilers.list
399
400    # zero out the variable before and append args
401    set compilers.list {}
402    foreach v $args {
403        lappend compilers.list $v
404    }
405}
406
407proc compilers.is_fortran_only {} {
408    global compilers.list
409
410    foreach c {cc cxx cpp objc} {
411        if {[lsearch -exact ${compilers.list} $c] >= 0} {
412            return 0
413        }
414    }
415
416    return 1
417}
418
419proc compilers.is_c_only {} {
420    global compilers.list
421
422    foreach c {f77 f90 fc} {
423        if {[lsearch -exact ${compilers.list} $c] >= 0} {
424            return 0
425        }
426    }
427
428    return 1
429}
430
431# for the c compiler
432proc compilers.enforce_c {args} {
433    global compilers.required_c
434    set compilers.required_c $args
435}
436
437proc compilers.action_enforce_c {args} {
438    foreach portname $args {
439        if {![catch {set result [active_variants $portname "" ""]}]} {
440            set otcomp  [c_active_variant_name $portname]
441            set mycomp  [c_variant_name]
442
443            if {$otcomp ne "" && $mycomp eq ""} {
444                default_variants +$otcomp
445            } elseif {$otcomp ne $mycomp} {
446                ui_error "Install $portname +$mycomp"
447                return -code error "$portname +$mycomp not installed"
448            }
449        }
450    }
451}
452
453proc compilers.enforce_fortran {args} {
454    global compilers.required_f
455    set compilers.required_f $args
456}
457
458proc compilers.action_enforce_f {args} {
459    global compilers.gfortran_equiv
460    foreach portname $args {
461        if {![catch {set result [active_variants $portname "" ""]}]} {
462            set otf  [fortran_active_variant_name $portname]
463            set myf  [fortran_variant_name]
464
465            # gfortran is nothing more than the fortran compiler from a default version of gcc
466            set equiv 0
467            if {($otf eq ${compilers.gfortran_equiv} || $otf eq "gfortran") &&
468                ($myf eq ${compilers.gfortran_equiv} || $myf eq "gfortran")} {
469                set equiv 1
470            }
471
472            if {$otf ne "" && $myf eq ""} {
473                default_variants +$otf
474            } elseif {$otf ne $myf && !$equiv} {
475                ui_error "Install $portname +$myf"
476                return -code error "$portname +$myf not installed"
477            }
478        }
479    }
480}
481
482proc compilers.setup {args} {
483    global cdb compilers.variants compilers.clang_variants compilers.gcc_variants
484    global compilers.dragonegg_variants compilers.fortran_variants
485    global compilers.require_fortran compilers.setup_done compilers.list
486    global compiler.blacklist
487
488    if {!${compilers.setup_done}} {
489        set add_list {}
490        set remove_list ${compilers.variants}
491
492        # if we are only setting fortran compilers, then we are in "only fortran
493        # mode", i.e. we just need +gccXY and +dragoneggXY for the fortran
494        # compilers so we remove +clangXY and +llvm
495        if {[compilers.is_fortran_only]} {
496            # remove gfortran since that only exists to "complete" clang/llvm
497            set remove_list [remove_from_list ${compilers.fortran_variants} gfortran]
498        } elseif {[compilers.is_c_only]} {
499            # remove gfortran and g95 since those are purely for fortran
500            set remove_list [remove_from_list ${compilers.variants} {gfortran g95}]
501        }
502
503        foreach v $args {
504            # if any negated compiler (e.g. -gcc47) is specified then we are
505            # removing from the default, complete list
506            set mode add
507            if {[string first - $v] == 0} {
508                set mode remove
509
510                #strip the beginning '-' character
511                set v [string range $v 1 end]
512            }
513
514            # handle special cases, such as 'gcc' -> all gcc variants
515            switch -exact $v {
516                gcc {
517                    set ${mode}_list [${mode}_from_list [expr $${mode}_list] ${compilers.gcc_variants}]
518                }
519                dragonegg {
520                    set ${mode}_list [${mode}_from_list [expr $${mode}_list] ${compilers.dragonegg_variants}]
521                }
522                fortran {
523                    # here we just check gfortran and g95, not every fortran
524                    # compatible variant since it makes more sense to specify
525                    # 'fortran' to mean add just the +gfortran and +g95 variants
526                    set ${mode}_list [${mode}_from_list [expr $${mode}_list] {gfortran g95}]
527
528                }
529                clang {
530                    set ${mode}_list [${mode}_from_list [expr $${mode}_list] ${compilers.clang_variants}]
531                }
532                require_fortran {
533                    # this signals that fortran is required and not optional
534                    set compilers.require_fortran 1
535                }
536                default {
537                    if {[info exists cdb($v,variant)] == 0} {
538                        return -code error "no such compiler: $v"
539                    }
540                    set ${mode}_list [${mode}_from_list [expr $${mode}_list] $cdb($v,variant)]
541                }
542            }
543        }
544
545        # also remove compilers blacklisted
546        foreach compiler ${compiler.blacklist} {
547            set matched no
548            foreach variant ${compilers.variants} {
549                if {[string match $compiler $cdb($variant,compiler)]} {
550                    set matched yes
551                    set remove_list [remove_from_list $remove_list $cdb($variant,variant)]
552                }
553            }
554
555            if {!$matched} {
556                ui_debug "Unmatched blacklisted compiler: $compiler"
557            }
558        }
559
560        # remove duplicates
561        set duplicates {}
562        foreach foo $remove_list {
563            if {[lsearch $add_list $foo] != -1} {
564                lappend duplicates $foo
565            }
566        }
567
568        set compilers.variants [lsort [concat [remove_from_list $remove_list $duplicates] $add_list]]
569        eval compilers.setup_variants ${compilers.variants}
570
571        if {${compilers.require_fortran} && ![fortran_variant_isset]} {
572            if {[lsearch -exact ${compilers.variants} gfortran] > -1} {
573                default_variants-append +gfortran
574            } elseif {[lsearch -exact ${compilers.variants} gcc49] > -1} {
575                default_variants-append +gcc49
576            } elseif {[lsearch -exact ${compilers.variants} gcc48] > -1} {
577                default_variants-append +gcc48
578            } elseif {[lsearch -exact ${compilers.variants} gcc47] > -1} {
579                default_variants-append +gcc47
580            } elseif {[lsearch -exact ${compilers.variants} gcc46] > -1} {
581                default_variants-append +gcc46
582            } elseif {[lsearch -exact ${compilers.variants} gcc45] > -1} {
583                default_variants-append +gcc45
584            } elseif {[lsearch -exact ${compilers.variants} gcc44] > -1} {
585                default_variants-append +gcc44
586            } elseif {[lsearch -exact ${compilers.variants} g95] > -1} {
587                default_variants-append +g95
588            }
589        }
590
591        set compilers.setup_done 1
592    }
593}
594
595# this might also need to be in pre-archivefetch
596pre-fetch {
597    if {${compilers.require_fortran} && [fortran_variant_name] eq ""} {
598        return -code error "must set at least one fortran variant"
599    }
600    eval compilers.action_enforce_c ${compilers.required_c}
601    eval compilers.action_enforce_f ${compilers.required_f}
602}
Note: See TracBrowser for help on using the repository browser.