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