Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
e968f1b
vs2010backend: use Build.get_global_args
bonzini Jul 14, 2026
72febeb
build: pass target to get_global_*args
bonzini Jul 14, 2026
a69feb5
build, interpreter: handle per-machine project arguments in BuildTarget
bonzini Jul 14, 2026
0e31d2b
add testcase for 1.12 regression - add_project_arguments version
bonzini Jul 13, 2026
208e807
build: store original "native: true" setting for subprojects
bonzini Jul 14, 2026
14b9d55
build, interpreter: handle per-machine global arguments in BuildTarget
bonzini Jul 14, 2026
0f15ac8
add testcase for 1.12 regression - add_global_arguments version
bonzini Jul 14, 2026
2b99628
python: fix application of machine map
bonzini Jul 15, 2026
aa26598
adjust minimum version for external program as DEPENDS and INPUT
bonzini Jul 13, 2026
2156e94
interpreter: add FeatureNew for generated non-.pyx sources
bonzini Jul 13, 2026
cd1bad3
Revert "linkers: apple: do not pass -object_path_lto to dyld"
bonzini Jul 13, 2026
26564cd
linkers: apple: -object_path_lto was added in ld 123.2
bonzini Jul 13, 2026
db9f865
linker: apple: fix xtools version detection
bonzini Jul 13, 2026
34524b9
test cases: add test for rust.test with structured_sources
bonzini Jun 5, 2026
097a5f1
backends, build: add a single function to determine what is a header_dep
bonzini Jun 5, 2026
6bed198
ninjabackend: make the description of GeneratedLists more complete
bonzini Jun 5, 2026
add7ce5
build: include computed fields of GeneratedList in repr
bonzini Jun 5, 2026
d079935
scripts: do not assume directory is created before copy
bonzini Jun 5, 2026
322b462
build: add output_subdir to GeneratedList
bonzini Jun 5, 2026
1d5f0d3
build: generalize check for incorrect use of structured_sources
bonzini Jun 5, 2026
679b4a0
build, ninjabackend: add support for Generator description
bonzini Jun 5, 2026
18488f6
build: add a hardcoded Generator to copy from structured sources
bonzini Jun 5, 2026
7d0e476
build, ninjabackend: use GeneratedList for jar resources
bonzini Jun 5, 2026
c28ad87
build, ninjabackend: use GeneratedList for structured_sources
bonzini Jun 5, 2026
9425ffe
tests: add testcase for non-Rust structured_sources
bonzini Jun 5, 2026
b63b088
docs: add release notes for non-Rust structured_sources
bonzini Jun 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/markdown/Gnome-module.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ Generates a marshal file using the `glib-genmarshal` tool. The first
argument is the basename of the output files.

* `depends` [](BuildTarget | CustomTarget | CustomTargetIndex | Program):
passed directly to CustomTarget (*since 0.61.0*; `program` *since 1.11.2*)
passed directly to CustomTarget (*since 0.61.0*; `program` *since 1.12.0*)
* `depend_files` [](str | File): Passed directly to CustomTarget (*since 0.61.0*)
* `extra_args`: (*Added 0.42.0*) additional command line arguments to pass
* `install_dir`: directory to install header to
Expand Down
12 changes: 0 additions & 12 deletions docs/markdown/Release-notes-for-1.11.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,15 +203,3 @@ as dependencies.
now has an `implicit_include_directories` keyword argument to automatically
add current build and source directories to the included paths when compiling
a resource.

## External programs as inputs and dependencies to custom targets

Custom targets now allow specifying an external program in
the `input` and `depends` keyword arguments. This also applies
to several methods provided by modules, as they are lowered to
custom targets internally. (*Added in 1.11.2*).

## External programs as dependencies to tests

Tests now allow specifying an external program in
the `depends` keyword argument. (*Added in 1.11.2*).
12 changes: 12 additions & 0 deletions docs/markdown/snippets/programs-in-more-places.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## External programs as inputs and dependencies to custom targets

Custom targets now allow specifying an external program in
the `input` and `depends` keyword arguments. This also applies
to several methods provided by modules, as they are lowered to
custom targets internally.

## External programs as dependencies to tests

Tests now allow specifying an external program in
the `depends` keyword argument.

11 changes: 11 additions & 0 deletions docs/markdown/snippets/structured-sources-any-language.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## `structured_sources()` can be used with any language

[[structured_sources]] previously only worked with Rust build targets
and Java resources, and raised an error otherwise. It can now be used
with a target of any language (other than Java, where it can only be
used for resources like before).

Files will be laid out in the build directory according to the structure
described by the dictionary keys; for example, in the case of C
it will be possible to include a file from the `structured_sources()`
from another according to their provided path.
6 changes: 4 additions & 2 deletions mesonbuild/ast/introspection.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def __init__(self,

self.cross_file = cross_file
self.backend = backend
self.build_project = BuildProject(subproject, '', subproject, MachineChoice.HOST)
self.build_project = BuildProject(subproject, '', subproject, MachineChoice.HOST, MachineChoice.HOST)
self.project_data: T.Dict[str, T.Any] = {}
self.targets: T.List[IntrospectionBuildTarget] = []
self.dependencies: T.List[IntrospectionDependency] = []
Expand Down Expand Up @@ -254,12 +254,14 @@ def build_target(self, node: BaseNode, args: T.List[TYPE_var], kwargs_raw: T.Dic
assert extraf_nodes is None
extraf_nodes = v

for_machine = MachineChoice.BUILD if kwargs.get('native', False) else MachineChoice.HOST

# Make sure nothing can crash when creating the build class
_kwargs_reduced = {k: v for k, v in kwargs.items() if k in _TARGET_KWARGS[targetclass.typename] and k in {'install', 'build_by_default', 'build_always', 'name_prefix'}}
_kwargs_reduced = {k: v.value if isinstance(v, ElementaryNode) else v for k, v in _kwargs_reduced.items()}
_kwargs_reduced = {k: v for k, v in _kwargs_reduced.items() if not isinstance(v, (BaseNode, UnknownValue))}
_kwargs_reduced['native'] = for_machine
kwargs_reduced = T.cast('BuildTargetKeywordArguments', _kwargs_reduced)
for_machine = MachineChoice.BUILD if kwargs.get('native', False) else MachineChoice.HOST
objects: T.List[T.Any] = []
empty_sources: T.List[T.Any] = []
# Passing the unresolved sources list causes errors
Expand Down
2 changes: 1 addition & 1 deletion mesonbuild/backend/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -970,7 +970,7 @@ def generate_basic_compiler_args(self, target: build.BuildTarget, compiler: 'Com
commands += self.build.get_project_args(compiler, target)
# Add compile args added using add_global_arguments()
# These override per-project arguments
commands += self.build.get_global_args(compiler, target.for_machine)
commands += self.build.get_global_args(compiler, target)
# Compile args added from the env: CFLAGS/CXXFLAGS, etc, or the cross
# file. We want these to override all the defaults, but not the
# per-target compile args.
Expand Down
126 changes: 26 additions & 100 deletions mesonbuild/backend/ninjabackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -1073,15 +1073,14 @@ def generate_target(self, target: T.Union[build.Target]) -> None:
generated_source_files.append(raw_src)
elif compilers.is_object(rel_src):
obj_list.append(rel_src)
elif compilers.is_library(rel_src) or modules.is_module_library(rel_src):
pass
elif is_compile_target:
generated_source_files.append(raw_src)
else:
# Assume anything not specifically a source file is a header. This is because
# people generate files with weird suffixes (.inc, .fh) that they then include
# in their source files.
header_deps.append(raw_src)
elif compilers.is_unknown(rel_src):
if is_compile_target:
generated_source_files.append(raw_src)
else:
# Assume anything not specifically a source file is a header. This is because
# people generate files with weird suffixes (.inc, .fh) that they then include
# in their source files.
header_deps.append(raw_src)

# For D language, the object of generated source files are added
# as order only deps because other files may depend on them
Expand Down Expand Up @@ -1486,8 +1485,6 @@ def generate_rules(self) -> None:
self.add_rule(NinjaRule('CUSTOM_COMMAND_MSVC_DEP', ['$COMMAND'], [], '$DESC',
deps='msvc',
restat=True))
self.add_rule(NinjaRule('COPY_FILE', self.environment.get_build_command() + ['--internal', 'copy'],
['$in', '$out'], 'Copying $in to $out'))

c = self.environment.get_build_command() + \
['--internal',
Expand Down Expand Up @@ -1564,9 +1561,11 @@ def generate_jar_target(self, target: build.Jar) -> None:
commands += ['-C', self.get_target_private_dir(target), '.']
elem = NinjaBuildElement(self.all_outputs, outname_rel, jar_rule, [])
elem.add_dep(class_dep_list)
if resources:
for gl in resources:
# Copy all resources into the root of the jar.
elem.add_orderdep(self.__generate_sources_structure(Path(self.get_target_private_dir(target)), resources)[0])
self.generate_genlist_for_target(gl, target)
elem.add_orderdep([os.path.join(self.get_target_private_dir(target), o)
for o in gl.get_outputs()])
elem.add_item('ARGS', commands)
self.add_build(elem)
# Create introspection information
Expand Down Expand Up @@ -1896,7 +1895,7 @@ def generate_cython_transpile(self, target: build.BuildTarget) -> \
args += cython.get_optimization_args(optimization)
args += cython.get_option_compile_args(target, target.subproject)
args += cython.get_option_std_args(target, target.subproject)
args += self.build.get_global_args(cython, target.for_machine)
args += self.build.get_global_args(cython, target)
args += self.build.get_project_args(cython, target)
args += target.get_extra_args('cython')

Expand Down Expand Up @@ -1954,52 +1953,13 @@ def generate_cython_transpile(self, target: build.BuildTarget) -> \
cython_sources.append(output)
else:
generated_sources[ssrc] = mesonlib.File.from_built_file(builddir, ssrc)
# Following logic in L883-900 where we determine whether to add generated source
# as a header(order-only) dep to the .so compilation rule
if not compilers.is_source(ssrc) and \
not compilers.is_object(ssrc) and \
not compilers.is_library(ssrc) and \
not modules.is_module_library(ssrc):
if compilers.is_unknown(ssrc):
header_deps.append(ssrc)
for source in pyx_sources:
source.add_orderdep(header_deps)

return static_sources, generated_sources, cython_sources

def _generate_copy_target(self, src: FileOrString, output: Path) -> None:
"""Create a target to copy a source file from one location to another."""
if isinstance(src, File):
instr = src.absolute_path(self.environment.source_dir, self.environment.build_dir)
else:
instr = src
elem = NinjaBuildElement(self.all_outputs, [str(output)], 'COPY_FILE', [instr])
elem.add_orderdep(instr)
self.add_build(elem)

def __generate_sources_structure(self, root: Path, structured_sources: build.StructuredSources,
main_file_ext: T.Union[str, T.Tuple[str, ...]] = tuple(),
) -> T.Tuple[T.List[str], T.Optional[str]]:
first_file: T.Optional[str] = None
orderdeps: T.List[str] = []
for path, files in structured_sources.sources.items():
for file in files:
if isinstance(file, File):
out = root / path / Path(file.fname).name
self._generate_copy_target(file, out)
out_s = str(out)
orderdeps.append(out_s)
if first_file is None and out_s.endswith(main_file_ext):
first_file = out_s
else:
for f in file.get_outputs():
out = root / path / f
out_s = str(out)
orderdeps.append(out_s)
self._generate_copy_target(str(Path(file.subdir) / f), out)
if first_file is None and out_s.endswith(main_file_ext):
first_file = out_s
return orderdeps, first_file

def _add_rust_project_entry(self, name: str, main_rust_file: str, args: CompilerArgs,
crate_type: str, target_name: str,
from_subproject: bool, proc_macro_dylib_path: T.Optional[str],
Expand Down Expand Up @@ -2052,44 +2012,6 @@ def generate_rust_sources(self, target: build.BuildTarget) -> T.Tuple[T.List[str
# figures out what other files are needed via import
# statements and magic.
main_rust_file: T.Optional[str] = None
if target.structured_sources:
if target.structured_sources.needs_copy():
_ods, main_rust_file = self.__generate_sources_structure(Path(
self.get_target_private_dir(target)) / 'structured', target.structured_sources, '.rs')
if main_rust_file is None:
raise MesonException('Could not find a rust file to treat as the main file for ', target.name)
else:
# The only way to get here is to have only files in the "root"
# positional argument, which are all generated into the same
# directory
for g in target.structured_sources.sources['']:
if isinstance(g, File):
if g.endswith('.rs'):
main_rust_file = g.rel_to_builddir(self.build_to_src)
elif isinstance(g, GeneratedList):
for h in g.get_outputs():
if h.endswith('.rs'):
main_rust_file = os.path.join(self.get_target_private_dir(target), h)
break
else:
for h in g.get_outputs():
if h.endswith('.rs'):
main_rust_file = os.path.join(g.get_builddir(), h)
break
if main_rust_file is not None:
break

_ods = []
for f in target.structured_sources.as_list():
if isinstance(f, File):
_ods.append(f.rel_to_builddir(self.build_to_src))
else:
_ods.extend([os.path.join(self.build_to_src, f.subdir, s)
for s in f.get_outputs()])
self.all_structured_sources.update(_ods)
orderdeps.extend(_ods)
return orderdeps, main_rust_file

for i in target.get_sources():
if main_rust_file is None and i.endswith('.rs'):
main_rust_file = i.rel_to_builddir(self.build_to_src)
Expand Down Expand Up @@ -2416,7 +2338,7 @@ def generate_swift_target(self, target: build.BuildTarget) -> None:
compile_args += swiftc.get_module_args(module_name)
compile_args += swiftc.get_cxx_interoperability_args(target)
compile_args += self.build.get_project_args(swiftc, target)
compile_args += self.build.get_global_args(swiftc, target.for_machine)
compile_args += self.build.get_global_args(swiftc, target)
if isinstance(target, (build.StaticLibrary, build.SharedLibrary)):
# swiftc treats modules with a single source file, and the main.swift file in multi-source file modules
# as top-level code. This is undesirable in library targets since it emits a main function. Add the
Expand All @@ -2430,7 +2352,7 @@ def generate_swift_target(self, target: build.BuildTarget) -> None:
compile_args += target.get_extra_args('swift')
link_args = swiftc.get_output_args(os.path.join(self.environment.get_build_dir(), self.get_target_filename(target)))
link_args += self.build.get_project_link_args(swiftc, target)
link_args += self.build.get_global_link_args(swiftc, target.for_machine)
link_args += self.build.get_global_link_args(swiftc, target)
rundir = self.get_target_private_dir(target)
out_module_name = self.swift_module_file_name(target)
in_module_files = self.determine_swift_dep_modules(target)
Expand Down Expand Up @@ -2918,14 +2840,18 @@ def generate_genlist_for_target(self, genlist: build.GeneratedList, target: buil
if generator.depfile is not None:
elem.add_item('DEPFILE', depfile)

if len(generator.outputs) == 1:
what = f'{sole_output!r}'
if generator is self.environment.copy_generator:
self.all_structured_sources.update(outfilespriv)
if generator.description is not None:
desc = generator.description.format(input=curfile, output=outfilespriv[0])
else:
# since there are multiple outputs, we log the source that caused the rebuild
what = f'from {sole_output!r}'
desc = 'Generating '
if len(generator.outputs) == 1:
desc += f'{outfilespriv[0]!r} '
desc += f'from {curfile!r}'
if reason:
reason = f' (wrapped by meson {reason})'
elem.add_item('DESC', f'Generating {what}{reason}')
desc += f' (wrapped by meson {reason})'
elem.add_item('DESC', desc)

elem.add_item('COMMAND', cmdlist)
self.add_build(elem)
Expand Down
12 changes: 3 additions & 9 deletions mesonbuild/backend/vs2010backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -602,9 +602,7 @@ def split_sources(self, srclist: list[FileLike]) -> tuple[list[FileLike], list[F
lang = self.lang_from_source_file(i)
if lang not in languages:
languages.append(lang)
elif compilers.is_library(i):
pass
else:
elif compilers.is_unknown(i):
# Everything that is not an object or source file is considered a header.
headers.append(i)
return sources, headers, objects, languages
Expand Down Expand Up @@ -1063,15 +1061,11 @@ def get_args_defines_and_inc_dirs(
file_args[l] += comp.get_option_std_args(
target, target.subproject)

# Add compile args added using add_project_arguments()
# Add compile args added using add_project_arguments() and add_global_arguments()
for l, comp in target.compilers.items():
file_args[l] += self.build.get_project_args(comp, target)
file_args[l] += self.build.get_global_args(comp, target)

# Add compile args added using add_global_arguments()
# These override per-project arguments
for l, args in self.build.global_args[target.for_machine].items():
if l in file_args:
file_args[l] += args
# Compile args added from the env or cross file: CFLAGS/CXXFLAGS, etc. We want these
# to override all the defaults, but not the per-target compile args.
for lang in file_args.keys():
Expand Down
Loading
Loading