diff --git a/backends.py b/backends.py index 94f1987c4..f45c4727f 100755 --- a/backends.py +++ b/backends.py @@ -14,11 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os, sys, stat, re, pickle +import os, sys, re, pickle import interpreter, nodes import environment from meson_install import InstallData -from interpreter import InvalidArguments if environment.is_windows(): quote_char = '"' @@ -27,9 +26,6 @@ else: quote_char = "'" execute_wrapper = '' -def shell_quote(cmdlist): - return ["'" + x + "'" for x in cmdlist] - def ninja_quote(text): return text.replace(' ', '$ ') @@ -88,7 +84,12 @@ def do_conf_file(src, dst, variables): pass os.replace(dst_tmp, dst) - +# It may seem a bit silly that this Backend class exists on its own +# rather than being a part of NinjaBackend, which is the only class +# that uses Backend. The point is that common functionality +# that will be used in XCode, Visual Studio etc will be in +# this one. Once work on that code starts the exact division +# of labor between the classes is determined. class Backend(): def __init__(self, build, interp): self.build = build @@ -650,246 +651,3 @@ class NinjaBackend(Backend): elem = NinjaBuildElement(deps, 'phony', '') elem.write(outfile) - -class ShellBackend(Backend): - def __init__(self, build, interp): - Backend.__init__(self, build, interp) - self.build_filename = 'compile.sh' - self.test_filename = 'run_tests.sh' - self.install_filename = 'install.sh' - - def generate(self): - self.generate_compile_script() - self.generate_test_script() - self.generate_install_script() - - def create_shfile(self, outfilename, message): - outfile = open(outfilename, 'w') - outfile.write('#!/bin/sh\n\n') - outfile.write(message) - cdcmd = ['cd', self.environment.get_build_dir()] - outfile.write(' '.join(shell_quote(cdcmd)) + '\n') - os.chmod(outfilename, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC |\ - stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH) - return outfile - - def generate_compile_script(self): - outfilename = os.path.join(self.environment.get_build_dir(), self.build_filename) - message = """echo This is an autogenerated shell script build file for project \\"%s\\" -echo This is experimental and most likely will not work! -""" % self.build.get_project() - outfile = self.create_shfile(outfilename, message) - self.generate_commands(outfile) - outfile.close() - - def generate_test_script(self): - outfilename = os.path.join(self.environment.get_build_dir(), self.test_filename) - message = """echo This is an autogenerated test script for project \\"%s\\" -echo This is experimental and most likely will not work! -echo Run compile.sh before this or bad things will happen. -""" % self.build.get_project() - outfile = self.create_shfile(outfilename, message) - self.generate_tests(outfile) - outfile.close() - - def generate_install_script(self): - outfilename = os.path.join(self.environment.get_build_dir(), self.install_filename) - message = """echo This is an autogenerated install script for project \\"%s\\" -echo This is experimental and most likely will not work! -echo Run compile.sh before this or bad things will happen. -""" % self.build.get_project() - outfile = self.create_shfile(outfilename, message) - self.generate_configure_files() - self.generate_target_install(outfile) - self.generate_header_install(outfile) - self.generate_man_install(outfile) - self.generate_data_install(outfile) - outfile.close() - - def make_subdir(self, outfile, sdir): - cmdlist = ['mkdir', '-p', sdir] - outfile.write(' '.join(shell_quote(cmdlist)) + ' || exit\n') - - def copy_file(self, outfile, filename, outdir): - cpcommand = ['cp', filename, outdir] - cpcommand = ' '.join(shell_quote(cpcommand)) + ' || exit\n' - outfile.write(cpcommand) - - def generate_data_install(self, outfile): - prefix = self.environment.get_prefix() - dataroot = os.path.join(prefix, self.environment.get_datadir()) - data = self.build.get_data() - if len(data) != 0: - outfile.write('\necho Installing data files.\n') - else: - outfile.write('\necho This project has no data files to install.\n') - for d in data: - subdir = os.path.join(dataroot, d.get_subdir()) - absdir = os.path.join(self.environment.get_prefix(), subdir) - for f in d.get_sources(): - self.make_subdir(outfile, absdir) - srcabs = os.path.join(self.environment.get_source_dir(), f) - dstabs = os.path.join(absdir, f) - self.copy_file(outfile, srcabs, dstabs) - - def generate_man_install(self, outfile): - prefix = self.environment.get_prefix() - manroot = os.path.join(prefix, self.environment.get_mandir()) - man = self.build.get_man() - if len(man) != 0: - outfile.write('\necho Installing man pages.\n') - else: - outfile.write('\necho This project has no man pages to install.\n') - for m in man: - for f in m.get_sources(): - num = f.split('.')[-1] - subdir = 'man' + num - absdir = os.path.join(manroot, subdir) - self.make_subdir(outfile, absdir) - srcabs = os.path.join(self.environment.get_source_dir(), f) - dstabs = os.path.join(manroot, - os.path.join(subdir, f + '.gz')) - cmd = "gzip < '%s' > '%s' || exit\n" % (srcabs, dstabs) - outfile.write(cmd) - - def generate_header_install(self, outfile): - prefix = self.environment.get_prefix() - incroot = os.path.join(prefix, self.environment.get_includedir()) - headers = self.build.get_headers() - if len(headers) != 0: - outfile.write('\necho Installing headers.\n') - else: - outfile.write('\necho This project has no headers to install.\n') - for h in headers: - outdir = os.path.join(incroot, h.get_subdir()) - self.make_subdir(outfile, outdir) - for f in h.get_sources(): - abspath = os.path.join(self.environment.get_source_dir(), f) # FIXME - self.copy_file(outfile, abspath, outdir) - - def generate_target_install(self, outfile): - prefix = self.environment.get_prefix() - libdir = os.path.join(prefix, self.environment.get_libdir()) - bindir = os.path.join(prefix, self.environment.get_bindir()) - self.make_subdir(outfile, libdir) - self.make_subdir(outfile, bindir) - if len(self.build.get_targets()) != 0: - outfile.write('\necho Installing targets.\n') - else: - outfile.write('\necho This project has no targets to install.\n') - for tmp in self.build.get_targets().items(): - (name, t) = tmp - if t.should_install(): - if isinstance(t, interpreter.Executable): - outdir = bindir - else: - outdir = libdir - outfile.write('echo Installing "%s".\n' % name) - self.copy_file(outfile, self.get_target_filename(t), outdir) - self.generate_shlib_aliases(t, outdir, outfile) - self.fix_deps(outfile, t, outdir) - - def fix_deps(self, outfile, target, outdir): - if isinstance(target, interpreter.StaticLibrary): - return - depfixer = self.environment.get_depfixer() - fname = os.path.join(outdir, target.get_filename()) - cmds = [depfixer, fname, './'] - outfile.write(' '.join(shell_quote(cmds)) + ' || exit\n') - - def generate_tests(self, outfile): - for t in self.build.get_tests(): - cmds = [] - cmds.append(self.get_target_filename(t.get_exe())) - outfile.write('echo Running test \\"%s\\".\n' % t.get_name()) - outfile.write(' '.join(shell_quote(cmds)) + ' || exit\n') - - - def generate_single_compile(self, target, outfile, src): - compiler = self.get_compiler_for_source(src) - commands = [] - commands += compiler.get_exelist() - commands += self.generate_basic_compiler_flags(target, compiler) - commands += compiler.get_compile_only_flags() - abs_src = os.path.join(self.environment.get_source_dir(), target.get_source_subdir(), src) - abs_obj = os.path.join(self.get_target_private_dir(target), src) - abs_obj += '.' + self.environment.get_object_suffix() - for i in target.get_include_dirs(): - basedir = i.get_curdir() - for d in i.get_incdirs(): - expdir = os.path.join(basedir, d) - fulldir = os.path.join(self.environment.get_source_dir(), expdir) - barg = compiler.get_include_arg(expdir) - sarg = compiler.get_include_arg(fulldir) - commands.append(barg) - commands.append(sarg) - commands += self.get_pch_include_args(compiler, target) - commands.append(abs_src) - commands += compiler.get_output_flags() - commands.append(abs_obj) - quoted = shell_quote(commands) - outfile.write('\necho Compiling \\"%s\\"\n' % src) - outfile.write(' '.join(quoted) + ' || exit\n') - return abs_obj - - def generate_link(self, target, outfile, outname, obj_list): - if isinstance(target, interpreter.StaticLibrary): - linker = self.build.static_linker - else: - linker = self.build.compilers[0] # Fixme. - commands = [] - commands += linker.get_exelist() - if isinstance(target, interpreter.StaticLibrary): - commands += linker.get_std_link_flags() - commands += linker.get_output_flags() - commands.append(outname) - commands += obj_list - if isinstance(target, interpreter.Executable): - commands += linker.get_std_exe_link_flags() - elif isinstance(target, interpreter.SharedLibrary): - commands += linker.get_std_shared_lib_link_flags() - commands += linker.get_pic_flags() - elif isinstance(target, interpreter.StaticLibrary): - pass - else: - raise RuntimeError('Unknown build target type.') - for dep in target.get_external_deps(): - commands += dep.get_link_flags() - commands += self.build_target_link_arguments(target.get_dependencies()) - quoted = shell_quote(commands) - outfile.write('\necho Linking \\"%s\\".\n' % target.get_basename()) - outfile.write(' '.join(quoted) + ' || exit\n') - - def generate_commands(self, outfile): - for i in self.build.get_targets().items(): - target = i[1] - self.generate_target(target, outfile) - - - def generate_pch(self, target, outfile): - print('Generating pch for "%s"' % target.get_basename()) - for pch in target.get_pch(): - if '/' not in pch: - raise interpreter.InvalidArguments('Precompiled header of "%s" must not be in the same direcotory as source, please put it in a subdirectory.' % target.get_basename()) - compiler = self.get_compiler_for_source(pch) - commands = [] - commands += compiler.get_exelist() - commands += self.generate_basic_compiler_flags(target, compiler) - srcabs = os.path.join(self.environment.get_source_dir(), target.get_source_subdir(), pch) - dstabs = os.path.join(self.environment.get_build_dir(), - self.get_target_private_dir(target), - os.path.split(pch)[-1] + '.' + compiler.get_pch_suffix()) - commands.append(srcabs) - commands += compiler.get_output_flags() - commands.append(dstabs) - quoted = shell_quote(commands) - outfile.write('\necho Generating pch \\"%s\\".\n' % pch) - outfile.write(' '.join(quoted) + ' || exit\n') - - def generate_shlib_aliases(self, target, outdir, outfile): - basename = target.get_filename() - aliases = target.get_aliaslist() - for alias in aliases: - aliasfile = os.path.join(outdir, alias) - cmd = ['ln', '-s', '-f', basename, aliasfile] - outfile.write(' '.join(shell_quote(cmd)) + '|| exit\n') diff --git a/meson.py b/meson.py index 828796ba7..9aebc1f8f 100755 --- a/meson.py +++ b/meson.py @@ -97,12 +97,10 @@ class MesonApp(): b = build.Build(env) intr = interpreter.Interpreter(b) intr.run() - if options.backend == 'shell': - g = backends.ShellBackend(b, intr) - elif options.backend == 'ninja': + if options.backend == 'ninja': g = backends.NinjaBackend(b, intr) else: - raise RuntimeError('Unknown generator "%s".' % options.generator) + raise RuntimeError('Unknown backend "%s".' % options.backend) g.generate() env.generating_finished() diff --git a/run_tests.py b/run_tests.py index c7a730987..5ab0713cc 100755 --- a/run_tests.py +++ b/run_tests.py @@ -20,14 +20,8 @@ import environment test_build_dir = 'work area' install_dir = os.path.join(os.path.split(os.path.abspath(__file__))[0], 'install dir') -use_shell = len(sys.argv) > 1 meson_command = './meson.py' -if use_shell: - backend_flags = ['--backend', 'shell'] - compile_commands = ['compile.sh'] - test_commands = ['run_tests.sh'] - install_commands = ['install.sh'] -else: +if True: # Currently we have only one backend. backend_flags = [] compile_commands = ['ninja'] test_commands = ['ninja', 'test']