aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2022-08-24 13:11:00 -0700
committerNirbheek Chauhan <nirbheek@centricular.com>2022-09-02 13:40:05 +0530
commitc6656793cc4d0af0557492d825ed1e257577a464 (patch)
tree55e3de984d1800a1e884dcabe8b9998471398a40
parent30f20bb3d338849e81356aa52027b5c6b8c31c7f (diff)
downloadmeson-c6656793cc4d0af0557492d825ed1e257577a464.zip
meson-c6656793cc4d0af0557492d825ed1e257577a464.tar.gz
meson-c6656793cc4d0af0557492d825ed1e257577a464.tar.bz2
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.
-rw-r--r--mesonbuild/backend/backends.py23
-rw-r--r--mesonbuild/backend/ninjabackend.py33
-rw-r--r--mesonbuild/backend/vs2010backend.py2
3 files changed, 41 insertions, 17 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index c3c44e6..90010b6 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.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:
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 27ff0ad..da9daa6 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -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)
@@ -2594,7 +2608,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
"""
@@ -2681,6 +2698,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)
@@ -2899,7 +2918,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:
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index 5711404..030ef75 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -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: