Add new compiler.get_argument_syntax method

Some compilers try very had to pretend they're another compiler (ICC
pretends to be GCC and Linux and MacOS, and MSVC on windows), Clang
behaves much like GCC, but now also has clang-cl, which behaves like MSVC.

This method provides an easy way to determine whether testing for MSVC
like arguments `/w1234` or gcc like arguments `-Wfoo` are likely to
succeed, without having to check for dozens of compilers and the host
operating system, (as you would otherwise have to do with ICC).
pull/4449/head
Dylan Baker 7 years ago committed by Jussi Pakkanen
parent 8cd7f7871b
commit 63f4f9481e
  1. 14
      docs/markdown/Compiler-properties.md
  2. 7
      docs/markdown/Reference-manual.md
  3. 45
      docs/markdown/Reference-tables.md
  4. 22
      docs/markdown/snippets/compiler_argument_syntax.md
  5. 3
      mesonbuild/compilers/c.py
  6. 14
      mesonbuild/compilers/compilers.py
  7. 7
      mesonbuild/interpreter.py
  8. 25
      test cases/common/206 argument syntax/meson.build

@ -29,9 +29,17 @@ Compiler id
== ==
The compiler object has a method called `get_id`, which returns a The compiler object has a method called `get_id`, which returns a
lower case string describing the "family" of the compiler. See lower case string describing the "family" of the compiler.
[reference tables](Reference-tables.md) for a list of supported
compiler ids. The compiler object also has a method `get_argument_syntax` which
returns a lower case string of `gcc`, `msvc`, or another undefined string
value; identifying whether the compiler arguments use the same syntax as
either `gcc` or `msvc`, or that its arguments are not like either. This should
only be used to select the syntax of the arguments, such as those to test
with `has_argument`.
See [reference tables](Reference-tables.md#compiler-ids) for a list of supported compiler
ids and their argument type.
Does code compile? Does code compile?
== ==

@ -1702,6 +1702,13 @@ the following methods:
- `get_id()` returns a string identifying the compiler. For example, - `get_id()` returns a string identifying the compiler. For example,
`gcc`, `msvc`, [and more](Reference-tables.md#compiler-ids). `gcc`, `msvc`, [and more](Reference-tables.md#compiler-ids).
- `get_argument_syntax()` *(new in 0.49.0)* returns a string identifying the type
of arguments the compiler takes. Can be one of `gcc`, `msvc`, or an undefined
string value. This method is useful for identifying compilers that are not
gcc or msvc, but use the same argument syntax as one of those two compilers
such as clang or icc, especially when they use different syntax on different
operating systems.
- `get_supported_arguments(list_of_string)` *(added 0.43.0)* returns - `get_supported_arguments(list_of_string)` *(added 0.43.0)* returns
an array containing only the arguments supported by the compiler, an array containing only the arguments supported by the compiler,
as if `has_argument` were called on them individually. as if `has_argument` were called on them individually.

@ -2,28 +2,29 @@
## Compiler ids ## Compiler ids
These are return values of the `get_id` method in a compiler object. These are return values of the `get_id` (Compiler family) and
`get_argument_syntax` (Argument syntax) method in a compiler object.
| Value | Compiler family |
| ----- | ---------------- | | Value | Compiler family | Argument syntax |
| gcc | The GNU Compiler Collection | | ----- | ---------------- | -------------------------------|
| clang | The Clang compiler | | gcc | The GNU Compiler Collection | gcc |
| msvc | Microsoft Visual Studio | | clang | The Clang compiler | gcc |
| intel | Intel compiler | | msvc | Microsoft Visual Studio | msvc |
| llvm | LLVM-based compiler (Swift, D) | | intel | Intel compiler | msvc on windows, otherwise gcc |
| mono | Xamarin C# compiler | | llvm | LLVM-based compiler (Swift, D) | |
| dmd | D lang reference compiler | | mono | Xamarin C# compiler | |
| rustc | Rust compiler | | dmd | D lang reference compiler | |
| valac | Vala compiler | | rustc | Rust compiler | |
| pathscale | The Pathscale Fortran compiler | | valac | Vala compiler | |
| pgi | The Portland Fortran compiler | | pathscale | The Pathscale Fortran compiler | |
| sun | Sun Fortran compiler | | pgi | The Portland Fortran compiler | |
| g95 | The G95 Fortran compiler | | sun | Sun Fortran compiler | |
| open64 | The Open64 Fortran Compiler | | g95 | The G95 Fortran compiler | |
| nagfor | The NAG Fortran compiler | | open64 | The Open64 Fortran Compiler | |
| lcc | Elbrus C/C++/Fortran Compiler | | nagfor | The NAG Fortran compiler | |
| arm | ARM compiler | | lcc | Elbrus C/C++/Fortran Compiler | |
| armclang | ARMCLANG compiler | | arm | ARM compiler | |
| armclang | ARMCLANG compiler | |
## Script environment variables ## Script environment variables

@ -0,0 +1,22 @@
## new compiler method `get_argument_syntax`
The compiler object now has `get_argument_syntax` method, which returns a
string value of `gcc`, `msvc`, or an undefined value string value. This can be
used to determine if a compiler uses gcc syntax (`-Wfoo`), msvc syntax
(`/w1234`), or some other kind of arguments.
```meson
cc = meson.get_compiler('c')
if cc.get_argument_syntax() == 'msvc'
if cc.has_argument('/w1235')
add_project_arguments('/w1235', language : ['c'])
endif
elif cc.get_argument_syntax() == 'gcc'
if cc.has_argument('-Wfoo')
add_project_arguments('-Wfoo', language : ['c'])
endif
elif cc.get_id() == 'some other compiler'
add_project_arguments('--error-on-foo', language : ['c'])
endif
```

@ -1543,6 +1543,9 @@ class VisualStudioCCompiler(CCompiler):
# false without compiling anything # false without compiling anything
return name in ['dllimport', 'dllexport'] return name in ['dllimport', 'dllexport']
def get_argument_syntax(self):
return 'msvc'
class ArmCCompiler(ArmCompiler, CCompiler): class ArmCCompiler(ArmCompiler, CCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, **kwargs): def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, **kwargs):

@ -1214,6 +1214,17 @@ class Compiler:
m = 'Language {} does not support position-independent executable' m = 'Language {} does not support position-independent executable'
raise EnvironmentException(m.format(self.get_display_language())) raise EnvironmentException(m.format(self.get_display_language()))
def get_argument_syntax(self):
"""Returns the argument family type.
Compilers fall into families if they try to emulate the command line
interface of another compiler. For example, clang is in the GCC family
since it accepts most of the same arguments as GCC. ICL (ICC on
windows) is in the MSVC family since it accepts most of the same
arguments as MSVC.
"""
return 'other'
@enum.unique @enum.unique
class CompilerType(enum.Enum): class CompilerType(enum.Enum):
@ -1449,6 +1460,9 @@ class GnuLikeCompiler(abc.ABC):
# For other targets, discard the .def file. # For other targets, discard the .def file.
return [] return []
def get_argument_syntax(self):
return 'gcc'
class GnuCompiler(GnuLikeCompiler): class GnuCompiler(GnuLikeCompiler):
""" """

@ -935,6 +935,7 @@ class CompilerHolder(InterpreterObject):
'first_supported_link_argument': self.first_supported_link_argument_method, 'first_supported_link_argument': self.first_supported_link_argument_method,
'unittest_args': self.unittest_args_method, 'unittest_args': self.unittest_args_method,
'symbols_have_underscore_prefix': self.symbols_have_underscore_prefix_method, 'symbols_have_underscore_prefix': self.symbols_have_underscore_prefix_method,
'get_argument_syntax': self.get_argument_syntax_method,
}) })
def _dep_msg(self, deps, endl): def _dep_msg(self, deps, endl):
@ -1532,6 +1533,12 @@ class CompilerHolder(InterpreterObject):
args = mesonlib.stringlistify(args) args = mesonlib.stringlistify(args)
return [a for a in args if self.has_func_attribute_method(a, kwargs)] return [a for a in args if self.has_func_attribute_method(a, kwargs)]
@FeatureNew('compiler.get_argument_syntax_method', '0.49.0')
@noPosargs
@noKwargs
def get_argument_syntax_method(self, args, kwargs):
return self.compiler.get_argument_syntax()
ModuleState = namedtuple('ModuleState', [ ModuleState = namedtuple('ModuleState', [
'build_to_src', 'subproject', 'subdir', 'current_lineno', 'environment', 'build_to_src', 'subproject', 'subdir', 'current_lineno', 'environment',

@ -0,0 +1,25 @@
project(
'argument syntax',
['c'],
)
cc = meson.get_compiler('c')
if ['gcc', 'lcc', 'clang'].contains(cc.get_id())
expected = 'gcc'
elif cc.get_id() == 'msvc'
expected = 'msvc'
elif cc.get_id() == 'intel'
if host_machine.system() == 'windows'
expected = 'msvc'
else
expected = 'gcc'
endif
else
# It's possible that other compilers end up here that shouldn't
expected = 'other'
endif
assert(cc.get_argument_syntax() == expected,
'Wrong output for compiler @0@. expected @1@ but got @2@'.format(
cc.get_id(), expected, cc.get_argument_syntax()))
Loading…
Cancel
Save