third_party:waf: update to upstream 2.0.4 release
[amitay/samba.git] / third_party / waf / waflib / extras / cross_gnu.py
1 #! /usr/bin/env python
2 # encoding: utf-8
3 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
4
5 #!/usr/bin/python
6 # -*- coding: utf-8 vi:ts=4:noexpandtab
7 # Tool to provide dedicated variables for cross-compilation
8
9 __author__ = __maintainer__ = "Jérôme Carretero <cJ-waf@zougloub.eu>"
10 __copyright__ = "Jérôme Carretero, 2014"
11
12 """
13 This tool allows to use environment variables to define cross-compilation
14 variables intended for build variants.
15
16 The variables are obtained from the environment in 3 ways:
17
18 1. By defining CHOST, they can be derived as ${CHOST}-${TOOL}
19 2. By defining HOST_x
20 3. By defining ${CHOST//-/_}_x
21
22 else one can set ``cfg.env.CHOST`` in ``wscript`` before loading ``cross_gnu``.
23
24 Usage:
25
26 - In your build script::
27
28         def configure(cfg):
29                 ...
30                 for variant in x_variants:
31                         setenv(variant)
32                         conf.load('cross_gnu')
33                         conf.xcheck_host_var('POUET')
34                         ...
35
36
37 - Then::
38
39         CHOST=arm-hardfloat-linux-gnueabi waf configure
40         env arm-hardfloat-linux-gnueabi-CC="clang -..." waf configure
41         CFLAGS=... CHOST=arm-hardfloat-linux-gnueabi HOST_CFLAGS=-g waf configure
42         HOST_CC="clang -..." waf configure
43
44 This example ``wscript`` compiles to Microchip PIC (xc16-gcc-xyz must be in PATH):
45
46 .. code:: python
47
48                 from waflib import Configure
49
50                 #from https://gist.github.com/rpuntaie/2bddfb5d7b77db26415ee14371289971
51                 import waf_variants
52
53                 variants='pc fw/variant1 fw/variant2'.split()
54
55                 top = "."
56                 out = "../build"
57
58                 PIC = '33FJ128GP804' #dsPICxxx
59
60                 @Configure.conf
61                 def gcc_modifier_xc16(cfg):
62                                 v = cfg.env
63                                 v.cprogram_PATTERN = '%s.elf'
64                                 v.LINKFLAGS_cprogram = ','.join(['-Wl','','','--defsym=__MPLAB_BUILD=0','','--script=p'+PIC+'.gld',
65                                                 '--stack=16','--check-sections','--data-init','--pack-data','--handles','--isr','--no-gc-sections',
66                                                 '--fill-upper=0','--stackguard=16','--no-force-link','--smart-io']) #,'--report-mem'])
67                                 v.CFLAGS_cprogram=['-mcpu='+PIC,'-omf=elf','-mlarge-code','-msmart-io=1',
68                                                 '-msfr-warn=off','-mno-override-inline','-finline','-Winline']
69
70                 def configure(cfg):
71                                 if 'fw' in cfg.variant: #firmware
72                                                 cfg.env.DEST_OS = 'xc16' #cfg.env.CHOST = 'xc16' #works too
73                                                 cfg.load('c cross_gnu') #cfg.env.CHOST becomes ['xc16']
74                                                 ...
75                                 else: #configure for pc SW
76                                                 ...
77
78                 def build(bld):
79                                 if 'fw' in bld.variant: #firmware
80                                                 bld.program(source='maintst.c', target='maintst');
81                                                 bld(source='maintst.elf', target='maintst.hex', rule="xc16-bin2hex ${SRC} -a -omf=elf")
82                                 else: #build for pc SW
83                                                 ...
84
85 """
86
87 import os
88 from waflib import Utils, Configure
89 from waflib.Tools import ccroot, gcc
90
91 try:
92         from shlex import quote
93 except ImportError:
94         from pipes import quote
95
96 def get_chost_stuff(conf):
97         """
98         Get the CHOST environment variable contents
99         """
100         chost = None
101         chost_envar = None
102         if conf.env.CHOST:
103                 chost = conf.env.CHOST[0]
104                 chost_envar = chost.replace('-', '_')
105         return chost, chost_envar
106
107
108 @Configure.conf
109 def xcheck_var(conf, name, wafname=None, cross=False):
110         wafname = wafname or name
111
112         if wafname in conf.env:
113                 value = conf.env[wafname]
114                 if isinstance(value, str):
115                         value = [value]
116         else:
117                 envar = os.environ.get(name)
118                 if not envar:
119                         return
120                 value = Utils.to_list(envar) if envar != '' else [envar]
121
122         conf.env[wafname] = value
123         if cross:
124                 pretty = 'cross-compilation %s' % wafname
125         else:
126                 pretty = wafname
127         conf.msg('Will use %s' % pretty, " ".join(quote(x) for x in value))
128
129 @Configure.conf
130 def xcheck_host_prog(conf, name, tool, wafname=None):
131         wafname = wafname or name
132
133         chost, chost_envar = get_chost_stuff(conf)
134
135         specific = None
136         if chost:
137                 specific = os.environ.get('%s_%s' % (chost_envar, name))
138
139         if specific:
140                 value = Utils.to_list(specific)
141                 conf.env[wafname] += value
142                 conf.msg('Will use cross-compilation %s from %s_%s' % (name, chost_envar, name),
143                  " ".join(quote(x) for x in value))
144                 return
145         else:
146                 envar = os.environ.get('HOST_%s' % name)
147                 if envar is not None:
148                         value = Utils.to_list(envar)
149                         conf.env[wafname] = value
150                         conf.msg('Will use cross-compilation %s from HOST_%s' % (name, name),
151                          " ".join(quote(x) for x in value))
152                         return
153
154         if conf.env[wafname]:
155                 return
156
157         value = None
158         if chost:
159                 value = '%s-%s' % (chost, tool)
160
161         if value:
162                 conf.env[wafname] = value
163                 conf.msg('Will use cross-compilation %s from CHOST' % wafname, value)
164
165 @Configure.conf
166 def xcheck_host_envar(conf, name, wafname=None):
167         wafname = wafname or name
168
169         chost, chost_envar = get_chost_stuff(conf)
170
171         specific = None
172         if chost:
173                 specific = os.environ.get('%s_%s' % (chost_envar, name))
174
175         if specific:
176                 value = Utils.to_list(specific)
177                 conf.env[wafname] += value
178                 conf.msg('Will use cross-compilation %s from %s_%s' \
179                  % (name, chost_envar, name),
180                  " ".join(quote(x) for x in value))
181                 return
182
183
184         envar = os.environ.get('HOST_%s' % name)
185         if envar is None:
186                 return
187
188         value = Utils.to_list(envar) if envar != '' else [envar]
189
190         conf.env[wafname] = value
191         conf.msg('Will use cross-compilation %s from HOST_%s' % (name, name),
192          " ".join(quote(x) for x in value))
193
194
195 @Configure.conf
196 def xcheck_host(conf):
197         conf.xcheck_var('CHOST', cross=True)
198         conf.env.CHOST = conf.env.CHOST or [conf.env.DEST_OS]
199         conf.env.DEST_OS = conf.env.CHOST[0].replace('-','_')
200         conf.xcheck_host_prog('CC', 'gcc')
201         conf.xcheck_host_prog('CXX', 'g++')
202         conf.xcheck_host_prog('LINK_CC', 'gcc')
203         conf.xcheck_host_prog('LINK_CXX', 'g++')
204         conf.xcheck_host_prog('AR', 'ar')
205         conf.xcheck_host_prog('AS', 'as')
206         conf.xcheck_host_prog('LD', 'ld')
207         conf.xcheck_host_envar('CFLAGS')
208         conf.xcheck_host_envar('CXXFLAGS')
209         conf.xcheck_host_envar('LDFLAGS', 'LINKFLAGS')
210         conf.xcheck_host_envar('LIB')
211         conf.xcheck_host_envar('PKG_CONFIG_LIBDIR')
212         conf.xcheck_host_envar('PKG_CONFIG_PATH')
213
214         if not conf.env.env:
215                 conf.env.env = {}
216                 conf.env.env.update(os.environ)
217         if conf.env.PKG_CONFIG_LIBDIR:
218                 conf.env.env['PKG_CONFIG_LIBDIR'] = conf.env.PKG_CONFIG_LIBDIR[0]
219         if conf.env.PKG_CONFIG_PATH:
220                 conf.env.env['PKG_CONFIG_PATH'] = conf.env.PKG_CONFIG_PATH[0]
221
222 def configure(conf):
223         """
224         Configuration example for gcc, it will not work for g++/clang/clang++
225         """
226         conf.xcheck_host()
227         conf.gcc_common_flags()
228         conf.gcc_modifier_platform()
229         conf.cc_load_tools()
230         conf.cc_add_flags()
231         conf.link_add_flags()