diff options
-rw-r--r-- | lib/spack/spack/package.py | 67 |
1 files changed, 46 insertions, 21 deletions
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py index c79237dbef..b203551b07 100644 --- a/lib/spack/spack/package.py +++ b/lib/spack/spack/package.py @@ -1288,43 +1288,68 @@ class PackageBase(with_metaclass(PackageMeta, PackageViewMixin, object)): dump_packages(self.spec, packages_dir) def _if_make_target_execute(self, target): - try: - # Check if we have a makefile - file = [x for x in ('Makefile', 'makefile') if os.path.exists(x)] - file = file.pop() - except IndexError: + make = inspect.getmodule(self).make + + # Check if we have a Makefile + for makefile in ['GNUmakefile', 'Makefile', 'makefile']: + if os.path.exists(makefile): + break + else: tty.msg('No Makefile found in the build directory') return - # Check if 'target' is in the makefile - regex = re.compile('^' + target + ':') - with open(file, 'r') as f: - matches = [line for line in f.readlines() if regex.match(line)] - - if not matches: - tty.msg("Target '" + target + ":' not found in Makefile") + # Check if 'target' is a valid target + # + # -q, --question + # ``Question mode''. Do not run any commands, or print anything; + # just return an exit status that is zero if the specified + # targets are already up to date, nonzero otherwise. + # + # https://www.gnu.org/software/make/manual/html_node/Options-Summary.html + # + # The exit status of make is always one of three values: + # + # 0 The exit status is zero if make is successful. + # + # 2 The exit status is two if make encounters any errors. + # It will print messages describing the particular errors. + # + # 1 The exit status is one if you use the '-q' flag and make + # determines that some target is not already up to date. + # + # https://www.gnu.org/software/make/manual/html_node/Running.html + # + # NOTE: This only works for GNU Make, not NetBSD Make. + make('-q', target, fail_on_error=False) + if make.returncode == 2: + tty.msg("Target '" + target + "' not found in " + makefile) return # Execute target - inspect.getmodule(self).make(target) + make(target) def _if_ninja_target_execute(self, target): - # Check if we have a ninja build script + ninja = inspect.getmodule(self).ninja + + # Check if we have a Ninja build script if not os.path.exists('build.ninja'): - tty.msg('No ninja build script found in the build directory') + tty.msg('No Ninja build script found in the build directory') return - # Check if 'target' is in the ninja build script - regex = re.compile('^build ' + target + ':') - with open('build.ninja', 'r') as f: - matches = [line for line in f.readlines() if regex.match(line)] + # Get a list of all targets in the Ninja build script + # https://ninja-build.org/manual.html#_extra_tools + all_targets = ninja('-t', 'targets', output=str).split('\n') + + # Check if 'target' is a valid target + matches = [line for line in all_targets + if line.startswith(target + ':')] if not matches: - tty.msg("Target 'build " + target + ":' not found in build.ninja") + tty.msg("Target '" + target + "' not found in build.ninja") return # Execute target - inspect.getmodule(self).ninja(target) + ninja(target) def _get_needed_resources(self): resources = [] |