Sync Mk with ports
[dports.git] / Mk / Uses / compiler.mk
1 # $FreeBSD$
2 #
3 # Allows to determine the compiler being used
4 #
5 # Feature:      compiler
6 # Usage:        USES=compiler or USES=compiler:ARGS
7 # Valid ARGS:   env (default, implicit) c++0x c++11-lib c++11-lang c11 openmp nestedfct features
8 #
9 # c++0x:        The port needs a compiler understanding C++0X
10 # c++11-lang:   The port needs a compiler understanding C++11
11 # c++14-lang:   The port needs a compiler understanding C++14
12 # gcc-c++11-lib:The port needs g++ compiler with a C++11 library
13 # c++11-lib:    The port needs a compiler understanding C++11 and with a C++11 ready standard library
14 # c11:          The port needs a compiler understanding C11
15 # openmp:       The port needs a compiler understanding openmp
16 # nestedfct:    The port needs a compiler understanding nested functions
17 # features:     The port will determine the features supported by the default compiler
18 #
19 # Variable to test after <bsd.port.pre.mk>
20 #
21 # COMPILER_TYPE:        can be gcc or clang
22 # ALT_COMPILER_TYPE:    can be gcc or clang depending on COMPILER_TYPE, only set if the base system has 2 compilers
23 # COMPILER_VERSION:     first 2 digits of the version: 33 for clang 3.3.*, 47 for gcc 4.7.*
24 # ALT_COMPILER_VERSION: first 2 digits of the version: 33 for clang 3.3.*, 47 for gcc 4.7.* of the ALT_COMPILER_TYPE
25 #
26 # COMPILER_FEATURES:    the list of features supported by the compiler includes the standard C++ library.
27 # CHOSEN_COMPILER_TYPE: can be gcc or clang (type of compiler chosen by the framework)
28 #
29 # MAINTAINER: portmgr@FreeBSD.org
30
31 .if !defined(_INCLUDE_USES_COMPILER_MK)
32 _INCLUDE_USES_COMPILER_MK=      yes
33
34 .if empty(compiler_ARGS)
35 compiler_ARGS=  env
36 .endif
37
38 VALID_ARGS=     c++11-lib c++11-lang c++14-lang c11 features openmp env nestedfct c++0x gcc-c++11-lib
39
40 .if ${compiler_ARGS} == gcc-c++11-lib
41 _COMPILER_ARGS+=        features gcc-c++11-lib
42 .elif ${compiler_ARGS} == c++11-lib
43 _COMPILER_ARGS+=        features c++11-lib
44 .elif ${compiler_ARGS} == c++0x
45 _COMPILER_ARGS+=        features c++0x
46 .elif ${compiler_ARGS} == c++11-lang
47 _COMPILER_ARGS+=        features c++11-lang
48 .elif ${compiler_ARGS} == c++14-lang
49 _COMPILER_ARGS+=        features c++14-lang
50 .elif ${compiler_ARGS} == c11
51 _COMPILER_ARGS+=        features c11
52 .elif ${compiler_ARGS} == features
53 _COMPILER_ARGS+=        features
54 .elif ${compiler_ARGS} == env
55 _COMPILER_ARGS+=        env
56 .elif ${compiler_ARGS} == openmp
57 _COMPILER_ARGS+=        env openmp
58 .elif ${compiler_ARGS} == nestedfct
59 _COMPILER_ARGS+=        env nestedfct
60 .else
61 IGNORE= Invalid argument "${compiler_ARGS}", valid arguments are: ${VALID_ARGS}
62 _COMPILER_ARGS= #
63 .endif
64
65 .if ${_COMPILER_ARGS:Mc++*} || ${_COMPILER_ARGS:Mc11}
66 _COMPILER_ARGS+=        features
67 .endif
68
69 .if ${CC} == cc 
70 # This is the DragonFly base compiler, we know it's gcc (for now)
71 COMPILER_TYPE=          gcc
72 COMPILER_VERSION=       53
73 .else
74 _CCVERSION!=    ${CC} --version
75 .if defined(.PARSEDIR)
76 COMPILER_VERSION=       ${_CCVERSION:M[0-9].[0-9]*:tW:C/([0-9]).([0-9]).*/\1\2/g}
77 .else
78 COMPILER_VERSION=       ${_CCVERSION:M[0-9].[0-9]*:C/([0-9]).([0-9]).*/\1\2/g:u}
79 .endif
80 .if ${_CCVERSION:Mclang}
81 COMPILER_TYPE=  clang
82 .else
83 COMPILER_TYPE=  gcc
84 .endif
85 .endif
86
87 ALT_COMPILER_VERSION=   0
88 ALT_COMPILER_TYPE=      none
89 _ALTCCVERSION=  
90 .if ${COMPILER_TYPE} == gcc && exists(/usr/bin/clang)
91 .if ${ARCH} == amd64 || ${ARCH} == i386 # clang often non-default for a reason
92 _ALTCCVERSION!= /usr/bin/clang --version
93 .endif
94 .elif ${COMPILER_TYPE} == clang && exists(/usr/bin/gcc)
95 _ALTCCVERSION!= /usr/bin/gcc --version
96 .endif
97
98 .if defined(.PARSEDIR)
99 ALT_COMPILER_VERSION=   ${_ALTCCVERSION:M[0-9].[0-9]*:tW:C/([0-9]).([0-9]).*/\1\2/g}
100 .else
101 ALT_COMPILER_VERSION=   ${_ALTCCVERSION:M[0-9].[0-9]*:C/([0-9]).([0-9]).*/\1\2/g:u}
102 .endif
103 .if ${_ALTCCVERSION:Mclang}
104 ALT_COMPILER_TYPE=      clang
105 .elif !empty(_ALTCCVERSION)
106 ALT_COMPILER_TYPE=      gcc
107 .endif
108
109 CHOSEN_COMPILER_TYPE=   ${COMPILER_TYPE}
110
111 .if ${_COMPILER_ARGS:Mopenmp}
112 .if ${COMPILER_TYPE} == clang
113 USE_GCC=        yes
114 CHOSEN_COMPILER_TYPE=   gcc
115 .endif
116 .endif
117
118 .if ${_COMPILER_ARGS:Mnestedfct}
119 .if ${COMPILER_TYPE} == clang
120 USE_GCC=        any
121 CHOSEN_COMPILER_TYPE=   gcc
122 .endif
123 .endif
124
125 .if ${_COMPILER_ARGS:Mfeatures}
126 .  if ${CC} == cc && ${CXX} == c++
127    # This is DragonFly's base gcc50 compiler
128    # Use a cache for DF rather than testing each feature.
129 COMPILER_FEATURES=      libstdc++ c89 c99 c11 gnu89 gnu99 gnu11 c++98 \
130                         c++0x c++11 c++14 gnu++98 gnu++11 dragonfly
131 .  else
132 _CXXINTERNAL!=  ${CXX} -\#\#\# /dev/null 2>&1
133 .if ${_CXXINTERNAL:M\"-lc++\"}
134 COMPILER_FEATURES=      libc++
135 .else
136 COMPILER_FEATURES=      libstdc++
137 .endif
138
139 CSTD=   c89 c99 c11 gnu89 gnu99 gnu11
140 CXXSTD= c++98 c++0x c++11 c++14 gnu++98 gnu++11
141
142 .for std in ${CSTD} ${CXXSTD}
143 _LANG=c
144 .if ${CXXSTD:M${std}}
145 _LANG=c++
146 .endif
147 OUTPUT_${std}!= echo | ${CC} -std=${std} -c -x ${_LANG} /dev/null -o /dev/null 2>&1; echo
148 .if !${OUTPUT_${std}:M*error*}
149 COMPILER_FEATURES+=     ${std}
150 .endif
151 .endfor
152 .  endif        # DragonFly base compiler
153 .endif
154
155 .if ${_COMPILER_ARGS:Mc++11-lib}
156 .if !${COMPILER_FEATURES:Mc++11}
157 USE_GCC=        yes
158 CHOSEN_COMPILER_TYPE=   gcc
159 .elif ${COMPILER_TYPE} == clang && ${COMPILER_FEATURES:Mlibstdc++}
160 USE_GCC=        yes
161 CHOSEN_COMPILER_TYPE=   gcc
162 .endif
163 .endif
164
165 .if ${_COMPILER_ARGS:Mc++14-lang}
166 .if !${COMPILER_FEATURES:Mc++14}
167 .if (defined(FAVORITE_COMPILER) && ${FAVORITE_COMPILER} == gcc) || (${ARCH} != amd64 && ${ARCH} != i386) # clang not always supported on Tier-2
168 USE_GCC=        5+
169 CHOSEN_COMPILER_TYPE=   gcc
170 .elif (${COMPILER_TYPE} == clang && ${COMPILER_VERSION} < 35) || ${COMPILER_TYPE} == gcc
171 .if ${ALT_COMPILER_TYPE} == clang && ${ALT_COMPILER_VERSION} >= 35
172 CPP=    clang-cpp
173 CC=     clang
174 CXX=    clang++
175 CHOSEN_COMPILER_TYPE=   clang
176 .else
177 BUILD_DEPENDS+= ${LOCALBASE}/bin/clang36:lang/clang36
178 CPP=    ${LOCALBASE}/bin/clang-cpp36
179 CC=     ${LOCALBASE}/bin/clang36
180 CXX=    ${LOCALBASE}/bin/clang++36
181 CHOSEN_COMPILER_TYPE=   clang
182 .endif
183 .endif
184 .endif
185 .endif
186
187 .if ${_COMPILER_ARGS:Mc++11-lang}
188 .if !${COMPILER_FEATURES:Mc++11}
189 .if (defined(FAVORITE_COMPILER) && ${FAVORITE_COMPILER} == gcc) || (${ARCH} != amd64 && ${ARCH} != i386) # clang not always supported on Tier-2
190 USE_GCC=        yes
191 CHOSEN_COMPILER_TYPE=   gcc
192 .elif (${COMPILER_TYPE} == clang && ${COMPILER_VERSION} < 34) || ${COMPILER_TYPE} == gcc
193 .if ${ALT_COMPILER_TYPE} == clang && ${ALT_COMPILER_VERSION} >= 34
194 CPP=    clang-cpp
195 CC=     clang
196 CXX=    clang++
197 CHOSEN_COMPILER_TYPE=   clang
198 .else
199 BUILD_DEPENDS+= ${LOCALBASE}/bin/clang38:lang/clang38
200 CPP=    ${LOCALBASE}/bin/clang-cpp38
201 CC=     ${LOCALBASE}/bin/clang38
202 CXX=    ${LOCALBASE}/bin/clang++38
203 CHOSEN_COMPILER_TYPE=   clang
204 .endif
205 .endif
206 .endif
207 .endif
208
209 .if ${_COMPILER_ARGS:Mc++0x}
210 .if !${COMPILER_FEATURES:Mc++0x}
211 .if (defined(FAVORITE_COMPILER) && ${FAVORITE_COMPILER} == gcc) || (${ARCH} != amd64 && ${ARCH} != i386) # clang not always supported on Tier-2
212 USE_GCC=        yes
213 CHOSEN_COMPILER_TYPE=   gcc
214 .elif (${COMPILER_TYPE} == clang && ${COMPILER_VERSION} < 34) || ${COMPILER_TYPE} == gcc
215 .if ${ALT_COMPILER_TYPE} == clang && ${ALT_COMPILER_VERSION} >= 34
216 CPP=    clang-cpp
217 CC=     clang
218 CXX=    clang++
219 CHOSEN_COMPILER_TYPE=   clang
220 .else
221 BUILD_DEPENDS+= ${LOCALBASE}/bin/clang38:lang/clang38
222 CHOSEN_COMPILER_TYPE=   clang
223 CPP=    ${LOCALBASE}/bin/clang-cpp38
224 CC=     ${LOCALBASE}/bin/clang38
225 CXX=    ${LOCALBASE}/bin/clang++38
226 .endif
227 .endif
228 .endif
229 .endif
230
231 .if ${_COMPILER_ARGS:Mc11}
232 .if !${COMPILER_FEATURES:Mc11}
233 .if (defined(FAVORITE_COMPILER) && ${FAVORITE_COMPILER} == gcc) || (${ARCH} != amd64 && ${ARCH} != i386) # clang not always supported on Tier-2
234 USE_GCC=        yes
235 CHOSEN_COMPILER_TYPE=   gcc
236 .elif (${COMPILER_TYPE} == clang && ${COMPILER_VERSION} < 34) || ${COMPILER_TYPE} == gcc
237 .if ${ALT_COMPILER_TYPE} == clang && ${ALT_COMPILER_VERSION} >= 34
238 CPP=    clang-cpp
239 CC=     clang
240 CXX=    clang++
241 CHOSEN_COMPILER_TYPE=   clang
242 .else
243 BUILD_DEPENDS+= ${LOCALBASE}/bin/clang38:lang/clang38
244 CHOSEN_COMPILER_TYPE=   clang
245 CPP=    ${LOCALBASE}/bin/clang-cpp38
246 CC=     ${LOCALBASE}/bin/clang38
247 CXX=    ${LOCALBASE}/bin/clang++38
248 .endif
249 .endif
250 .endif
251 .endif
252
253 .if ${_COMPILER_ARGS:Mgcc-c++11-lib}
254 USE_GCC=        yes
255 CHOSEN_COMPILER_TYPE=   gcc
256 .if ${COMPILER_FEATURES:Mlibc++}
257 LDFLAGS+=       -L${LOCALBASE}/lib/c++
258 CXXFLAGS+=      -nostdinc++ -isystem ${LOCALBASE}/include/c++/v1
259 BUILD_DEPENDS+= ${LOCALBASE}/lib/c++/libstdc++.so:devel/libc++
260 .endif
261 .endif
262
263 .endif