2015-11-30 17:13:20 -04:00
|
|
|
"""
|
|
|
|
WAF Tool to select the correct toolchain based on the target archtecture.
|
|
|
|
|
2016-03-21 20:55:23 -03:00
|
|
|
This tool loads compiler_c and compiler_cxx, so you don't need to load them
|
|
|
|
(and you must not load them before this tool). Use the environment variable
|
|
|
|
TOOLCHAIN to define the toolchain.
|
2015-11-30 17:13:20 -04:00
|
|
|
|
|
|
|
Example::
|
|
|
|
|
|
|
|
def configure(cfg):
|
|
|
|
cfg.env.TOOLCHAIN = 'arm-linux-gnueabihf'
|
|
|
|
cfg.load('toolchain')
|
|
|
|
"""
|
|
|
|
|
2016-03-21 21:13:05 -03:00
|
|
|
from waflib import Errors, Context, Utils
|
2016-05-20 09:22:30 -03:00
|
|
|
from waflib.Configure import conf
|
2016-03-23 16:48:46 -03:00
|
|
|
from waflib.Tools import compiler_c, compiler_cxx
|
2016-03-22 19:28:19 -03:00
|
|
|
from waflib.Tools import clang, clangxx, gcc, gxx
|
2018-09-02 14:05:27 -03:00
|
|
|
from waflib.Tools import c_config
|
2018-01-23 11:27:18 -04:00
|
|
|
from waflib import Logs
|
2016-03-08 20:11:09 -04:00
|
|
|
|
|
|
|
import os
|
2016-05-20 09:22:30 -03:00
|
|
|
import re
|
2021-04-20 01:22:42 -03:00
|
|
|
import sys
|
2015-11-30 17:13:20 -04:00
|
|
|
|
2016-08-03 15:50:37 -03:00
|
|
|
@conf
|
|
|
|
def find_gxx(conf):
|
|
|
|
names = ['g++', 'c++']
|
|
|
|
if conf.env.TOOLCHAIN != 'native':
|
|
|
|
names = ['%s-%s' % (conf.env.TOOLCHAIN, n) for n in names]
|
|
|
|
cxx = conf.find_program(names, var='CXX')
|
|
|
|
conf.get_cc_version(cxx, gcc=True)
|
|
|
|
conf.env.CXX_NAME = 'gcc'
|
|
|
|
|
|
|
|
@conf
|
|
|
|
def find_gcc(conf):
|
|
|
|
names = ['gcc', 'cc']
|
|
|
|
if conf.env.TOOLCHAIN != 'native':
|
|
|
|
names = ['%s-%s' % (conf.env.TOOLCHAIN, n) for n in names]
|
|
|
|
cc = conf.find_program(names, var='CC')
|
|
|
|
conf.get_cc_version(cc, gcc=True)
|
|
|
|
conf.env.CC_NAME = 'gcc'
|
2016-03-21 21:13:05 -03:00
|
|
|
|
2016-03-22 19:28:19 -03:00
|
|
|
def _clang_cross_support(cfg):
|
|
|
|
if _clang_cross_support.called:
|
2016-03-21 19:54:52 -03:00
|
|
|
return
|
|
|
|
|
2016-03-22 19:28:19 -03:00
|
|
|
prefix = cfg.env.TOOLCHAIN + '-'
|
|
|
|
|
2016-03-29 12:42:37 -03:00
|
|
|
try:
|
|
|
|
cfg.find_program(prefix + 'gcc', var='CROSS_GCC')
|
|
|
|
except Errors.ConfigurationError as e:
|
|
|
|
cfg.fatal('toolchain: clang: couldn\'t find cross GCC', ex=e)
|
2016-03-22 19:28:19 -03:00
|
|
|
|
2016-03-23 08:37:02 -03:00
|
|
|
environ = dict(os.environ)
|
|
|
|
if 'TOOLCHAIN_CROSS_AR' in environ:
|
|
|
|
# avoid OS's environment to mess up toolchain path finding
|
|
|
|
del environ['TOOLCHAIN_CROSS_AR']
|
|
|
|
try:
|
|
|
|
cfg.find_program(
|
|
|
|
prefix + 'ar',
|
|
|
|
var='TOOLCHAIN_CROSS_AR',
|
|
|
|
environ=environ,
|
|
|
|
)
|
|
|
|
except Errors.ConfigurationError as e:
|
|
|
|
cfg.fatal('toolchain: clang: couldn\'t find toolchain path', ex=e)
|
|
|
|
|
|
|
|
toolchain_path = os.path.join(cfg.env.TOOLCHAIN_CROSS_AR[0], '..', '..')
|
|
|
|
toolchain_path = os.path.abspath(toolchain_path)
|
2016-03-22 19:28:19 -03:00
|
|
|
cfg.msg('Using toolchain path for clang', toolchain_path)
|
2016-03-21 19:54:52 -03:00
|
|
|
|
2016-03-22 19:28:19 -03:00
|
|
|
sysroot = cfg.cmd_and_log(
|
|
|
|
[cfg.env.CROSS_GCC[0], '--print-sysroot'],
|
|
|
|
quiet=Context.BOTH,
|
|
|
|
).strip()
|
2016-03-21 19:54:52 -03:00
|
|
|
|
2016-03-22 19:28:19 -03:00
|
|
|
cfg.env.CLANG_FLAGS = [
|
|
|
|
'--target=' + cfg.env.TOOLCHAIN,
|
|
|
|
'--gcc-toolchain=' + toolchain_path,
|
|
|
|
'--sysroot=' + sysroot,
|
|
|
|
'-B' + os.path.join(toolchain_path, 'bin')
|
|
|
|
]
|
2016-03-21 19:54:52 -03:00
|
|
|
|
2016-03-22 19:28:19 -03:00
|
|
|
_clang_cross_support.called = False
|
|
|
|
|
|
|
|
def _set_clang_crosscompilation_wrapper(tool_module):
|
|
|
|
original_configure = tool_module.configure
|
|
|
|
def new_configure(cfg):
|
|
|
|
if cfg.env.TOOLCHAIN == 'native':
|
|
|
|
original_configure(cfg)
|
|
|
|
return
|
2016-03-21 19:54:52 -03:00
|
|
|
|
2016-03-22 19:28:19 -03:00
|
|
|
cfg.env.stash()
|
|
|
|
try:
|
|
|
|
_clang_cross_support(cfg)
|
|
|
|
original_configure(cfg)
|
|
|
|
except Errors.ConfigurationError as e:
|
|
|
|
cfg.env.revert()
|
|
|
|
raise
|
|
|
|
else:
|
|
|
|
cfg.env.commit()
|
|
|
|
tool_module.configure = new_configure
|
2016-03-21 19:54:52 -03:00
|
|
|
|
2016-03-22 19:28:19 -03:00
|
|
|
_set_clang_crosscompilation_wrapper(clang)
|
|
|
|
_set_clang_crosscompilation_wrapper(clangxx)
|
2016-03-21 19:54:52 -03:00
|
|
|
|
2016-03-23 16:48:46 -03:00
|
|
|
def _filter_supported_c_compilers(*compilers):
|
|
|
|
for k in compiler_c.c_compiler:
|
|
|
|
l = compiler_c.c_compiler[k]
|
2016-10-14 17:00:51 -03:00
|
|
|
compiler_c.c_compiler[k] = [c for c in compilers if c in l]
|
2016-03-23 16:48:46 -03:00
|
|
|
|
|
|
|
def _filter_supported_cxx_compilers(*compilers):
|
|
|
|
for k in compiler_cxx.cxx_compiler:
|
|
|
|
l = compiler_cxx.cxx_compiler[k]
|
2016-10-14 17:00:51 -03:00
|
|
|
compiler_cxx.cxx_compiler[k] = [c for c in compilers if c in l]
|
2016-03-23 16:48:46 -03:00
|
|
|
|
2018-09-02 14:05:27 -03:00
|
|
|
def _set_pkgconfig_crosscompilation_wrapper(cfg):
|
|
|
|
original_validatecfg = cfg.validate_cfg
|
2016-05-20 09:22:30 -03:00
|
|
|
|
2018-09-02 14:05:27 -03:00
|
|
|
@conf
|
|
|
|
def new_validate_cfg(kw):
|
2023-08-31 18:46:25 -03:00
|
|
|
if 'path' not in kw:
|
2018-09-02 14:05:27 -03:00
|
|
|
if not cfg.env.PKGCONFIG:
|
|
|
|
cfg.find_program('%s-pkg-config' % cfg.env.TOOLCHAIN, var='PKGCONFIG')
|
|
|
|
kw['path'] = cfg.env.PKGCONFIG
|
2016-05-20 09:22:30 -03:00
|
|
|
|
2018-09-02 14:05:27 -03:00
|
|
|
original_validatecfg(kw)
|
2016-05-20 09:22:30 -03:00
|
|
|
|
2018-09-02 14:05:27 -03:00
|
|
|
cfg.validate_cfg = new_validate_cfg
|
2016-05-20 09:22:30 -03:00
|
|
|
|
2016-03-22 19:28:19 -03:00
|
|
|
def configure(cfg):
|
2018-01-23 11:27:18 -04:00
|
|
|
_filter_supported_c_compilers('gcc', 'clang')
|
|
|
|
_filter_supported_cxx_compilers('g++', 'clang++')
|
|
|
|
|
2019-02-21 10:33:37 -04:00
|
|
|
cfg.msg('Using toolchain', cfg.env.TOOLCHAIN)
|
2024-07-05 20:13:29 -03:00
|
|
|
if cfg.env.TOOLCHAIN == "custom":
|
|
|
|
return
|
2019-02-21 10:33:37 -04:00
|
|
|
|
2016-03-22 19:28:19 -03:00
|
|
|
if cfg.env.TOOLCHAIN == 'native':
|
2018-09-02 11:30:47 -03:00
|
|
|
cfg.load('compiler_cxx compiler_c')
|
|
|
|
|
|
|
|
if not cfg.options.disable_gccdeps:
|
|
|
|
cfg.load('gccdeps')
|
|
|
|
|
2016-03-22 19:28:19 -03:00
|
|
|
return
|
2016-03-21 20:55:23 -03:00
|
|
|
|
2018-09-02 14:05:27 -03:00
|
|
|
_set_pkgconfig_crosscompilation_wrapper(cfg)
|
2021-04-22 06:04:16 -03:00
|
|
|
if sys.platform.startswith("cygwin"):
|
2021-04-20 01:22:42 -03:00
|
|
|
# on cygwin arm-none-eabi-ar doesn't support the @FILE syntax for splitting long lines
|
|
|
|
cfg.find_program('ar', var='AR', quiet=True)
|
|
|
|
else:
|
|
|
|
cfg.find_program('%s-ar' % cfg.env.TOOLCHAIN, var='AR', quiet=True)
|
2018-09-02 11:30:47 -03:00
|
|
|
cfg.load('compiler_cxx compiler_c')
|
|
|
|
|
2024-05-27 01:35:34 -03:00
|
|
|
if sys.platform.startswith("cygwin"):
|
|
|
|
cfg.find_program('nm', var='NM')
|
|
|
|
else:
|
|
|
|
cfg.find_program('%s-nm' % cfg.env.TOOLCHAIN, var='NM')
|
2024-05-27 00:58:49 -03:00
|
|
|
|
2018-09-02 11:30:47 -03:00
|
|
|
if not cfg.options.disable_gccdeps:
|
|
|
|
cfg.load('gccdeps')
|
2016-03-22 19:28:19 -03:00
|
|
|
|
|
|
|
if cfg.env.COMPILER_CC == 'clang':
|
|
|
|
cfg.env.CFLAGS += cfg.env.CLANG_FLAGS
|
|
|
|
cfg.env.LINKFLAGS_cprogram += cfg.env.CLANG_FLAGS
|
|
|
|
|
|
|
|
if cfg.env.COMPILER_CXX == 'clang++':
|
|
|
|
cfg.env.CXXFLAGS += cfg.env.CLANG_FLAGS
|
|
|
|
cfg.env.LINKFLAGS_cxxprogram += cfg.env.CLANG_FLAGS
|