2016-08-04 06:51:47 +00:00
|
|
|
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
|
|
|
# vim: set filetype=python:
|
|
|
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
|
2017-10-12 13:22:59 +00:00
|
|
|
|
2016-08-04 06:51:47 +00:00
|
|
|
@template
|
|
|
|
@imports("textwrap")
|
2016-10-13 03:45:24 +00:00
|
|
|
@imports(_from="mozbuild.configure", _import="SandboxDependsFunction")
|
2017-08-18 16:05:05 +00:00
|
|
|
def compiler_class(compiler, host_or_target):
|
|
|
|
is_target = host_or_target is target
|
|
|
|
|
2016-10-13 03:45:24 +00:00
|
|
|
class Compiler(SandboxDependsFunction):
|
2024-02-10 18:28:42 +00:00
|
|
|
def _try_compile_or_link(
|
|
|
|
self,
|
|
|
|
includes,
|
|
|
|
body,
|
|
|
|
flags,
|
|
|
|
ldflags,
|
|
|
|
check_msg,
|
|
|
|
when,
|
|
|
|
onerror,
|
|
|
|
):
|
|
|
|
if ldflags is None:
|
|
|
|
|
|
|
|
@depends(dependable(flags))
|
|
|
|
def flags(flags):
|
|
|
|
flags = list(flags or [])
|
|
|
|
flags.append("-c")
|
|
|
|
return flags
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
@depends(compiler, dependable(ldflags), dependable(flags), when=when)
|
|
|
|
def flags(compiler, ldflags, flags):
|
|
|
|
if compiler.type == "clang-cl":
|
|
|
|
configure_error(
|
|
|
|
"checking linker flags for clang-cl is not supported yet"
|
|
|
|
)
|
|
|
|
|
|
|
|
flags = list(flags or [])
|
|
|
|
flags.extend(ldflags)
|
|
|
|
return flags
|
|
|
|
|
|
|
|
@depends(dependable(includes))
|
|
|
|
def header(includes):
|
|
|
|
includes = includes or []
|
|
|
|
return ["#include <%s>" % f for f in includes]
|
|
|
|
|
|
|
|
return self.try_run(
|
|
|
|
header=header,
|
|
|
|
body=body,
|
|
|
|
flags=flags,
|
|
|
|
check_msg=check_msg,
|
|
|
|
when=when,
|
|
|
|
onerror=onerror,
|
|
|
|
)
|
|
|
|
|
2016-08-04 06:51:47 +00:00
|
|
|
# Generates a test program and attempts to compile it. In case of
|
|
|
|
# failure, the resulting check will return None. If the test program
|
|
|
|
# succeeds, it will return the output of the test program.
|
|
|
|
# - `includes` are the includes (as file names) that will appear at the
|
|
|
|
# top of the generated test program.
|
|
|
|
# - `body` is the code that will appear in the main function of the
|
|
|
|
# generated test program. `return 0;` is appended to the function
|
|
|
|
# body automatically.
|
|
|
|
# - `flags` are the flags to be passed to the compiler, in addition to
|
|
|
|
# `-c`.
|
|
|
|
# - `check_msg` is the message to be printed to accompany compiling the
|
|
|
|
# test program.
|
|
|
|
def try_compile(
|
|
|
|
self,
|
|
|
|
includes=None,
|
|
|
|
body="",
|
|
|
|
flags=None,
|
2016-08-05 08:13:48 +00:00
|
|
|
check_msg=None,
|
|
|
|
when=None,
|
|
|
|
onerror=lambda: None,
|
|
|
|
):
|
2024-02-10 18:28:42 +00:00
|
|
|
return self._try_compile_or_link(
|
|
|
|
includes=includes,
|
|
|
|
body=body,
|
|
|
|
flags=flags,
|
|
|
|
ldflags=None,
|
|
|
|
check_msg=check_msg,
|
|
|
|
when=when,
|
|
|
|
onerror=onerror,
|
|
|
|
)
|
2024-02-06 11:22:23 +00:00
|
|
|
|
2024-02-10 18:28:42 +00:00
|
|
|
# Same steps as try_compile but doesn't add "-c"
|
|
|
|
def try_link(
|
|
|
|
self,
|
|
|
|
ldflags,
|
|
|
|
includes=None,
|
|
|
|
body="",
|
|
|
|
flags=None,
|
|
|
|
check_msg=None,
|
|
|
|
when=None,
|
|
|
|
onerror=lambda: None,
|
|
|
|
):
|
|
|
|
return self._try_compile_or_link(
|
|
|
|
includes=includes,
|
2018-12-19 22:40:38 +00:00
|
|
|
body=body,
|
|
|
|
flags=flags,
|
2024-02-10 18:28:42 +00:00
|
|
|
ldflags=ldflags,
|
2018-12-19 22:40:38 +00:00
|
|
|
check_msg=check_msg,
|
|
|
|
when=when,
|
|
|
|
onerror=onerror,
|
|
|
|
)
|
|
|
|
|
|
|
|
# Generates a test program and run the compiler against it. In case of
|
|
|
|
# failure, the resulting check will return None.
|
|
|
|
# - `header` is code that will appear at the top of the generated test
|
|
|
|
# program.
|
|
|
|
# - `body` is the code that will appear in the main function of the
|
|
|
|
# generated test program. `return 0;` is appended to the function
|
|
|
|
# body automatically.
|
|
|
|
# - `flags` are the flags to be passed to the compiler.
|
|
|
|
# - `check_msg` is the message to be printed to accompany compiling the
|
|
|
|
# test program.
|
|
|
|
# - `onerror` is a function called when the check fails.
|
|
|
|
def try_run(
|
|
|
|
self,
|
|
|
|
header=None,
|
|
|
|
body="",
|
|
|
|
flags=None,
|
|
|
|
check_msg=None,
|
|
|
|
when=None,
|
|
|
|
onerror=lambda: None,
|
|
|
|
):
|
|
|
|
source = textwrap.dedent(
|
|
|
|
"""\
|
2016-08-04 06:51:47 +00:00
|
|
|
int
|
|
|
|
main(void)
|
|
|
|
{
|
|
|
|
%s
|
|
|
|
;
|
|
|
|
return 0;
|
|
|
|
}
|
2020-10-26 18:34:53 +00:00
|
|
|
"""
|
2016-08-04 06:51:47 +00:00
|
|
|
% body
|
|
|
|
)
|
|
|
|
|
|
|
|
if check_msg:
|
2020-10-26 18:34:53 +00:00
|
|
|
|
2016-08-04 06:51:47 +00:00
|
|
|
def checking_fn(fn):
|
2016-08-10 01:00:43 +00:00
|
|
|
return checking(check_msg)(fn)
|
2020-10-26 18:34:53 +00:00
|
|
|
|
2016-08-04 06:51:47 +00:00
|
|
|
else:
|
2020-10-26 18:34:53 +00:00
|
|
|
|
2016-08-04 06:51:47 +00:00
|
|
|
def checking_fn(fn):
|
|
|
|
return fn
|
|
|
|
|
2023-01-18 23:39:05 +00:00
|
|
|
# We accept onerror being a @depends function that returns a callable.
|
|
|
|
# So, create a similar @depends function when it's not already one.
|
|
|
|
if not isinstance(onerror, SandboxDependsFunction):
|
|
|
|
onerror = dependable(lambda: onerror)
|
|
|
|
|
2019-03-27 22:05:04 +00:00
|
|
|
@depends(
|
|
|
|
self,
|
|
|
|
dependable(flags),
|
|
|
|
extra_toolchain_flags,
|
|
|
|
dependable(header),
|
2023-01-18 23:39:05 +00:00
|
|
|
onerror,
|
2023-02-28 08:42:52 +00:00
|
|
|
configure_cache,
|
2019-03-27 22:05:04 +00:00
|
|
|
when=when,
|
|
|
|
)
|
2016-08-04 06:51:47 +00:00
|
|
|
@checking_fn
|
2023-02-28 08:42:52 +00:00
|
|
|
def func(
|
|
|
|
compiler,
|
|
|
|
flags,
|
|
|
|
extra_flags,
|
|
|
|
header,
|
|
|
|
onerror,
|
|
|
|
configure_cache,
|
|
|
|
):
|
2018-12-19 22:40:38 +00:00
|
|
|
flags = list(flags or [])
|
2017-08-18 16:05:05 +00:00
|
|
|
if is_target:
|
|
|
|
flags += extra_flags or []
|
2018-12-19 22:40:38 +00:00
|
|
|
header = header or ""
|
|
|
|
if isinstance(header, (list, tuple)):
|
|
|
|
header = "\n".join(header)
|
|
|
|
if header:
|
|
|
|
header += "\n"
|
2016-08-04 06:51:47 +00:00
|
|
|
|
2016-08-10 01:00:43 +00:00
|
|
|
if (
|
|
|
|
try_invoke_compiler(
|
2023-02-28 08:42:52 +00:00
|
|
|
configure_cache,
|
|
|
|
[compiler.compiler] + compiler.flags,
|
2018-12-19 22:40:38 +00:00
|
|
|
compiler.language,
|
|
|
|
header + source,
|
|
|
|
flags,
|
2017-10-12 13:22:59 +00:00
|
|
|
onerror=onerror,
|
2023-02-28 08:42:52 +00:00
|
|
|
wrapper=compiler.wrapper,
|
2017-10-12 13:22:59 +00:00
|
|
|
)
|
|
|
|
is not None
|
|
|
|
):
|
2016-08-10 01:00:43 +00:00
|
|
|
return True
|
2016-08-04 06:51:47 +00:00
|
|
|
|
|
|
|
return func
|
|
|
|
|
|
|
|
compiler.__class__ = Compiler
|
|
|
|
return compiler
|