aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/backend/ninjabackend.py
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/backend/ninjabackend.py')
-rw-r--r--mesonbuild/backend/ninjabackend.py141
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):