CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: Ardupilot/ardupilot
Path: blob/master/Tools/ardupilotwaf/toolchain.py
Views: 1798
1
"""
2
WAF Tool to select the correct toolchain based on the target archtecture.
3
4
This tool loads compiler_c and compiler_cxx, so you don't need to load them
5
(and you must not load them before this tool). Use the environment variable
6
TOOLCHAIN to define the toolchain.
7
8
Example::
9
10
def configure(cfg):
11
cfg.env.TOOLCHAIN = 'arm-linux-gnueabihf'
12
cfg.load('toolchain')
13
"""
14
15
from waflib import Errors, Context, Utils
16
from waflib.Configure import conf
17
from waflib.Tools import compiler_c, compiler_cxx
18
from waflib.Tools import clang, clangxx, gcc, gxx
19
from waflib.Tools import c_config
20
from waflib import Logs
21
22
import os
23
import re
24
import sys
25
26
@conf
27
def find_gxx(conf):
28
names = ['g++', 'c++']
29
if conf.env.TOOLCHAIN != 'native':
30
names = ['%s-%s' % (conf.env.TOOLCHAIN, n) for n in names]
31
cxx = conf.find_program(names, var='CXX')
32
conf.get_cc_version(cxx, gcc=True)
33
conf.env.CXX_NAME = 'gcc'
34
35
@conf
36
def find_gcc(conf):
37
names = ['gcc', 'cc']
38
if conf.env.TOOLCHAIN != 'native':
39
names = ['%s-%s' % (conf.env.TOOLCHAIN, n) for n in names]
40
cc = conf.find_program(names, var='CC')
41
conf.get_cc_version(cc, gcc=True)
42
conf.env.CC_NAME = 'gcc'
43
44
def _clang_cross_support(cfg):
45
if _clang_cross_support.called:
46
return
47
48
prefix = cfg.env.TOOLCHAIN + '-'
49
50
try:
51
cfg.find_program(prefix + 'gcc', var='CROSS_GCC')
52
except Errors.ConfigurationError as e:
53
cfg.fatal('toolchain: clang: couldn\'t find cross GCC', ex=e)
54
55
environ = dict(os.environ)
56
if 'TOOLCHAIN_CROSS_AR' in environ:
57
# avoid OS's environment to mess up toolchain path finding
58
del environ['TOOLCHAIN_CROSS_AR']
59
try:
60
cfg.find_program(
61
prefix + 'ar',
62
var='TOOLCHAIN_CROSS_AR',
63
environ=environ,
64
)
65
except Errors.ConfigurationError as e:
66
cfg.fatal('toolchain: clang: couldn\'t find toolchain path', ex=e)
67
68
toolchain_path = os.path.join(cfg.env.TOOLCHAIN_CROSS_AR[0], '..', '..')
69
toolchain_path = os.path.abspath(toolchain_path)
70
cfg.msg('Using toolchain path for clang', toolchain_path)
71
72
sysroot = cfg.cmd_and_log(
73
[cfg.env.CROSS_GCC[0], '--print-sysroot'],
74
quiet=Context.BOTH,
75
).strip()
76
77
cfg.env.CLANG_FLAGS = [
78
'--target=' + cfg.env.TOOLCHAIN,
79
'--gcc-toolchain=' + toolchain_path,
80
'--sysroot=' + sysroot,
81
'-B' + os.path.join(toolchain_path, 'bin')
82
]
83
84
_clang_cross_support.called = False
85
86
def _set_clang_crosscompilation_wrapper(tool_module):
87
original_configure = tool_module.configure
88
def new_configure(cfg):
89
if cfg.env.TOOLCHAIN == 'native':
90
original_configure(cfg)
91
return
92
93
cfg.env.stash()
94
try:
95
_clang_cross_support(cfg)
96
original_configure(cfg)
97
except Errors.ConfigurationError as e:
98
cfg.env.revert()
99
raise
100
else:
101
cfg.env.commit()
102
tool_module.configure = new_configure
103
104
_set_clang_crosscompilation_wrapper(clang)
105
_set_clang_crosscompilation_wrapper(clangxx)
106
107
def _filter_supported_c_compilers(*compilers):
108
for k in compiler_c.c_compiler:
109
l = compiler_c.c_compiler[k]
110
compiler_c.c_compiler[k] = [c for c in compilers if c in l]
111
112
def _filter_supported_cxx_compilers(*compilers):
113
for k in compiler_cxx.cxx_compiler:
114
l = compiler_cxx.cxx_compiler[k]
115
compiler_cxx.cxx_compiler[k] = [c for c in compilers if c in l]
116
117
def _set_pkgconfig_crosscompilation_wrapper(cfg):
118
original_validatecfg = cfg.validate_cfg
119
120
@conf
121
def new_validate_cfg(kw):
122
if 'path' not in kw:
123
if not cfg.env.PKGCONFIG:
124
cfg.find_program('%s-pkg-config' % cfg.env.TOOLCHAIN, var='PKGCONFIG')
125
kw['path'] = cfg.env.PKGCONFIG
126
127
original_validatecfg(kw)
128
129
cfg.validate_cfg = new_validate_cfg
130
131
def configure(cfg):
132
_filter_supported_c_compilers('gcc', 'clang')
133
_filter_supported_cxx_compilers('g++', 'clang++')
134
135
cfg.msg('Using toolchain', cfg.env.TOOLCHAIN)
136
if cfg.env.TOOLCHAIN == "custom":
137
return
138
139
if cfg.env.TOOLCHAIN == 'native':
140
cfg.load('compiler_cxx compiler_c')
141
142
if not cfg.options.disable_gccdeps:
143
cfg.load('gccdeps')
144
145
return
146
147
_set_pkgconfig_crosscompilation_wrapper(cfg)
148
if sys.platform.startswith("cygwin"):
149
# on cygwin arm-none-eabi-ar doesn't support the @FILE syntax for splitting long lines
150
cfg.find_program('ar', var='AR', quiet=True)
151
else:
152
cfg.find_program('%s-ar' % cfg.env.TOOLCHAIN, var='AR', quiet=True)
153
cfg.load('compiler_cxx compiler_c')
154
155
if sys.platform.startswith("cygwin"):
156
cfg.find_program('nm', var='NM')
157
else:
158
cfg.find_program('%s-nm' % cfg.env.TOOLCHAIN, var='NM')
159
160
if not cfg.options.disable_gccdeps:
161
cfg.load('gccdeps')
162
163
if cfg.env.COMPILER_CC == 'clang':
164
cfg.env.CFLAGS += cfg.env.CLANG_FLAGS
165
cfg.env.LINKFLAGS_cprogram += cfg.env.CLANG_FLAGS
166
167
if cfg.env.COMPILER_CXX == 'clang++':
168
cfg.env.CXXFLAGS += cfg.env.CLANG_FLAGS
169
cfg.env.LINKFLAGS_cxxprogram += cfg.env.CLANG_FLAGS
170
171