backend/ninja: properly track objects extracted from fortran sources

We need this to ensure that .mod files are created before we start
compiling, and to ensure that the proper include directory arguments are
generated.
pull/10703/head
Dylan Baker 2 years ago committed by Eli Schwartz
parent a044f42308
commit c02d7fe119
  1. 23
      mesonbuild/backend/backends.py
  2. 33
      mesonbuild/backend/ninjabackend.py
  3. 2
      mesonbuild/backend/vs2010backend.py

@ -305,7 +305,7 @@ class Backend:
elif isinstance(t, build.CustomTargetIndex):
filename = t.get_outputs()[0]
else:
assert isinstance(t, build.BuildTarget)
assert isinstance(t, build.BuildTarget), t
filename = t.get_filename()
return os.path.join(self.get_target_dir(t), filename)
@ -452,18 +452,20 @@ class Backend:
return os.path.relpath(os.path.join('dummyprefixdir', todir),
os.path.join('dummyprefixdir', fromdir))
def flatten_object_list(self, target: build.BuildTarget, proj_dir_to_build_root: str = '') -> T.List[str]:
obj_list = self._flatten_object_list(target, target.get_objects(), proj_dir_to_build_root)
return list(dict.fromkeys(obj_list))
def flatten_object_list(self, target: build.BuildTarget, proj_dir_to_build_root: str = ''
) -> T.Tuple[T.List[str], T.List[build.BuildTargetTypes]]:
obj_list, deps = self._flatten_object_list(target, target.get_objects(), proj_dir_to_build_root)
return list(dict.fromkeys(obj_list)), deps
def determine_ext_objs(self, objects: build.ExtractedObjects, proj_dir_to_build_root: str = '') -> T.List[str]:
obj_list = self._flatten_object_list(objects.target, [objects], proj_dir_to_build_root)
obj_list, _ = self._flatten_object_list(objects.target, [objects], proj_dir_to_build_root)
return list(dict.fromkeys(obj_list))
def _flatten_object_list(self, target: build.BuildTarget,
objects: T.Sequence[T.Union[str, 'File', build.ExtractedObjects]],
proj_dir_to_build_root: str) -> T.List[str]:
proj_dir_to_build_root: str) -> T.Tuple[T.List[str], T.List[build.BuildTargetTypes]]:
obj_list: T.List[str] = []
deps: T.List[build.BuildTargetTypes] = []
for obj in objects:
if isinstance(obj, str):
o = os.path.join(proj_dir_to_build_root,
@ -480,11 +482,14 @@ class Backend:
obj_list.append(obj.rel_to_builddir(o))
elif isinstance(obj, build.ExtractedObjects):
if obj.recursive:
obj_list += self._flatten_object_list(obj.target, obj.objlist, proj_dir_to_build_root)
obj_list += self._determine_ext_objs(obj, proj_dir_to_build_root)
objs, d = self._flatten_object_list(obj.target, obj.objlist, proj_dir_to_build_root)
obj_list.extend(objs)
deps.extend(d)
obj_list.extend(self._determine_ext_objs(obj, proj_dir_to_build_root))
deps.append(obj.target)
else:
raise MesonException('Unknown data type in object list.')
return obj_list
return obj_list, deps
@staticmethod
def is_swift_target(target: build.BuildTarget) -> bool:

@ -859,6 +859,16 @@ class NinjaBackend(backends.Backend):
else:
pch_objects = []
o, od = self.flatten_object_list(target)
obj_targets = [t for t in od if t.uses_fortran()]
obj_list.extend(o)
fortran_order_deps = [self.get_target_filename(t) for t in obj_targets]
fortran_inc_args: T.List[str] = []
if target.uses_fortran():
fortran_inc_args = mesonlib.listify([target.compilers['fortran'].get_include_args(
self.get_target_private_dir(t), is_system=False) for t in obj_targets])
# Generate compilation targets for C sources generated from Vala
# sources. This can be extended to other $LANG->C compilers later if
# necessary. This needs to be separate for at least Vala
@ -898,15 +908,17 @@ class NinjaBackend(backends.Backend):
src.rel_to_builddir(self.build_to_src))
unity_src.append(abs_src)
else:
o, s = self.generate_single_compile(target, src, False, [], header_deps + d_generated_deps)
o, s = self.generate_single_compile(target, src, False, [],
header_deps + d_generated_deps + fortran_order_deps,
fortran_inc_args)
obj_list.append(o)
compiled_sources.append(s)
source2object[s] = o
obj_list += self.flatten_object_list(target)
if is_unity:
for src in self.generate_unity_files(target, unity_src):
o, s = self.generate_single_compile(target, src, True, unity_deps + header_deps + d_generated_deps)
o, s = self.generate_single_compile(target, src, True, unity_deps + header_deps + d_generated_deps,
fortran_order_deps, fortran_inc_args)
obj_list.append(o)
compiled_sources.append(s)
source2object[s] = o
@ -916,7 +928,7 @@ class NinjaBackend(backends.Backend):
else:
final_obj_list = obj_list
elem = self.generate_link(target, outname, final_obj_list, linker, pch_objects, stdlib_args=stdlib_args)
self.generate_dependency_scan_target(target, compiled_sources, source2object, generated_source_files)
self.generate_dependency_scan_target(target, compiled_sources, source2object, generated_source_files, fortran_order_deps)
self.add_build(elem)
def should_use_dyndeps_for_target(self, target: 'build.BuildTarget') -> bool:
@ -941,7 +953,8 @@ class NinjaBackend(backends.Backend):
return False
return True
def generate_dependency_scan_target(self, target, compiled_sources, source2object, generated_source_files: T.List[mesonlib.File]):
def generate_dependency_scan_target(self, target, compiled_sources, source2object, generated_source_files: T.List[mesonlib.File],
object_deps: T.List[str]) -> None:
if not self.should_use_dyndeps_for_target(target):
return
depscan_file = self.get_dep_scan_file_for(target)
@ -963,6 +976,7 @@ class NinjaBackend(backends.Backend):
# that those sources are present
for g in generated_source_files:
elem.orderdeps.add(g.relative_name())
elem.orderdeps.update(object_deps)
scaninfo = TargetDependencyScannerInfo(self.get_target_private_dir(target), source2object)
with open(pickle_abs, 'wb') as p:
pickle.dump(scaninfo, p)
@ -2605,7 +2619,10 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
commands += compiler.get_include_args(self.get_target_private_dir(target), False)
return commands
def generate_single_compile(self, target, src, is_generated=False, header_deps=None, order_deps=None):
def generate_single_compile(self, target: build.BuildTarget, src,
is_generated=False, header_deps=None,
order_deps: T.Optional[T.List[str]] = None,
extra_args: T.Optional[T.List[str]] = None) -> None:
"""
Compiles C/C++, ObjC/ObjC++, Fortran, and D sources
"""
@ -2692,6 +2709,8 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
rel_obj)
self.add_build(depelem)
commands += compiler.get_module_outdir_args(self.get_target_private_dir(target))
if extra_args is not None:
commands.extend(extra_args)
element = NinjaBuildElement(self.all_outputs, rel_obj, compiler_name, rel_src)
self.add_header_deps(target, element, header_deps)
@ -2910,7 +2929,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
for dep in target.link_whole_targets:
l = dep.extract_all_objects(False)
objects_from_static_libs += self.determine_ext_objs(l, '')
objects_from_static_libs.extend(self.flatten_object_list(dep))
objects_from_static_libs.extend(self.flatten_object_list(dep)[0])
return objects_from_static_libs
else:

@ -1279,7 +1279,7 @@ class Vs2010Backend(backends.Backend):
for lib in self.get_custom_target_provided_libraries(target):
additional_links.append(self.relpath(lib, self.get_target_dir(target)))
additional_objects = []
for o in self.flatten_object_list(target, down):
for o in self.flatten_object_list(target, down)[0]:
assert isinstance(o, str)
additional_objects.append(o)
for o in custom_objs:

Loading…
Cancel
Save