mirror of
https://github.com/mesonbuild/meson.git
synced 2026-11-06 05:16:42 +00:00
Fix missing build project prefixes
A build project prefix ("build.") was introduced in 499f73da1 to separate build
files from host and build targets when cross compiling subprojects.
Additional work was done in 83fba12da. However, this prefix was missing from
some places:
- for generated files, with or without `build_subdir`: those files were
generated at the same place for both host and build targets.
- for include dirs: was erroring if it was only available in the build
tree.
- for subdirs
- for generated ast
Additionally, extra_build_dirs were double-prefixed.
This commit is contained in:
1 parent
9706cac6af
commit
fb511f0ab1
15 files changed
+109
-23
No files matched your search
@@ -3092,19 +3092,20 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
|
||||
return (rel_obj, rel_src)
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def generate_inc_dir(self, compiler: 'Compiler', d: str, basedir: str, is_system: bool
|
||||
def generate_inc_dir(self, compiler: Compiler, d: str, inc_dir: build.IncludeDirs
|
||||
) -> T.Tuple[ImmutableListProtocol[str], ImmutableListProtocol[str]]:
|
||||
expdir = os.path.normpath(os.path.join(basedir, d))
|
||||
expdir = os.path.join(inc_dir.curdir, d)
|
||||
srctreedir = os.path.normpath(os.path.join(self.build_to_src, expdir))
|
||||
sargs = compiler.get_include_args(srctreedir, is_system)
|
||||
sargs = compiler.get_include_args(srctreedir, inc_dir.is_system)
|
||||
# There may be include dirs where a build directory has not been
|
||||
# created for some source dir. For example if someone does this:
|
||||
#
|
||||
# inc = include_directories('foo/bar/baz')
|
||||
#
|
||||
# But never subdir()s into the actual dir.
|
||||
if os.path.isdir(os.path.join(self.environment.get_build_dir(), expdir)):
|
||||
bargs = compiler.get_include_args(expdir, is_system)
|
||||
build_subdir = os.path.normpath(inc_dir.build_project.prefix + expdir)
|
||||
if os.path.isdir(os.path.join(self.environment.get_build_dir(), build_subdir)):
|
||||
bargs = compiler.get_include_args(build_subdir, inc_dir.is_system)
|
||||
else:
|
||||
bargs = []
|
||||
return (sargs, bargs)
|
||||
@@ -3134,7 +3135,6 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
|
||||
# external deps and must maintain the order in which they are specified.
|
||||
# Hence, we must reverse the list so that the order is preserved.
|
||||
for i in reversed(target.get_include_dirs()):
|
||||
basedir = i.curdir
|
||||
# Each directory must be added to CompilerArgs individually
|
||||
# via a separate ``commands +=`` call, in reversed order.
|
||||
#
|
||||
@@ -3159,11 +3159,11 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
|
||||
# appended at once in the original (unreversed) order, making
|
||||
# the *first*-listed directory appear first instead of last.
|
||||
for d in reversed(i.incdirs):
|
||||
sargs, bargs = self.generate_inc_dir(compiler, d, basedir, i.is_system)
|
||||
sargs, bargs = self.generate_inc_dir(compiler, d, i)
|
||||
commands += sargs
|
||||
commands += bargs
|
||||
for d in i.extra_build_dirs:
|
||||
commands += compiler.get_include_args(d, i.is_system)
|
||||
commands += compiler.get_include_args(os.path.normpath(os.path.join(i.curdir, d)), i.is_system)
|
||||
|
||||
# Add any embed search dir arguments
|
||||
for i in target.embed_dirs:
|
||||
|
||||
@@ -1046,13 +1046,14 @@ class Vs2010Backend(backends.Backend):
|
||||
try:
|
||||
# Add source subdir first so that the build subdir overrides it
|
||||
args.append('-I' + os.path.join(proj_to_src_root, curdir)) # src dir
|
||||
args.append('-I' + self.relpath(curdir, target.subdir)) # build dir
|
||||
args.append('-I' + self.relpath(d.build_project.prefix + curdir,
|
||||
self.get_target_dir(target))) # build dir
|
||||
except ValueError:
|
||||
# Include is on different drive
|
||||
args.append('-I' + os.path.normpath(curdir))
|
||||
for i in d.extra_build_dirs:
|
||||
curdir = os.path.join(d.curdir, i)
|
||||
args.append('-I' + self.relpath(curdir, target.subdir)) # build dir
|
||||
args.append('-I' + self.relpath(curdir, self.get_target_dir(target))) # build dir
|
||||
# Add per-target compile args, f.ex, `c_args : ['/DFOO']`. We set these
|
||||
# near the end since these are supposed to override everything else.
|
||||
for l, args in target.extra_args.items():
|
||||
|
||||
+10
-8
@@ -734,7 +734,7 @@ class IncludeDirs(HoldableObject):
|
||||
for idir in self.incdirs:
|
||||
strlist.append(os.path.join(sourcedir, self.curdir, idir))
|
||||
strlist.append(os.path.join(builddir, bsubdir, idir))
|
||||
strlist.extend(os.path.join(builddir, bsubdir, idir) for idir in self.extra_build_dirs)
|
||||
strlist.extend(os.path.join(builddir, self.curdir, idir) for idir in self.extra_build_dirs)
|
||||
return strlist
|
||||
|
||||
def rel_string_list(self, build_to_src: str, build_root: T.Optional[str] = None) -> T.List[str]:
|
||||
@@ -748,13 +748,15 @@ class IncludeDirs(HoldableObject):
|
||||
strlist: T.List[str] = []
|
||||
bsubdir = self.build_project.prefix + self.curdir
|
||||
|
||||
for idirs, add_src in [(self.incdirs, True), (self.extra_build_dirs, False)]:
|
||||
for idir in idirs:
|
||||
bld_dir = os.path.normpath(os.path.join(bsubdir, idir))
|
||||
if build_root is None or os.path.isdir(os.path.join(build_root, bld_dir)):
|
||||
strlist.append(bld_dir)
|
||||
if add_src:
|
||||
strlist.append(os.path.normpath(os.path.join(build_to_src, self.curdir, idir)))
|
||||
for idir in self.incdirs:
|
||||
bld_dir = os.path.normpath(os.path.join(bsubdir, idir))
|
||||
if build_root is None or os.path.isdir(os.path.join(build_root, bld_dir)):
|
||||
strlist.append(bld_dir)
|
||||
strlist.append(os.path.normpath(os.path.join(build_to_src, self.curdir, idir)))
|
||||
for idir in self.extra_build_dirs:
|
||||
bld_dir = os.path.normpath(os.path.join(self.curdir, idir))
|
||||
if build_root is None or os.path.isdir(os.path.join(build_root, bld_dir)):
|
||||
strlist.append(bld_dir)
|
||||
|
||||
return strlist
|
||||
|
||||
|
||||
@@ -980,7 +980,7 @@ class Interpreter(InterpreterBase, HoldableObject):
|
||||
mlog.error(*msg)
|
||||
raise e
|
||||
|
||||
self.create_build_subdir(subdir)
|
||||
self.create_build_subdir(for_machine.get_prefix() + subdir)
|
||||
self.global_args_frozen = True
|
||||
|
||||
stack = self.format_subproject_stack(fullstack, ':')
|
||||
@@ -1052,7 +1052,7 @@ class Interpreter(InterpreterBase, HoldableObject):
|
||||
|
||||
with mlog.nested(subp_name):
|
||||
if ast:
|
||||
self._save_ast(subdir, ast)
|
||||
self._save_ast(for_machine.get_prefix() + subdir, ast)
|
||||
|
||||
subi = Interpreter(new_build, self.backend, subp_name, subdir, self.subproject_dir,
|
||||
default_options, ast=ast, relaxations=relaxations,
|
||||
@@ -2713,12 +2713,13 @@ class Interpreter(InterpreterBase, HoldableObject):
|
||||
if not is_new:
|
||||
raise InvalidArguments(f'Tried to enter directory "{subdir}", which has already been visited.')
|
||||
|
||||
self.create_build_subdir(subdir)
|
||||
build_subdir = self.current_build_project().prefix + subdir
|
||||
self.create_build_subdir(build_subdir)
|
||||
|
||||
if self.relaxed(InterpreterRuleRelaxation.CARGO_SUBDIR) and \
|
||||
os.path.exists(os.path.join(self.environment.get_source_dir(), subdir, 'Cargo.toml')):
|
||||
codeblock = self.cargo.interpret(subdir, self.root_subdir)
|
||||
self._save_ast(subdir, codeblock)
|
||||
self._save_ast(build_subdir, codeblock)
|
||||
self._evaluate_codeblock(codeblock, subdir)
|
||||
elif not self._evaluate_subdir(self.environment.get_source_dir(), subdir):
|
||||
buildfilename = os.path.join(subdir, environment.build_filename)
|
||||
@@ -3116,7 +3117,7 @@ class Interpreter(InterpreterBase, HoldableObject):
|
||||
src_root = self.environment.get_source_dir()
|
||||
build_root = self.environment.get_build_dir()
|
||||
absbase_src = os.path.join(src_root, self.subdir)
|
||||
absbase_build = os.path.join(build_root, self.subdir)
|
||||
absbase_build = os.path.join(build_root, self.current_build_dir())
|
||||
|
||||
for a in incdir_strings:
|
||||
if path_is_in_root(Path(a), Path(src_root)):
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
project('native subproject build dirs', 'c', meson_version: '>=1.12.0')
|
||||
|
||||
subproject('sub', native: true)
|
||||
subproject('sub', native: false)
|
||||
subproject('nativeonly', native: true)
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#define FOR_MACHINE @for_machine@
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
data = configuration_data()
|
||||
data.set('for_machine', meson.is_cross_build() ? 1 : 0)
|
||||
configure_file(input: 'gen.h.in', output: 'gen.h', configuration: data)
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "gen.h"
|
||||
|
||||
#if FOR_MACHINE != EXPECTED
|
||||
#error Wrong architecture
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
project('native only', 'c')
|
||||
|
||||
subdir('gen')
|
||||
|
||||
executable('main', 'main.c',
|
||||
include_directories: include_directories('gen'),
|
||||
c_args: '-DEXPECTED=@0@'.format(meson.is_cross_build() ? 1 : 0),
|
||||
)
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#define FOR_MACHINE @for_machine@
|
||||
@@ -0,0 +1,3 @@
|
||||
data = configuration_data()
|
||||
data.set('for_machine', meson.is_cross_build() ? 1 : 0)
|
||||
configure_file(input: 'gen.h.in', output: 'gen.h', build_subdir: 'sub2', configuration: data)
|
||||
@@ -0,0 +1 @@
|
||||
#pragma once
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "gen.h"
|
||||
#include "static.h"
|
||||
|
||||
#if FOR_MACHINE != EXPECTED
|
||||
#error Wrong architecture
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
project('sub', 'c', meson_version: '>=1.10.0')
|
||||
|
||||
subdir('gen')
|
||||
|
||||
executable('main', 'main.c',
|
||||
include_directories: include_directories('inc', 'gen/sub2'),
|
||||
c_args: '-DEXPECTED=@0@'.format(meson.is_cross_build() ? 1 : 0),
|
||||
)
|
||||
@@ -5079,6 +5079,33 @@ class AllPlatformTests(BasePlatformTests):
|
||||
self.setconf('-Duse-sub=true')
|
||||
self.build()
|
||||
|
||||
def test_native_subproject_build_dirs(self):
|
||||
# Ensure that in a cross build, a native subproject has include dirs,
|
||||
# configure_file outputs and subdirs under build.<subdir>, not in the host tree.
|
||||
crossdir = os.path.join(self.unit_test_dir, '69 cross')
|
||||
# Reuse the cross test project to generate a native and a cross file
|
||||
# describing this machine, so the configuration below is treated as a
|
||||
# cross build (see test_identity_cross).
|
||||
self.init(crossdir, extra_args=['-Dgenerate=true'])
|
||||
self.meson_native_files = [os.path.join(self.builddir, "nativefile")]
|
||||
self.meson_cross_files = [os.path.join(self.builddir, "crossfile")]
|
||||
|
||||
self.new_builddir()
|
||||
testdir = os.path.join(self.unit_test_dir, '146 native subproject build dirs')
|
||||
self.init(testdir)
|
||||
self.build()
|
||||
|
||||
build_path = Path(self.builddir, 'build.subprojects/sub/gen/sub2/gen.h')
|
||||
self.assertPathExists(build_path)
|
||||
self.assertIn('FOR_MACHINE 0', build_path.read_text(encoding='utf8'))
|
||||
|
||||
host_path = Path(self.builddir, 'subprojects/sub/gen/sub2/gen.h')
|
||||
self.assertPathExists(host_path)
|
||||
self.assertIn('FOR_MACHINE 1', host_path.read_text(encoding='utf8'))
|
||||
|
||||
self.assertPathExists(os.path.join(self.builddir, 'build.subprojects/nativeonly'))
|
||||
self.assertPathDoesNotExist(os.path.join(self.builddir, 'subprojects/nativeonly'))
|
||||
|
||||
def test_devenv(self):
|
||||
testdir = os.path.join(self.unit_test_dir, '90 devenv')
|
||||
self.init(testdir)
|
||||
|
||||
Reference in new issue
Block a user