aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/backend/ninjabackend.py4
-rw-r--r--mesonbuild/compilers/compilers.py12
-rw-r--r--mesonbuild/compilers/mixins/clike.py18
-rw-r--r--mesonbuild/compilers/mixins/visualstudio.py5
4 files changed, 38 insertions, 1 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 2747c27..8dd21f5 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.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
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index 53b4307..b3191a8 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -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],
diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py
index cc78639..e1baa84 100644
--- a/mesonbuild/compilers/mixins/clike.py
+++ b/mesonbuild/compilers/mixins/clike.py
@@ -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
diff --git a/mesonbuild/compilers/mixins/visualstudio.py b/mesonbuild/compilers/mixins/visualstudio.py
index dc5e962..76ce9c1 100644
--- a/mesonbuild/compilers/mixins/visualstudio.py
+++ b/mesonbuild/compilers/mixins/visualstudio.py
@@ -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]