Added support for precompiled headers.
This commit is contained in:
parent
5701529632
commit
3e9416fc4a
|
@ -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…
Reference in New Issue