Added support for precompiled headers.

pull/15/head
Jussi Pakkanen 12 years ago
parent 5701529632
commit 3e9416fc4a
  1. 9
      environment.py
  2. 22
      interpreter.py
  3. 58
      shellgenerator.py
  4. 4
      test cases/13 pch/builder.txt
  5. 1
      test cases/13 pch/pch/prog.h
  6. 7
      test cases/13 pch/prog.c

@ -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']

@ -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):

@ -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)

@ -0,0 +1,4 @@
project('pch test', 'c')
exe = executable('prog', 'prog.c')
exe.pch('pch/prog.h')

@ -0,0 +1 @@
#include<stdio.h>

@ -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;
}
Loading…
Cancel
Save