Meson.build: How can find_program() be combined with run_command() in a subproject?

I try to build pango with

meson setup --wrap-mode=forcefallback --prefix=~/some-new-directory -Dintrospection=disabled -Dglib:sysprof=disabled -Dpixman:demos=disabled build-dir

Some features must be disabled to avoid circular dependencies. That’s not the problem here.

The build fails during configuration with

subprojects/fontconfig/meson.build:341:18: Exception: Program 'gperf' was overridden with the compiled executable 'gperf' and therefore cannot be used during configuration
Subproject subprojects/fontconfig is buildable: NO (disabling)
Dependency fontconfig from subproject fontconfig found: NO (subproject failed to configure)

meson.build:284:17: ERROR: Subproject "subprojects/fontconfig" required but not found.

The culprit is this part of fontconfig/meson.build:

gperf = find_program('gperf', required: false)
gperf_len_type = ''
if gperf.found()
  #====== not shown
  gperf_snippet = run_command(gperf, '-L', 'ANSI-C', files('meson-cc-tests/gperf.txt'),
                              check: true).stdout()
  #====== not shown
else
  # Fallback to subproject
  gperf = find_program('gperf')
  # assume if we are compiling from the wrap, the size is just size_t
  gperf_len_type = 'size_t'
endif

gperf.found() is true, but the gperf command can’t be used in run_command().
It belongs to a subproject and has not yet been built during configuration.
The object returned from dependency() has the type_name() method, which can be used
to check how the dependency was found (e.g. if dependency('foo').type_name() != 'internal').
The object returned from find_program() has no similar method, AFAIK.

How can fontconfig/meson.build be fixed, so the Fallback to subproject branch
is chosen in this case?

An unrelated comment: If the first call to find_program() would not find gperf,
then the call in the else branch would fail.

meson version 1.5.1

If the first call to find_program() would not find gperf, then the call in the else branch would fail.

Not always true. The first call to find_program (gperf = find_program('gperf', required: false))
finds gperf in a subproject only if wrap-mode is forcefallback. The second call
(gperf = find_program('gperf')) finds gperf in a subproject if wrap-mode is
anything but nofallback. Meson searches harder when the program is required.

I think I’ve found an acceptable solution myself. It seems this is an issue only
when --wrap-mode=forcefallback. If so, if gperf.found() in fontconfig/meson.build
can be changed to

if gperf.found() and get_option('wrap_mode') != 'forcefallback'

I’ve filed fontconfig issue 462.