diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2013-01-13 20:50:16 +0200 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2013-01-13 20:50:16 +0200 |
commit | 3e9416fc4ae7f37f3a4f07c8402a95705fa176ad (patch) | |
tree | e876bb37d9f25f07688b50240701ee0499b94023 | |
parent | 57015296328a4fe5c8bad5410a3b4ba67637fbb6 (diff) | |
download | meson-3e9416fc4ae7f37f3a4f07c8402a95705fa176ad.zip meson-3e9416fc4ae7f37f3a4f07c8402a95705fa176ad.tar.gz meson-3e9416fc4ae7f37f3a4f07c8402a95705fa176ad.tar.bz2 |
Added support for precompiled headers.
-rwxr-xr-x | environment.py | 9 | ||||
-rwxr-xr-x | interpreter.py | 22 | ||||
-rwxr-xr-x | shellgenerator.py | 58 | ||||
-rw-r--r-- | test cases/13 pch/builder.txt | 4 | ||||
-rw-r--r-- | test cases/13 pch/pch/prog.h | 1 | ||||
-rw-r--r-- | test cases/13 pch/prog.c | 7 |
6 files changed, 87 insertions, 14 deletions
diff --git a/environment.py b/environment.py index 377bbf9..49c3a3e 100755 --- a/environment.py +++ b/environment.py @@ -45,6 +45,9 @@ class CCompiler(): def get_std_exe_link_flags(self): return [] + + def get_include_arg(self, path): + return '-I' + path def get_std_shared_lib_link_flags(self): return ['-shared'] @@ -115,6 +118,9 @@ class GnuCCompiler(CCompiler): def get_std_opt_flags(self): return GnuCCompiler.std_opt_flags + def get_pch_suffix(self): + return 'gch' + class GnuCXXCompiler(CXXCompiler): std_warn_flags = ['-Wall', '-Winvalid-pch'] std_opt_flags = ['-O2'] @@ -128,6 +134,9 @@ class GnuCXXCompiler(CXXCompiler): def get_std_opt_flags(self): return GnuCXXCompiler.std_opt_flags + def get_pch_suffix(self): + return 'gch' + class ArLinker(): std_flags = ['cr'] diff --git a/interpreter.py b/interpreter.py index 293db9e..3e1a066 100755 --- a/interpreter.py +++ b/interpreter.py @@ -95,10 +95,13 @@ class BuildTarget(InterpreterObject): self.external_deps = [] self.methods.update({'add_dep': self.add_dep_method, 'link' : self.link_method, - 'install': self.install}) + 'install': self.install_method, + 'pch' : self.pch_method + }) self.link_targets = [] self.filename = 'no_name' self.need_install = False + self.pch = [] def get_filename(self): return self.filename @@ -118,11 +121,17 @@ class BuildTarget(InterpreterObject): def should_install(self): return self.need_install + def has_pch(self): + return len(self.pch) > 0 + + def get_pch(self): + return self.pch + def add_external_dep(self, dep): if not isinstance(dep, environment.PkgConfigDependency): raise InvalidArguments('Argument is not an external dependency') self.external_deps.append(dep) - + def get_external_deps(self): return self.external_deps @@ -136,10 +145,17 @@ class BuildTarget(InterpreterObject): raise InvalidArguments('Link target is not library.') self.link_targets.append(target) - def install(self, args): + def install_method(self, args): if len(args) != 0: raise InvalidArguments('Install() takes no arguments.') self.need_install = True + + def pch_method(self, args): + if len(args) == 0: + raise InvalidArguments('Pch requires arguments.') + for a in args: + self.pch.append(a) + class Executable(BuildTarget): def __init__(self, name, subdir, sources, environment): diff --git a/shellgenerator.py b/shellgenerator.py index 73574b4..7052be0 100755 --- a/shellgenerator.py +++ b/shellgenerator.py @@ -95,7 +95,7 @@ echo Run compile.sh before this or bad things will happen. else: outfile.write('\necho This project has no data files to install.\n') for d in data: - subdir = os.path.join(self.environment.get_datadir(), d.get_subdir()) + 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) @@ -165,18 +165,13 @@ echo Run compile.sh before this or bad things will happen. 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 = None + def get_compiler_for_source(self, src): for i in self.build.compilers: if i.can_compile(src): - compiler = i - break - if compiler is None: - raise RuntimeError('No specified compiler can handle file ' + src) - abs_src = os.path.join(self.environment.get_source_dir(), target.get_source_subdir(), src) - print(target.get_source_subdir()) - abs_obj = os.path.join(self.get_target_dir(target), src) - abs_obj += '.' + self.environment.get_object_suffix() + return i + raise RuntimeError('No specified compiler can handle file ' + src) + + def generate_basic_compiler_arguments(self, target, compiler): commands = [] commands += compiler.get_exelist() commands += compiler.get_debug_flags() @@ -186,6 +181,27 @@ echo Run compile.sh before this or bad things will happen. commands += compiler.get_pic_flags() for dep in target.get_external_deps(): commands += dep.get_compile_flags() + return commands + + def get_pch_include_args(self, compiler, target): + args = [] + pchpath = self.get_target_dir(target) + includearg = compiler.get_include_arg(pchpath) + for p in target.get_pch(): + if compiler.can_compile(p): + args.append('-include') + args.append(os.path.split(p)[-1]) + if len(args) > 0: + args = [includearg] + args + return args + + def generate_single_compile(self, target, outfile, src): + compiler = self.get_compiler_for_source(src) + commands = self.generate_basic_compiler_arguments(target, compiler) + abs_src = os.path.join(self.environment.get_source_dir(), target.get_source_subdir(), src) + abs_obj = os.path.join(self.get_target_dir(target), src) + abs_obj += '.' + self.environment.get_object_suffix() + commands += self.get_pch_include_args(compiler, target) commands.append(abs_src) commands += compiler.get_output_flags() commands.append(abs_obj) @@ -250,6 +266,24 @@ echo Run compile.sh before this or bad things will happen. filename = os.path.join(targetdir, target.get_filename()) return filename + 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 = self.generate_basic_compiler_arguments(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_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_target(self, target, outfile): name = target.get_basename() if name in self.processed_targets: @@ -258,6 +292,8 @@ echo Run compile.sh before this or bad things will happen. print('Generating target', name) outname = self.get_target_filename(target) obj_list = [] + if target.has_pch(): + self.generate_pch(target, outfile) for src in target.get_sources(): obj_list.append(self.generate_single_compile(target, outfile, src)) self.generate_link(target, outfile, outname, obj_list) diff --git a/test cases/13 pch/builder.txt b/test cases/13 pch/builder.txt new file mode 100644 index 0000000..a95aafb --- /dev/null +++ b/test cases/13 pch/builder.txt @@ -0,0 +1,4 @@ +project('pch test', 'c') + +exe = executable('prog', 'prog.c') +exe.pch('pch/prog.h') diff --git a/test cases/13 pch/pch/prog.h b/test cases/13 pch/pch/prog.h new file mode 100644 index 0000000..354499a --- /dev/null +++ b/test cases/13 pch/pch/prog.h @@ -0,0 +1 @@ +#include<stdio.h> diff --git a/test cases/13 pch/prog.c b/test cases/13 pch/prog.c new file mode 100644 index 0000000..995bb3f --- /dev/null +++ b/test cases/13 pch/prog.c @@ -0,0 +1,7 @@ +void func() { + fprintf(stdout, "This is a function that fails if stdio is not #included.\n"); +} + +int main(int argc, char **argv) { + return 0; +} |