Compilers: Add a preprocessor mode for clike compilers

A compiler object can now return a list of "modes", they are new
compiler object specialized for a specific task.
pull/10916/head
Xavier Claessens 2 years ago
parent af6d70a176
commit 5e0f22896f
  1. 4
      mesonbuild/backend/ninjabackend.py
  2. 12
      mesonbuild/compilers/compilers.py
  3. 18
      mesonbuild/compilers/mixins/clike.py
  4. 5
      mesonbuild/compilers/mixins/visualstudio.py

@ -1983,7 +1983,7 @@ class NinjaBackend(backends.Backend):
@classmethod
def compiler_to_rule_name(cls, compiler: Compiler) -> str:
return cls.get_compiler_rule_name(compiler.get_language(), compiler.for_machine)
return cls.get_compiler_rule_name(compiler.get_language(), compiler.for_machine, compiler.mode)
@classmethod
def compiler_to_pch_rule_name(cls, compiler: Compiler) -> str:
@ -2362,6 +2362,8 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
self.generate_llvm_ir_compile_rule(compiler)
self.generate_compile_rule_for(langname, compiler)
self.generate_pch_rule_for(langname, compiler)
for mode in compiler.get_modes():
self.generate_compile_rule_for(langname, mode)
def generate_generator_list_rules(self, target):
# CustomTargets have already written their rules and

@ -494,6 +494,7 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
language: str
id: str
warn_args: T.Dict[str, T.List[str]]
mode: str = 'COMPILER'
def __init__(self, exelist: T.List[str], version: str,
for_machine: MachineChoice, info: 'MachineInfo',
@ -513,6 +514,7 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
self.linker = linker
self.info = info
self.is_cross = is_cross
self.modes: T.List[Compiler] = []
def __repr__(self) -> str:
repr_str = "<{0}: v{1} `{2}`>"
@ -531,6 +533,9 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
def get_id(self) -> str:
return self.id
def get_modes(self) -> T.List[Compiler]:
return self.modes
def get_linker_id(self) -> str:
# There is not guarantee that we have a dynamic linker instance, as
# some languages don't have separate linkers and compilers. In those
@ -1050,6 +1055,9 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
def get_preprocess_only_args(self) -> T.List[str]:
raise EnvironmentException('This compiler does not have a preprocessor')
def get_preprocess_to_file_args(self) -> T.List[str]:
return self.get_preprocess_only_args()
def get_default_include_dirs(self) -> T.List[str]:
# TODO: This is a candidate for returning an immutable list
return []
@ -1290,6 +1298,10 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
def needs_static_linker(self) -> bool:
raise NotImplementedError(f'There is no static linker for {self.language}')
def get_preprocessor(self) -> Compiler:
"""Get compiler's preprocessor.
"""
raise EnvironmentException(f'{self.get_id()} does not support preprocessor')
def get_global_options(lang: str,
comp: T.Type[Compiler],

@ -27,6 +27,7 @@ import itertools
import os
import re
import subprocess
import copy
import typing as T
from pathlib import Path
@ -145,6 +146,8 @@ class CLikeCompiler(Compiler):
self.exe_wrapper = None
else:
self.exe_wrapper = exe_wrapper
# Lazy initialized in get_preprocessor()
self.preprocessor: T.Optional[Compiler] = None
def compiler_args(self, args: T.Optional[T.Iterable[str]] = None) -> CLikeCompilerArgs:
# This is correct, mypy just doesn't understand co-operative inheritance
@ -1328,3 +1331,18 @@ class CLikeCompiler(Compiler):
def get_disable_assert_args(self) -> T.List[str]:
return ['-DNDEBUG']
@functools.lru_cache(maxsize=None)
def can_compile(self, src: 'mesonlib.FileOrString') -> bool:
# Files we preprocess can be anything, e.g. .in
if self.mode == 'PREPROCESSOR':
return True
return super().can_compile(src)
def get_preprocessor(self) -> Compiler:
if not self.preprocessor:
self.preprocessor = copy.copy(self)
self.preprocessor.exelist = self.exelist + self.get_preprocess_to_file_args()
self.preprocessor.mode = 'PREPROCESSOR'
self.modes.append(self.preprocessor)
return self.preprocessor

@ -159,6 +159,9 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta):
def get_preprocess_only_args(self) -> T.List[str]:
return ['/EP']
def get_preprocess_to_file_args(self) -> T.List[str]:
return ['/EP', '/P']
def get_compile_only_args(self) -> T.List[str]:
return ['/c']
@ -173,6 +176,8 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta):
return ['/fsanitize=address']
def get_output_args(self, target: str) -> T.List[str]:
if self.mode == 'PREPROCESSOR':
return ['/Fi' + target]
if target.endswith('.exe'):
return ['/Fe' + target]
return ['/Fo' + target]

Loading…
Cancel
Save