diff options
Diffstat (limited to 'mesonbuild/backend/ninjabackend.py')
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 141 |
1 files changed, 77 insertions, 64 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 595fedd..e81c407 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -133,17 +133,18 @@ class NinjaBackend(backends.Backend): self.all_outputs = {} self.valgrind = environment.find_valgrind() - def detect_vs_dep_prefix(self, outfile, tempfilename): + def detect_vs_dep_prefix(self, tempfilename): '''VS writes its dependency in a locale dependent format. Detect the search prefix to use.''' # Of course there is another program called 'cl' on # some platforms. Let's just require that on Windows # cl points to msvc. if not mesonlib.is_windows() or shutil.which('cl') is None: - return outfile - outfile.close() - open(os.path.join(self.environment.get_scratch_dir(), 'incdetect.c'), - 'w').write('''#include<stdio.h> + return open(tempfilename, 'a') + filename = os.path.join(self.environment.get_scratch_dir(), + 'incdetect.c') + with open(filename, 'w') as f: + f.write('''#include<stdio.h> int dummy; ''') @@ -157,9 +158,8 @@ int dummy; for line in stdo.split(b'\r\n'): if line.endswith(b'stdio.h'): matchstr = b':'.join(line.split(b':')[0:2]) + b':' - binfile = open(tempfilename, 'ab') - binfile.write(b'msvc_deps_prefix = ' + matchstr + b'\r\n') - binfile.close() + with open(tempfilename, 'ab') as binfile: + binfile.write(b'msvc_deps_prefix = ' + matchstr + b'\r\n') return open(tempfilename, 'a') raise MesonException('Could not determine vs dep dependency prefix string.') @@ -167,30 +167,31 @@ int dummy; self.interpreter = interp outfilename = os.path.join(self.environment.get_build_dir(), self.ninja_filename) tempfilename = outfilename + '~' - outfile = open(tempfilename, 'w') - outfile.write('# This is the build file for project "%s"\n' % self.build.get_project()) - outfile.write('# It is autogenerated by the Meson build system.\n') - outfile.write('# Do not edit by hand.\n\n') - outfile.write('ninja_required_version = 1.5.1\n\n') - outfile = self.detect_vs_dep_prefix(outfile, tempfilename) - self.generate_rules(outfile) - self.generate_phony(outfile) - outfile.write('# Build rules for targets\n\n') - [self.generate_target(t, outfile) for t in self.build.get_targets().values()] - outfile.write('# Test rules\n\n') - self.generate_tests(outfile) - outfile.write('# Install rules\n\n') - self.generate_install(outfile) - if 'b_coverage' in self.environment.coredata.base_options and \ - self.environment.coredata.base_options['b_coverage'].value: - outfile.write('# Coverage rules\n\n') - self.generate_coverage_rules(outfile) - outfile.write('# Suffix\n\n') - self.generate_utils(outfile) - self.generate_ending(outfile) + with open(tempfilename, 'w') as outfile: + outfile.write('# This is the build file for project "%s"\n' % + self.build.get_project()) + outfile.write('# It is autogenerated by the Meson build system.\n') + outfile.write('# Do not edit by hand.\n\n') + outfile.write('ninja_required_version = 1.5.1\n\n') + with self.detect_vs_dep_prefix(tempfilename) as outfile: + self.generate_rules(outfile) + self.generate_phony(outfile) + outfile.write('# Build rules for targets\n\n') + for t in self.build.get_targets().values(): + self.generate_target(t, outfile) + outfile.write('# Test rules\n\n') + self.generate_tests(outfile) + outfile.write('# Install rules\n\n') + self.generate_install(outfile) + if 'b_coverage' in self.environment.coredata.base_options and \ + self.environment.coredata.base_options['b_coverage'].value: + outfile.write('# Coverage rules\n\n') + self.generate_coverage_rules(outfile) + outfile.write('# Suffix\n\n') + self.generate_utils(outfile) + self.generate_ending(outfile) # Only ovewrite the old build file after the new one has been # fully created. - outfile.close() os.replace(tempfilename, outfilename) self.generate_compdb() @@ -202,7 +203,8 @@ int dummy; jsondb = subprocess.check_output([ninja_exe, '-t', 'compdb', 'c_COMPILER', 'cpp_COMPILER'], cwd=builddir) except Exception: raise MesonException('Could not create compilation database.') - open(os.path.join(builddir, 'compile_commands.json'), 'wb').write(jsondb) + with open(os.path.join(builddir, 'compile_commands.json'), 'wb') as f: + f.write(jsondb) # Get all generated headers. Any source file might need them so # we need to add an order dependency to them. @@ -505,8 +507,8 @@ int dummy; self.generate_subdir_install(d) elem.write(outfile) - ofile = open(install_data_file, 'wb') - pickle.dump(d, ofile) + with open(install_data_file, 'wb') as ofile: + pickle.dump(d, ofile) def generate_target_install(self, d): should_strip = self.environment.coredata.get_builtin_option('strip') @@ -1416,16 +1418,22 @@ rule FORTRAN_DEP_HACK # but those are really rare. I hope. if not compiler.can_compile(s): continue - for line in open(os.path.join(self.environment.get_source_dir(), s.subdir, s.fname)): - modmatch = modre.match(line) - if modmatch is not None: - modname = modmatch.group(1) - if modname.lower() == 'procedure': # MODULE PROCEDURE construct - continue - if modname in module_files: - raise InvalidArguments('Namespace collision: module %s defined in two files %s and %s.' % - (modname, module_files[modname], s)) - module_files[modname] = s + filename = os.path.join(self.environment.get_source_dir(), + s.subdir, s.fname) + with open(filename) as f: + for line in f: + modmatch = modre.match(line) + if modmatch is not None: + modname = modmatch.group(1) + if modname.lower() == 'procedure': + # MODULE PROCEDURE construct + continue + if modname in module_files: + raise InvalidArguments( + 'Namespace collision: module %s defined in ' + 'two files %s and %s.' % + (modname, module_files[modname], s)) + module_files[modname] = s self.fortran_deps[target.get_basename()] = module_files def get_fortran_deps(self, compiler, src, target): @@ -1433,27 +1441,32 @@ rule FORTRAN_DEP_HACK usere = re.compile(r"\s*use\s+(\w+)", re.IGNORECASE) dirname = self.get_target_private_dir(target) tdeps= self.fortran_deps[target.get_basename()] - for line in open(src): - usematch = usere.match(line) - if usematch is not None: - usename = usematch.group(1) - if usename not in tdeps: - # The module is not provided by any source file. This is due to - # a) missing file/typo/etc - # b) using a module provided by the compiler, such as OpenMP - # There's no easy way to tell which is which (that I know of) - # so just ignore this and go on. Ideally we would print a - # warning message to the user but this is a common occurrance, - # which would lead to lots of distracting noise. - continue - mod_source_file = tdeps[usename] - # Check if a source uses a module it exports itself. - # Potential bug if multiple targets have a file with - # the same name. - if mod_source_file.fname == os.path.split(src)[1]: - continue - mod_name = compiler.module_name_to_filename(usematch.group(1)) - mod_files.append(os.path.join(dirname, mod_name)) + with open(src) as f: + for line in f: + usematch = usere.match(line) + if usematch is not None: + usename = usematch.group(1) + if usename not in tdeps: + # The module is not provided by any source file. This + # is due to: + # a) missing file/typo/etc + # b) using a module provided by the compiler, such as + # OpenMP + # There's no easy way to tell which is which (that I + # know of) so just ignore this and go on. Ideally we + # would print a warning message to the user but this is + # a common occurrence, which would lead to lots of + # distracting noise. + continue + mod_source_file = tdeps[usename] + # Check if a source uses a module it exports itself. + # Potential bug if multiple targets have a file with + # the same name. + if mod_source_file.fname == os.path.split(src)[1]: + continue + mod_name = compiler.module_name_to_filename( + usematch.group(1)) + mod_files.append(os.path.join(dirname, mod_name)) return mod_files def get_cross_stdlib_args(self, target, compiler): |