mesonbuild / meson

The Meson Build System
http://mesonbuild.com
Apache License 2.0
5.51k stars 1.6k forks source link

Crash when passing the output from generator().process() to generator.process() #10391

Open kusma opened 2 years ago

kusma commented 2 years ago

Describe the bug When passing the output of generator().process() to generator().process(), an assertion triggers in Meson.

To Reproduce meson.build

project('bug-repro', 'c')

gen_foo = generator(
  find_program('cat'),
  output : '@BASENAME@.foo',
  arguments : ['@INPUT@'],
  capture : true
)

gen_bar = generator(
  find_program('cat'),
  output : '@BASENAME@.bar',
  arguments : ['@INPUT@'],
  capture : true
)

input_foo = gen_foo.process('input.txt')
input_bar = gen_bar.process(input_foo)

executable(
  'dummy', [files('main.c'), input_bar],
)

You also need to create a input.txt and main.c file. The content of these doesn't matter, as Meson crashes before they are even processed.

When running meson <build-dir>, I get this crash:

Traceback (most recent call last):
  File "/home/kusma/.local/lib/python3.10/site-packages/mesonbuild/mesonmain.py", line 146, in run
    return options.run_func(options)
  File "/home/kusma/.local/lib/python3.10/site-packages/mesonbuild/msetup.py", line 294, in run
    app.generate()
  File "/home/kusma/.local/lib/python3.10/site-packages/mesonbuild/msetup.py", line 185, in generate
    self._generate(env)
  File "/home/kusma/.local/lib/python3.10/site-packages/mesonbuild/msetup.py", line 247, in _generate
    intr.backend.generate()
  File "/home/kusma/.local/lib/python3.10/site-packages/mesonbuild/backend/ninjabackend.py", line 553, in generate
    self.generate_target(t)
  File "/home/kusma/.local/lib/python3.10/site-packages/mesonbuild/backend/ninjabackend.py", line 782, in generate_target
    self.generate_generator_list_rules(target)
  File "/home/kusma/.local/lib/python3.10/site-packages/mesonbuild/backend/ninjabackend.py", line 2194, in generate_generator_list_rules
    self.generate_genlist_for_target(genlist, target)
  File "/home/kusma/.local/lib/python3.10/site-packages/mesonbuild/backend/ninjabackend.py", line 2249, in generate_genlist_for_target
    elem.add_dep([self.get_target_filename(x) for x in generator.depends])
  File "/home/kusma/.local/lib/python3.10/site-packages/mesonbuild/backend/ninjabackend.py", line 2249, in <listcomp>
    elem.add_dep([self.get_target_filename(x) for x in generator.depends])
  File "/home/kusma/.local/lib/python3.10/site-packages/mesonbuild/backend/backends.py", line 319, in get_target_filename
    assert isinstance(t, build.BuildTarget)
AssertionError

ERROR: Unhandled python exception

    This is a Meson bug and should be reported!

Expected behavior Meson should finish configure, and let us at least try to compile the result.

system parameters

kusma commented 2 years ago

Worth noting: This seems to work if the second generator is replaced with custom_target() instead:

project('bug-repro', 'c')

gen_foo = generator(
  find_program('cat'),
  output : '@BASENAME@.foo',
  arguments : ['@INPUT@'],
  capture : true
)

input_foo = gen_foo.process('input.txt')

input_bar = custom_target('input.bar',
  input: input_foo,
  output: 'input.bar',
  command : [find_program('cat'), '@INPUT@'],
  capture : true
)

executable(
  'dummy', [files('main.c'), input_bar],
)

Just to give some more background on what I'm trying to do:

I'm trying to implement baking of binary data to be embedded into an executable using Meson. This involves processing some graphics files (tiling of images, dumping of bitmap data etc) as well as some bin2c kind of magic at the end to create something that can be compiled out of the result.

However, these baking tasks are fairly repetitive, so generators makes it a lot more manageable to maintain. Sadly, that doesn't seem to work.

amyspark commented 1 year ago

This is still an issue with meson 1.1.1 and 1.2.0. In the latter two cases, such a chaining just results in a build time Ninja error:

ninja: error: 'libavfilter/vf_yadif_videotoolbox.metal.metallib', needed by 'libavfilter-static.a.p/vf_yadif_videotoolbox.metal.metallib.c', missing and no known rule to make it

Files are generated e.g.

  gen_objects = libavfilter_optional_sources['yadif_videotoolbox_filter']
  gen_objects += bin2c.process(metallib.process(metalcc.process(
    files('metal/vf_yadif_videotoolbox.metal',)
  )))
  libavfilter_optional_sources += {
    'yadif_videotoolbox_filter' : gen_objects,
  }