summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Brunet <charles.brunet@optelgroup.com>2025-08-29 08:28:22 -0400
committerDylan Baker <dylan@pnwbakers.com>2025-10-14 09:24:17 -0700
commit632115ecff3bd7f9cb519098e04e0467b0cfd3a1 (patch)
treecbe868b80b2cb472d08b3e6c24021a1bf5b71cab
parente2164545cba239e27a604c89c1d11a4c470f50f3 (diff)
downloadmeson-632115ecff3bd7f9cb519098e04e0467b0cfd3a1.tar.gz
Detect dependency changes in Windows rc compiler
The `rc.exe` resource compiler neither provides *depfile* support nor allows showing includes, as is possible with C or C++ compilers. Therefore, changes to files included by the `.rc` file did not trigger recompilation of the resource file. A workaround was added to *meson* by calling the preprocessor on the `.rc` file to detect the included headers and adding the result as a dependency to the resource compilation.
-rw-r--r--docs/markdown/Windows-module.md7
-rw-r--r--docs/markdown/snippets/windows_rc_depfile.md10
-rw-r--r--mesonbuild/modules/windows.py46
3 files changed, 56 insertions, 7 deletions
diff --git a/docs/markdown/Windows-module.md b/docs/markdown/Windows-module.md
index 025f046cc..5ae828109 100644
--- a/docs/markdown/Windows-module.md
+++ b/docs/markdown/Windows-module.md
@@ -20,8 +20,11 @@ Compiles Windows `rc` files specified in the positional arguments.
Returns a list of `CustomTarget` objects that you put in the list of sources for
the target you want to have the resources in.
-*Since 0.61.0* CustomTargetIndexes and CustomTargets with more than out output
-*may be used as positional arguments.
+*Since 0.61.0* `CustomTargetIndexes` and `CustomTargets` with more than one output
+may be used as positional arguments.
+
+*Since 1.10.0* Changes to included header files are now detected when using
+`rc.exe` resource compiler.
This method has the following keyword arguments:
diff --git a/docs/markdown/snippets/windows_rc_depfile.md b/docs/markdown/snippets/windows_rc_depfile.md
new file mode 100644
index 000000000..8a2c9ac6f
--- /dev/null
+++ b/docs/markdown/snippets/windows_rc_depfile.md
@@ -0,0 +1,10 @@
+## windows.compile_resources now detects header changes with rc.exe
+
+The `rc.exe` resource compiler neither provides *depfile* support nor
+allows showing includes, as is possible with C or C++ compilers.
+Therefore, changes to files included by the `.rc` file did not trigger
+recompilation of the resource file.
+
+A workaround was added to *meson* by calling the preprocessor on the
+`.rc` file to detect the included headers and adding the result as a
+dependency to the resource compilation.
diff --git a/mesonbuild/modules/windows.py b/mesonbuild/modules/windows.py
index 29ae96b08..17fc8abe4 100644
--- a/mesonbuild/modules/windows.py
+++ b/mesonbuild/modules/windows.py
@@ -22,13 +22,13 @@ if T.TYPE_CHECKING:
from . import ModuleState
from ..compilers import Compiler
from ..interpreter import Interpreter
+ from ..interpreter.interpreter import SourceOutputs
from typing_extensions import TypedDict
class CompileResources(TypedDict):
-
depend_files: T.List[mesonlib.FileOrString]
- depends: T.List[T.Union[build.BuildTarget, build.CustomTarget]]
+ depends: T.List[T.Union[build.BuildTarget, build.CustomTarget, build.CustomTargetIndex]]
include_directories: T.List[T.Union[str, build.IncludeDirs]]
args: T.List[str]
@@ -102,6 +102,33 @@ class WindowsModule(ExtensionModule):
return self._rescomp
+ def get_preprocessor_target(self,
+ name_formatted: str,
+ src: T.Union[str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex],
+ include_directories: T.List[build.IncludeDirs],
+ state: ModuleState) -> build.CustomTargetIndex:
+ compiler = self.detect_compiler(state.environment.coredata.compilers[MachineChoice.HOST])
+ _sources: T.List[T.Union[mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList]] = self.interpreter.source_strings_to_files([src])
+ sources = T.cast('T.List[SourceOutputs]', _sources)
+
+ tg = build.CompileTarget(
+ name_formatted,
+ state.subdir,
+ state.subproject,
+ state.environment,
+ sources,
+ '@PLAINNAME@.i',
+ compiler.get_preprocessor(),
+ state.backend,
+ ['-DRC_INVOKED'],
+ include_directories,
+ [],
+ [])
+ self.interpreter.add_target(tg.name, tg)
+
+ private_dir = os.path.relpath(state.backend.get_target_private_dir(tg), state.subdir)
+ return build.CustomTargetIndex(tg, os.path.join(private_dir, tg.outputs[0]))
+
@typed_pos_args('windows.compile_resources', varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex), min_varargs=1)
@typed_kwargs(
'windows.compile_resources',
@@ -121,7 +148,8 @@ class WindowsModule(ExtensionModule):
extra_args += state.get_include_args([
build.IncludeDirs('', [], False, [os.path.join('@BUILD_ROOT@', self.interpreter.backend.get_target_dir(d))])
])
- extra_args += state.get_include_args(kwargs['include_directories'])
+ include_directories = self.interpreter.extract_incdirs(kwargs)
+ extra_args += state.get_include_args(include_directories)
rescomp, rescomp_type = self._find_resource_compiler(state)
if rescomp_type == ResourceCompilerType.rc:
@@ -178,12 +206,20 @@ class WindowsModule(ExtensionModule):
command.append(rescomp)
command.extend(res_args)
depfile: T.Optional[str] = None
- # instruct binutils windres to generate a preprocessor depfile
+ extra_depends = wrc_depends.copy()
if rescomp_type == ResourceCompilerType.windres:
+ # instruct binutils windres to generate a preprocessor depfile
depfile = f'{output}.d'
command.extend(['--preprocessor-arg=-MD',
'--preprocessor-arg=-MQ@OUTPUT@',
'--preprocessor-arg=-MF@DEPFILE@'])
+ elif rescomp_type == ResourceCompilerType.rc:
+ # use preprocessor to detect header dependencies
+ extra_depends.append(self.get_preprocessor_target(
+ name_formatted + '_i',
+ src,
+ include_directories,
+ state))
res_targets.append(build.CustomTarget(
name_formatted,
@@ -195,7 +231,7 @@ class WindowsModule(ExtensionModule):
[output],
depfile=depfile,
depend_files=wrc_depend_files,
- extra_depends=wrc_depends,
+ extra_depends=extra_depends,
description='Compiling Windows resource {}',
))