prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  windows.compile_resources() can't be used with custom targets
  ```meson
      rc_target = custom_target('Windows resource file',
          command : [preprocess_command, rcdefs, '@INPUT@', '@OUTPUT@'],
          build_always : true,
          input : 'taisei.rc.in',
          output : 'taisei.rc',
      )
  
      version_deps += winmod.compile_resources(rc_target)
  ```
  
  ```
  Meson encountered an error in file src/meson.build, line 59, column 4:
  Windows resource arguments must be strings or files not <CustomTargetHolder Windows resource file@cus: ['/data/git/taisei/scripts/configure-file.py', '--rootdir', '/data/git/taisei', '--fallback-version', 'v1.1.0-9999', '-DMESON_BUILD_TYPE=release', '-DICONS_DIR=/data/git/taisei/misc/icons', '-DBUILDTYPE_DEFINE=#define RELEASE_BUILD', '@INPUT@', '@OUTPUT@']>
  ```
  
  This bug makes it impossible to reliably regenerate the `.rc` source on every rebuild.
  Add something like depend_files to windows.compile_resources()
  Resource script can include various other files (bitmap, cursor, font, html, icon, message table, binary data, manifest), it would be nice if it were possible to declare the resource script depends on these.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `mesonbuild/modules/windows.py`
  Content:
  ```
  1 # Copyright 2015 The Meson development team
  2 
  3 # Licensed under the Apache License, Version 2.0 (the "License");
  4 # you may not use this file except in compliance with the License.
  5 # You may obtain a copy of the License at
  6 
  7 #     http://www.apache.org/licenses/LICENSE-2.0
  8 
  9 # Unless required by applicable law or agreed to in writing, software
  10 # distributed under the License is distributed on an "AS IS" BASIS,
  11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12 # See the License for the specific language governing permissions and
  13 # limitations under the License.
  14 
  15 import os
  16 
  17 from .. import mlog
  18 from .. import mesonlib, dependencies, build
  19 from ..mesonlib import MesonException, extract_as_list
  20 from . import get_include_args
  21 from . import ModuleReturnValue
  22 from . import ExtensionModule
  23 from ..interpreterbase import permittedKwargs
  24 
  25 class WindowsModule(ExtensionModule):
  26 
  27     def detect_compiler(self, compilers):
  28         for l in ('c', 'cpp'):
  29             if l in compilers:
  30                 return compilers[l]
  31         raise MesonException('Resource compilation requires a C or C++ compiler.')
  32 
  33     @permittedKwargs({'args', 'include_directories'})
  34     def compile_resources(self, state, args, kwargs):
  35         comp = self.detect_compiler(state.compilers)
  36 
  37         extra_args = mesonlib.stringlistify(kwargs.get('args', []))
  38         inc_dirs = extract_as_list(kwargs, 'include_directories', pop = True)
  39         for incd in inc_dirs:
  40             if not isinstance(incd.held_object, (str, build.IncludeDirs)):
  41                 raise MesonException('Resource include dirs should be include_directories().')
  42         extra_args += get_include_args(inc_dirs)
  43 
  44         if comp.id == 'msvc':
  45             rescomp = dependencies.ExternalProgram('rc', silent=True)
  46             res_args = extra_args + ['/nologo', '/fo@OUTPUT@', '@INPUT@']
  47             suffix = 'res'
  48         else:
  49             m = 'Argument {!r} has a space which may not work with windres due to ' \
  50                 'a MinGW bug: https://sourceware.org/bugzilla/show_bug.cgi?id=4933'
  51             for arg in extra_args:
  52                 if ' ' in arg:
  53                     mlog.warning(m.format(arg))
  54             rescomp_name = None
  55             # FIXME: Does not handle `native: true` executables, see
  56             # https://github.com/mesonbuild/meson/issues/1531
  57             if state.environment.is_cross_build():
  58                 # If cross compiling see if windres has been specified in the
  59                 # cross file before trying to find it another way.
  60                 rescomp_name = state.environment.cross_info.config['binaries'].get('windres')
  61             if rescomp_name is None:
  62                 # Pick-up env var WINDRES if set. This is often used for
  63                 # specifying an arch-specific windres.
  64                 rescomp_name = os.environ.get('WINDRES', 'windres')
  65             rescomp = dependencies.ExternalProgram(rescomp_name, silent=True)
  66             res_args = extra_args + ['@INPUT@', '@OUTPUT@']
  67             suffix = 'o'
  68         if not rescomp.found():
  69             raise MesonException('Could not find Windows resource compiler %s.' % ' '.join(rescomp.get_command()))
  70         res_kwargs = {'output': '@BASENAME@.' + suffix,
  71                       'arguments': res_args}
  72         res_gen = build.Generator([rescomp], res_kwargs)
  73         res_output = res_gen.process_files('Windows resource', args, state)
  74         return ModuleReturnValue(res_output, [res_output])
  75 
  76 def initialize():
  77     return WindowsModule()
  78
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/mesonbuild/modules/windows.py b/mesonbuild/modules/windows.py
  --- a/mesonbuild/modules/windows.py
  +++ b/mesonbuild/modules/windows.py
  @@ -67,11 +67,42 @@
               suffix = 'o'
           if not rescomp.found():
               raise MesonException('Could not find Windows resource compiler %s.' % ' '.join(rescomp.get_command()))
  -        res_kwargs = {'output': '@BASENAME@.' + suffix,
  -                      'arguments': res_args}
  -        res_gen = build.Generator([rescomp], res_kwargs)
  -        res_output = res_gen.process_files('Windows resource', args, state)
  -        return ModuleReturnValue(res_output, [res_output])
  +
  +        res_targets = []
  +
  +        def add_target(src):
  +            if isinstance(src, list):
  +                for subsrc in src:
  +                    add_target(subsrc)
  +                return
  +
  +            if hasattr(src, 'held_object'):
  +                src = src.held_object
  +
  +            res_kwargs = {
  +                'output': '@BASENAME@.' + suffix,
  +                'input': [src],
  +                'command': [rescomp] + res_args,
  +            }
  +
  +            if isinstance(src, (str, mesonlib.File)):
  +                name = 'file {!r}'.format(str(src))
  +            elif isinstance(src, build.CustomTarget):
  +                if len(src.get_outputs()) > 1:
  +                    raise MesonException('windows.compile_resources does not accept custom targets with more than 1 output.')
  +
  +                name = 'target {!r}'.format(src.get_id())
  +            else:
  +                raise MesonException('Unexpected source type {!r}. windows.compile_resources accepts only strings, files, custom targets, and lists thereof.'.format(src))
  +
  +            # Path separators are not allowed in target names
  +            name = name.replace('/', '_').replace('\\', '_')
  +
  +            res_targets.append(build.CustomTarget('Windows resource for ' + name, state.subdir, state.subproject, res_kwargs))
  +
  +        add_target(args)
  +
  +        return ModuleReturnValue(res_targets, [res_targets])
   
   def initialize():
       return WindowsModule()
  
verification_info: {"golden_diff": "diff --git a/mesonbuild/modules/windows.py b/mesonbuild/modules/windows.py\n--- a/mesonbuild/modules/windows.py\n+++ b/mesonbuild/modules/windows.py\n@@ -67,11 +67,42 @@\n             suffix = 'o'\n         if not rescomp.found():\n             raise MesonException('Could not find Windows resource compiler %s.' % ' '.join(rescomp.get_command()))\n-        res_kwargs = {'output': '@BASENAME@.' + suffix,\n-                      'arguments': res_args}\n-        res_gen = build.Generator([rescomp], res_kwargs)\n-        res_output = res_gen.process_files('Windows resource', args, state)\n-        return ModuleReturnValue(res_output, [res_output])\n+\n+        res_targets = []\n+\n+        def add_target(src):\n+            if isinstance(src, list):\n+                for subsrc in src:\n+                    add_target(subsrc)\n+                return\n+\n+            if hasattr(src, 'held_object'):\n+                src = src.held_object\n+\n+            res_kwargs = {\n+                'output': '@BASENAME@.' + suffix,\n+                'input': [src],\n+                'command': [rescomp] + res_args,\n+            }\n+\n+            if isinstance(src, (str, mesonlib.File)):\n+                name = 'file {!r}'.format(str(src))\n+            elif isinstance(src, build.CustomTarget):\n+                if len(src.get_outputs()) > 1:\n+                    raise MesonException('windows.compile_resources does not accept custom targets with more than 1 output.')\n+\n+                name = 'target {!r}'.format(src.get_id())\n+            else:\n+                raise MesonException('Unexpected source type {!r}. windows.compile_resources accepts only strings, files, custom targets, and lists thereof.'.format(src))\n+\n+            # Path separators are not allowed in target names\n+            name = name.replace('/', '_').replace('\\\\', '_')\n+\n+            res_targets.append(build.CustomTarget('Windows resource for ' + name, state.subdir, state.subproject, res_kwargs))\n+\n+        add_target(args)\n+\n+        return ModuleReturnValue(res_targets, [res_targets])\n \n def initialize():\n     return WindowsModule()\n", "issue": "windows.compile_resources() can't be used with custom targets\n```meson\r\n    rc_target = custom_target('Windows resource file',\r\n        command : [preprocess_command, rcdefs, '@INPUT@', '@OUTPUT@'],\r\n        build_always : true,\r\n        input : 'taisei.rc.in',\r\n        output : 'taisei.rc',\r\n    )\r\n\r\n    version_deps += winmod.compile_resources(rc_target)\r\n```\r\n\r\n```\r\nMeson encountered an error in file src/meson.build, line 59, column 4:\r\nWindows resource arguments must be strings or files not <CustomTargetHolder Windows resource file@cus: ['/data/git/taisei/scripts/configure-file.py', '--rootdir', '/data/git/taisei', '--fallback-version', 'v1.1.0-9999', '-DMESON_BUILD_TYPE=release', '-DICONS_DIR=/data/git/taisei/misc/icons', '-DBUILDTYPE_DEFINE=#define RELEASE_BUILD', '@INPUT@', '@OUTPUT@']>\r\n```\r\n\r\nThis bug makes it impossible to reliably regenerate the `.rc` source on every rebuild.\nAdd something like depend_files to windows.compile_resources()\nResource script can include various other files (bitmap, cursor, font, html, icon, message table, binary data, manifest), it would be nice if it were possible to declare the resource script depends on these.\n", "before_files": [{"content": "# Copyright 2015 The Meson development team\n\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n\n#     http://www.apache.org/licenses/LICENSE-2.0\n\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport os\n\nfrom .. import mlog\nfrom .. import mesonlib, dependencies, build\nfrom ..mesonlib import MesonException, extract_as_list\nfrom . import get_include_args\nfrom . import ModuleReturnValue\nfrom . import ExtensionModule\nfrom ..interpreterbase import permittedKwargs\n\nclass WindowsModule(ExtensionModule):\n\n    def detect_compiler(self, compilers):\n        for l in ('c', 'cpp'):\n            if l in compilers:\n                return compilers[l]\n        raise MesonException('Resource compilation requires a C or C++ compiler.')\n\n    @permittedKwargs({'args', 'include_directories'})\n    def compile_resources(self, state, args, kwargs):\n        comp = self.detect_compiler(state.compilers)\n\n        extra_args = mesonlib.stringlistify(kwargs.get('args', []))\n        inc_dirs = extract_as_list(kwargs, 'include_directories', pop = True)\n        for incd in inc_dirs:\n            if not isinstance(incd.held_object, (str, build.IncludeDirs)):\n                raise MesonException('Resource include dirs should be include_directories().')\n        extra_args += get_include_args(inc_dirs)\n\n        if comp.id == 'msvc':\n            rescomp = dependencies.ExternalProgram('rc', silent=True)\n            res_args = extra_args + ['/nologo', '/fo@OUTPUT@', '@INPUT@']\n            suffix = 'res'\n        else:\n            m = 'Argument {!r} has a space which may not work with windres due to ' \\\n                'a MinGW bug: https://sourceware.org/bugzilla/show_bug.cgi?id=4933'\n            for arg in extra_args:\n                if ' ' in arg:\n                    mlog.warning(m.format(arg))\n            rescomp_name = None\n            # FIXME: Does not handle `native: true` executables, see\n            # https://github.com/mesonbuild/meson/issues/1531\n            if state.environment.is_cross_build():\n                # If cross compiling see if windres has been specified in the\n                # cross file before trying to find it another way.\n                rescomp_name = state.environment.cross_info.config['binaries'].get('windres')\n            if rescomp_name is None:\n                # Pick-up env var WINDRES if set. This is often used for\n                # specifying an arch-specific windres.\n                rescomp_name = os.environ.get('WINDRES', 'windres')\n            rescomp = dependencies.ExternalProgram(rescomp_name, silent=True)\n            res_args = extra_args + ['@INPUT@', '@OUTPUT@']\n            suffix = 'o'\n        if not rescomp.found():\n            raise MesonException('Could not find Windows resource compiler %s.' % ' '.join(rescomp.get_command()))\n        res_kwargs = {'output': '@BASENAME@.' + suffix,\n                      'arguments': res_args}\n        res_gen = build.Generator([rescomp], res_kwargs)\n        res_output = res_gen.process_files('Windows resource', args, state)\n        return ModuleReturnValue(res_output, [res_output])\n\ndef initialize():\n    return WindowsModule()\n", "path": "mesonbuild/modules/windows.py"}], "after_files": [{"content": "# Copyright 2015 The Meson development team\n\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n\n#     http://www.apache.org/licenses/LICENSE-2.0\n\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport os\n\nfrom .. import mlog\nfrom .. import mesonlib, dependencies, build\nfrom ..mesonlib import MesonException, extract_as_list\nfrom . import get_include_args\nfrom . import ModuleReturnValue\nfrom . import ExtensionModule\nfrom ..interpreterbase import permittedKwargs\n\nclass WindowsModule(ExtensionModule):\n\n    def detect_compiler(self, compilers):\n        for l in ('c', 'cpp'):\n            if l in compilers:\n                return compilers[l]\n        raise MesonException('Resource compilation requires a C or C++ compiler.')\n\n    @permittedKwargs({'args', 'include_directories'})\n    def compile_resources(self, state, args, kwargs):\n        comp = self.detect_compiler(state.compilers)\n\n        extra_args = mesonlib.stringlistify(kwargs.get('args', []))\n        inc_dirs = extract_as_list(kwargs, 'include_directories', pop = True)\n        for incd in inc_dirs:\n            if not isinstance(incd.held_object, (str, build.IncludeDirs)):\n                raise MesonException('Resource include dirs should be include_directories().')\n        extra_args += get_include_args(inc_dirs)\n\n        if comp.id == 'msvc':\n            rescomp = dependencies.ExternalProgram('rc', silent=True)\n            res_args = extra_args + ['/nologo', '/fo@OUTPUT@', '@INPUT@']\n            suffix = 'res'\n        else:\n            m = 'Argument {!r} has a space which may not work with windres due to ' \\\n                'a MinGW bug: https://sourceware.org/bugzilla/show_bug.cgi?id=4933'\n            for arg in extra_args:\n                if ' ' in arg:\n                    mlog.warning(m.format(arg))\n            rescomp_name = None\n            # FIXME: Does not handle `native: true` executables, see\n            # https://github.com/mesonbuild/meson/issues/1531\n            if state.environment.is_cross_build():\n                # If cross compiling see if windres has been specified in the\n                # cross file before trying to find it another way.\n                rescomp_name = state.environment.cross_info.config['binaries'].get('windres')\n            if rescomp_name is None:\n                # Pick-up env var WINDRES if set. This is often used for\n                # specifying an arch-specific windres.\n                rescomp_name = os.environ.get('WINDRES', 'windres')\n            rescomp = dependencies.ExternalProgram(rescomp_name, silent=True)\n            res_args = extra_args + ['@INPUT@', '@OUTPUT@']\n            suffix = 'o'\n        if not rescomp.found():\n            raise MesonException('Could not find Windows resource compiler %s.' % ' '.join(rescomp.get_command()))\n\n        res_targets = []\n\n        def add_target(src):\n            if isinstance(src, list):\n                for subsrc in src:\n                    add_target(subsrc)\n                return\n\n            if hasattr(src, 'held_object'):\n                src = src.held_object\n\n            res_kwargs = {\n                'output': '@BASENAME@.' + suffix,\n                'input': [src],\n                'command': [rescomp] + res_args,\n            }\n\n            if isinstance(src, (str, mesonlib.File)):\n                name = 'file {!r}'.format(str(src))\n            elif isinstance(src, build.CustomTarget):\n                if len(src.get_outputs()) > 1:\n                    raise MesonException('windows.compile_resources does not accept custom targets with more than 1 output.')\n\n                name = 'target {!r}'.format(src.get_id())\n            else:\n                raise MesonException('Unexpected source type {!r}. windows.compile_resources accepts only strings, files, custom targets, and lists thereof.'.format(src))\n\n            # Path separators are not allowed in target names\n            name = name.replace('/', '_').replace('\\\\', '_')\n\n            res_targets.append(build.CustomTarget('Windows resource for ' + name, state.subdir, state.subproject, res_kwargs))\n\n        add_target(args)\n\n        return ModuleReturnValue(res_targets, [res_targets])\n\ndef initialize():\n    return WindowsModule()\n", "path": "mesonbuild/modules/windows.py"}]}