Repository: mesonbuild/meson

Issue:
Missing rule for glib-mkenums
**Describe the bug**
When using meson from git (8cb0217c4e726e37dcca6ce6a76bac36896152b4) to build GTK4, ninja fails with the following message:

```
ninja: error: 'D:/msys64/mingw64/bin/glib-mkenums', needed by 'gdk/gdkenumtypes.h', missing and no known rule to make it
```

If i checkout meson @ 1.2.1 everything goes well

**system parameters**
* Native build
* Windows 10
* Python 3.11.4
* Ninja 1.11.1



Discussion:
Bisected to c663476075b18739066e727db9b4f0f4f882b9d1
@xclaesse, looks like your commit
I got this error also while building talkatu with meson 1.2.2. The error is as following.

```
ninja: error: 'D:/M/msys64/ucrt64/bin/glib-mkenums', needed by 'talkatu/talkatuenums.h', missing and no known rule to make it
```

OOC, do you have `mkenums` (without glib prefix) in `D:/M/msys64/ucrt64/bin/` ?
> OOC, do you have `mkenums` (without glib prefix) in `D:/M/msys64/ucrt64/bin/` ?

The full path of that file file looks like this.

```
$ ls -lash /ucrt64/bin/glib-mkenums.exe
28K -rwxr-xr-x 1 x None 27K Sep 12 20:00 /ucrt64/bin/glib-mkenums.exe

$ file /ucrt64/bin/glib-mkenums.exe
/ucrt64/bin/glib-mkenums.exe: PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows, 11 sections
```

Oh, that's probably a posix VS windows path issue then. I imagine you have pkg-config and `glib-2.0.pc` contains the path with `D:/M/msys64/ucrt64/bin/glib-mkenums`?
The glib-2.0.pc file has this...

```ini
$ head -n 10 /ucrt64/lib/pkgconfig/glib-2.0.pc
prefix=/ucrt64
includedir=${prefix}/include
libdir=${prefix}/lib

bindir=${prefix}/bin
datadir=${prefix}/share
glib_genmarshal=${bindir}/glib-genmarshal
gobject_query=${bindir}/gobject-query
glib_mkenums=${bindir}/glib-mkenums
glib_valgrind_suppressions=${datadir}/glib-2.0/valgrind/glib.supp
```

And pkgconf returns this...

```
$ pkgconf --variable glib_mkenums glib-2.0
F:/msys64/ucrt64/bin/glib-mkenums
```

Note that the fact that MSYS2 provides a glib-mkenums.exe (emphasis on the ".exe") is a downstream "feature" for tools not supporting shebangs. In case that is at fault here.

Maybe we also need to adjust the .pc file? Though things that are .exe upstream as well also don't have the extension in the .pc file, like gobject-query, so I'm not sure what's the expected .pc content here.
I think meson should resolve "F:/msys64/ucrt64/bin/glib-mkenums" to "F:/msys64/ucrt64/bin/glib-mkenums.exe", because that's also what CMD does (and I also found that CPython recently added this for shutil.which: https://github.com/python/cpython/pull/103179). Also meson should fail at the configure stage imho.

I'll patch our .pc file in the meantime in MSYS2 as a workaround, for the scripts we have created .exe wrappers for (https://github.com/msys2/MINGW-packages/pull/18659)
I *thought* that we should already be directly using `shutil.which` for this. But I may be misremembering.

Does shutil.which fail to find the program when specifying it without the .exe, or does it simply return the "wrong" filename?
Python 3.12rc3:

```
>>> import shutil
>>> shutil.which("C:/msys64/ucrt64/bin/glib-mkenums")
'C:/msys64/ucrt64/bin\\glib-mkenums.EXE'
```

Python 3.11:

```
>>> import shutil
>>> shutil.which("C:/msys64/ucrt64/bin/glib-mkenums")
>>>
```
I got another error which is not related to pkgconfig file probably.

```
ninja: error: 'D:/M/msys64/clang32/bin/glib-compile-resources', needed by 'talkatu/talkaturesources.h', missing and no known rule to make it
```

I've reverted f0b2ab8bb02f282499c downstream for now
> CPython recently added this for shutil.which: python/cpython#103179). Also meson should fail at the configure stage imho.

I think that's the root issue here, meson should be adding `.exe` suffix itself because we cannot rely on py12 to do it for us.

Resolving patch:
diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py
--- a/mesonbuild/modules/__init__.py
+++ b/mesonbuild/modules/__init__.py
@@ -112,7 +112,7 @@ def find_tool(self, name: str, depname: str, varname: str, required: bool = True
         if dep.found() and dep.type_name == 'pkgconfig':
             value = dep.get_variable(pkgconfig=varname)
             if value:
-                return ExternalProgram(name, [value])
+                return ExternalProgram(value)
 
         # Normal program lookup
         return self.find_program(name, required=required, wanted=wanted)


Test patch: