aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xenvironment.py9
-rwxr-xr-xinterpreter.py22
-rwxr-xr-xshellgenerator.py58
-rw-r--r--test cases/13 pch/builder.txt4
-rw-r--r--test cases/13 pch/pch/prog.h1
-rw-r--r--test cases/13 pch/prog.c7
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;
+}