backends: Stop passing generator exes to ExecutableSerialisation as strings

The code below this already handles being passed an Executable or
ExternalProgram, and it does it correctly, since it handles host
binaries that need an exe_wrapper correctly, while the code in the
generator paths doesn't.

The xcode backend is, like always, problematic, it doesn't handle things
the same way as the ninja and vscode backends, and generates a shell
script instead of using meson as a wrapper when needed (it seems likely
that just forcing the meson path for xcode would be better). I don't
have a working mac to develop a fix for, so I've left a todo comment
there.

Fixes: #11264
pull/11269/head
Dylan Baker 2 years ago
parent 8655287c56
commit 6aeec80836
  1. 5
      mesonbuild/backend/ninjabackend.py
  2. 6
      mesonbuild/backend/vs2010backend.py
  3. 2
      mesonbuild/backend/xcodebackend.py
  4. 35
      test cases/common/105 generatorcustom/gen.c
  5. 9
      test cases/common/105 generatorcustom/host.c
  6. 16
      test cases/common/105 generatorcustom/meson.build
  7. 1
      test cases/failing/129 generator host binary/exe.c
  8. 1
      test cases/failing/129 generator host binary/lib.in
  9. 14
      test cases/failing/129 generator host binary/meson.build
  10. 5
      test cases/failing/129 generator host binary/test.json

@ -2388,7 +2388,6 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
generator = genlist.get_generator()
subdir = genlist.subdir
exe = generator.get_exe()
exe_arr = self.build_target_to_cmd_array(exe)
infilelist = genlist.get_inputs()
outfilelist = genlist.get_outputs()
extra_dependencies = self.get_custom_target_depend_files(genlist)
@ -2416,8 +2415,8 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
if len(generator.outputs) > 1:
outfilelist = outfilelist[len(generator.outputs):]
args = self.replace_paths(target, args, override_subdir=subdir)
cmdlist = exe_arr + self.replace_extra_args(args, genlist)
cmdlist, reason = self.as_meson_exe_cmdline(cmdlist[0], cmdlist[1:],
cmdlist, reason = self.as_meson_exe_cmdline(exe,
self.replace_extra_args(args, genlist),
capture=outfiles[0] if generator.capture else None)
abs_pdir = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target))
os.makedirs(abs_pdir, exist_ok=True)

@ -137,7 +137,6 @@ class Vs2010Backend(backends.Backend):
infilelist = genlist.get_inputs()
outfilelist = genlist.get_outputs()
source_dir = os.path.join(down, self.build_to_src, genlist.subdir)
exe_arr = self.build_target_to_cmd_array(exe)
idgroup = ET.SubElement(parent_node, 'ItemGroup')
for i, curfile in enumerate(infilelist):
if len(infilelist) == len(outfilelist):
@ -161,13 +160,12 @@ class Vs2010Backend(backends.Backend):
.replace("@BUILD_ROOT@", self.environment.get_build_dir())
for x in args]
args = [x.replace('\\', '/') for x in args]
cmd = exe_arr + self.replace_extra_args(args, genlist)
# Always use a wrapper because MSBuild eats random characters when
# there are many arguments.
tdir_abs = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target))
cmd, _ = self.as_meson_exe_cmdline(
cmd[0],
cmd[1:],
exe,
self.replace_extra_args(args, genlist),
workdir=tdir_abs,
capture=outfiles[0] if generator.capture else None,
force_serialize=True

@ -1219,6 +1219,8 @@ class XCodeBackend(backends.Backend):
generator_id += 1
def generate_single_generator_phase(self, tname, t, genlist, generator_id, objects_dict):
# TODO: this should be rewritten to use the meson wrapper, like the other generators do
# Currently it doesn't handle a host binary that requires an exe wrapper correctly.
generator = genlist.get_generator()
exe = generator.get_exe()
exe_arr = self.build_target_to_cmd_array(exe)

@ -0,0 +1,35 @@
/* SPDX-License-Identifier: Apache-2.0 */
/* Copyright © 2023 Intel Corporation */
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char ** argv) {
if (argc != 3) {
fprintf(stderr, "%s %i %s\n", "Got incorrect number of arguments, got ", argc - 1, ", but expected 2");
exit(1);
}
FILE * input, * output;
if ((input = fopen(argv[1], "rb")) == NULL) {
exit(1);
}
if ((output = fopen(argv[2], "wb")) == NULL) {
exit(1);
}
fprintf(output, "#pragma once\n");
fprintf(output, "#define ");
char c;
while((c = fgetc(input)) != EOF) {
fputc(c, output);
}
fputc('\n', output);
fclose(input);
fclose(output);
return 0;
}

@ -0,0 +1,9 @@
#include "res1-cpp.h"
int main(void) {
#ifdef res1
return 0;
#else
return 1;
#endif
}

@ -26,3 +26,19 @@ allinone = custom_target('alltogether',
proggie = executable('proggie', 'main.c', allinone)
test('proggie', proggie)
# specifically testing that cross binaries are run with an exe_wrapper
if meson.can_run_host_binaries()
gen_tool = executable('generator', 'gen.c', native : false)
c_gen = generator(
gen_tool,
output : '@BASENAME@-cpp.h',
arguments : ['@INPUT@', '@OUTPUT@']
)
hs2 = c_gen.process('res1.txt')
host_exe = executable('host_test', 'host.c', hs2, native : false)
test('compiled generator', host_exe)
endif

@ -0,0 +1,14 @@
project('generator host binary no exe_wrapper')
if meson.can_run_host_binaries()
error('MESON_SKIP_TEST: test requires that build machine cannot run host binaries')
endif
add_languages('c', native : false)
exe = executable('exe', 'exe.c', native : false)
gen = generator(exe, output : '@BASENAME@.c', arguments : ['@INPUT@', '@OUTPU@'])
foo = gen.process('lib.in')
library('foo', foo)

@ -0,0 +1,5 @@
{
"stdout": [
{ "line": "ERROR: An exe_wrapper is needed but was not found. Please define one in cross file and check the command and/or add it to PATH." }
]
}
Loading…
Cancel
Save