aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2019-02-09 00:31:00 +0200
committerGitHub <noreply@github.com>2019-02-09 00:31:00 +0200
commit711f73e3862e6d1ef96b5c5c6e8d27231c9eca9c (patch)
treef01a3de0e77d0825dd236857cde8124ac461dd1c
parentbb3997a39c5ca88590db86c1918c2c8b7c7ba97e (diff)
parent3cbc7c7bd97a57419f2344edc919dbb2b2ef7d55 (diff)
downloadmeson-711f73e3862e6d1ef96b5c5c6e8d27231c9eca9c.zip
meson-711f73e3862e6d1ef96b5c5c6e8d27231c9eca9c.tar.gz
meson-711f73e3862e6d1ef96b5c5c6e8d27231c9eca9c.tar.bz2
Merge pull request #4860 from nioncode/fixPch
Fix missing PCH dependencies
-rw-r--r--mesonbuild/backend/ninjabackend.py39
-rw-r--r--test cases/common/13 pch/generated/gen_custom.py5
-rw-r--r--test cases/common/13 pch/generated/gen_generator.py7
-rw-r--r--test cases/common/13 pch/generated/generated_generator.in1
-rw-r--r--test cases/common/13 pch/generated/meson.build16
-rw-r--r--test cases/common/13 pch/generated/pch/prog.h2
-rw-r--r--test cases/common/13 pch/generated/pch/prog_pch.c5
-rw-r--r--test cases/common/13 pch/generated/prog.c6
-rw-r--r--test cases/common/13 pch/meson.build2
-rw-r--r--test cases/common/13 pch/withIncludeDirectories/include/lib/lib.h1
-rw-r--r--test cases/common/13 pch/withIncludeDirectories/meson.build9
-rw-r--r--test cases/common/13 pch/withIncludeDirectories/pch/prog.h1
-rw-r--r--test cases/common/13 pch/withIncludeDirectories/pch/prog_pch.c5
-rw-r--r--test cases/common/13 pch/withIncludeDirectories/prog.c10
14 files changed, 96 insertions, 13 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 463e999..66d42b0 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -428,12 +428,7 @@ int dummy;
# Generate rules for building the remaining source files in this target
outname = self.get_target_filename(target)
obj_list = []
- use_pch = self.environment.coredata.base_options.get('b_pch', False)
is_unity = self.is_unity(target)
- if use_pch and target.has_pch():
- pch_objects = self.generate_pch(target, outfile)
- else:
- pch_objects = []
header_deps = []
unity_src = []
unity_deps = [] # Generated sources that must be built before compiling a Unity target.
@@ -486,6 +481,12 @@ int dummy;
header_deps=header_deps)
obj_list.append(o)
+ use_pch = self.environment.coredata.base_options.get('b_pch', False)
+ if use_pch and target.has_pch():
+ pch_objects = self.generate_pch(target, outfile, header_deps=header_deps)
+ else:
+ pch_objects = []
+
# Generate compilation targets for C sources generated from Vala
# sources. This can be extended to other $LANG->C compilers later if
# necessary. This needs to be separate for at least Vala
@@ -2208,12 +2209,7 @@ rule FORTRAN_DEP_HACK%s
commands += compiler.get_module_outdir_args(self.get_target_private_dir(target))
element = NinjaBuildElement(self.all_outputs, rel_obj, compiler_name, rel_src)
- for d in header_deps:
- if isinstance(d, File):
- d = d.rel_to_builddir(self.build_to_src)
- elif not self.has_dir_part(d):
- d = os.path.join(self.get_target_private_dir(target), d)
- element.add_dep(d)
+ self.add_header_deps(target, element, header_deps)
for d in extra_deps:
element.add_dep(d)
for d in order_deps:
@@ -2222,7 +2218,14 @@ rule FORTRAN_DEP_HACK%s
elif not self.has_dir_part(d):
d = os.path.join(self.get_target_private_dir(target), d)
element.add_orderdep(d)
- element.add_orderdep(pch_dep)
+ if compiler.id == 'msvc':
+ # MSVC does not show includes coming from the PCH with '/showIncludes',
+ # thus we must add an implicit dependency to the generated PCH.
+ element.add_dep(pch_dep)
+ else:
+ # All other compilers properly handle includes through the PCH, so only an
+ # orderdep is needed to make the initial build without depfile work.
+ element.add_orderdep(pch_dep)
# Convert from GCC-style link argument naming to the naming used by the
# current compiler.
commands = commands.to_native()
@@ -2233,6 +2236,14 @@ rule FORTRAN_DEP_HACK%s
element.write(outfile)
return rel_obj
+ def add_header_deps(self, target, ninja_element, header_deps):
+ for d in header_deps:
+ if isinstance(d, File):
+ d = d.rel_to_builddir(self.build_to_src)
+ elif not self.has_dir_part(d):
+ d = os.path.join(self.get_target_private_dir(target), d)
+ ninja_element.add_dep(d)
+
def has_dir_part(self, fname):
# FIXME FIXME: The usage of this is a terrible and unreliable hack
if isinstance(fname, File):
@@ -2263,6 +2274,7 @@ rule FORTRAN_DEP_HACK%s
just_name = os.path.basename(header)
(objname, pch_args) = compiler.gen_pch_args(just_name, source, dst)
commands += pch_args
+ commands += self._generate_single_compile(target, compiler)
commands += self.get_compile_debugfile_args(compiler, target, objname)
dep = dst + '.' + compiler.get_depfile_suffix()
return commands, dep, dst, [objname]
@@ -2278,7 +2290,7 @@ rule FORTRAN_DEP_HACK%s
dep = dst + '.' + compiler.get_depfile_suffix()
return commands, dep, dst, [] # Gcc does not create an object file during pch generation.
- def generate_pch(self, target, outfile):
+ def generate_pch(self, target, outfile, header_deps=[]):
cstr = ''
pch_objects = []
if target.is_cross:
@@ -2309,6 +2321,7 @@ rule FORTRAN_DEP_HACK%s
elem = NinjaBuildElement(self.all_outputs, dst, rulename, src)
if extradep is not None:
elem.add_dep(extradep)
+ self.add_header_deps(target, elem, header_deps)
elem.add_item('ARGS', commands)
elem.add_item('DEPFILE', dep)
elem.write(outfile)
diff --git a/test cases/common/13 pch/generated/gen_custom.py b/test cases/common/13 pch/generated/gen_custom.py
new file mode 100644
index 0000000..650e03c
--- /dev/null
+++ b/test cases/common/13 pch/generated/gen_custom.py
@@ -0,0 +1,5 @@
+#!/usr/bin/env python3
+import sys
+
+with open(sys.argv[1], 'w') as f:
+ f.write("#define FOO 0")
diff --git a/test cases/common/13 pch/generated/gen_generator.py b/test cases/common/13 pch/generated/gen_generator.py
new file mode 100644
index 0000000..a245e7a
--- /dev/null
+++ b/test cases/common/13 pch/generated/gen_generator.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python3
+import sys
+
+with open(sys.argv[1]) as f:
+ content = f.read()
+with open(sys.argv[2], 'w') as f:
+ f.write(content)
diff --git a/test cases/common/13 pch/generated/generated_generator.in b/test cases/common/13 pch/generated/generated_generator.in
new file mode 100644
index 0000000..1a00ebd
--- /dev/null
+++ b/test cases/common/13 pch/generated/generated_generator.in
@@ -0,0 +1 @@
+#define BAR 0
diff --git a/test cases/common/13 pch/generated/meson.build b/test cases/common/13 pch/generated/meson.build
new file mode 100644
index 0000000..372a00e
--- /dev/null
+++ b/test cases/common/13 pch/generated/meson.build
@@ -0,0 +1,16 @@
+cc = meson.get_compiler('c')
+cc_id = cc.get_id()
+if cc_id == 'lcc'
+ error('MESON_SKIP_TEST: Elbrus compiler does not support PCH.')
+endif
+
+generated_customTarget = custom_target('makeheader',
+ output: 'generated_customTarget.h',
+ command : [find_program('gen_custom.py'), '@OUTPUT0@'])
+
+generated_generator = generator(find_program('gen_generator.py'),
+ output: '@BASENAME@.h',
+ arguments: ['@INPUT@', '@OUTPUT@'])
+
+exe = executable('prog', 'prog.c', generated_customTarget, generated_generator.process('generated_generator.in'),
+ c_pch: ['pch/prog_pch.c', 'pch/prog.h'])
diff --git a/test cases/common/13 pch/generated/pch/prog.h b/test cases/common/13 pch/generated/pch/prog.h
new file mode 100644
index 0000000..15fec38
--- /dev/null
+++ b/test cases/common/13 pch/generated/pch/prog.h
@@ -0,0 +1,2 @@
+#include "generated_customTarget.h"
+#include "generated_generator.h"
diff --git a/test cases/common/13 pch/generated/pch/prog_pch.c b/test cases/common/13 pch/generated/pch/prog_pch.c
new file mode 100644
index 0000000..4960505
--- /dev/null
+++ b/test cases/common/13 pch/generated/pch/prog_pch.c
@@ -0,0 +1,5 @@
+#if !defined(_MSC_VER)
+#error "This file is only for use with MSVC."
+#endif
+
+#include "prog.h"
diff --git a/test cases/common/13 pch/generated/prog.c b/test cases/common/13 pch/generated/prog.c
new file mode 100644
index 0000000..9b2e2ef
--- /dev/null
+++ b/test cases/common/13 pch/generated/prog.c
@@ -0,0 +1,6 @@
+// No includes here, they need to come from the PCH
+
+int main(int argc, char **argv) {
+ return FOO + BAR;
+}
+
diff --git a/test cases/common/13 pch/meson.build b/test cases/common/13 pch/meson.build
index d39527b..43129c9 100644
--- a/test cases/common/13 pch/meson.build
+++ b/test cases/common/13 pch/meson.build
@@ -2,6 +2,8 @@ project('pch test', 'c', 'cpp')
subdir('c')
subdir('cpp')
+subdir('generated')
+subdir('withIncludeDirectories')
if meson.backend() == 'xcode'
warning('Xcode backend only supports one precompiled header per target. Skipping "mixed" which has various precompiled headers.')
diff --git a/test cases/common/13 pch/withIncludeDirectories/include/lib/lib.h b/test cases/common/13 pch/withIncludeDirectories/include/lib/lib.h
new file mode 100644
index 0000000..53c5fdf
--- /dev/null
+++ b/test cases/common/13 pch/withIncludeDirectories/include/lib/lib.h
@@ -0,0 +1 @@
+#include <stdio.h>
diff --git a/test cases/common/13 pch/withIncludeDirectories/meson.build b/test cases/common/13 pch/withIncludeDirectories/meson.build
new file mode 100644
index 0000000..2ab2cd8
--- /dev/null
+++ b/test cases/common/13 pch/withIncludeDirectories/meson.build
@@ -0,0 +1,9 @@
+cc = meson.get_compiler('c')
+cc_id = cc.get_id()
+if cc_id == 'lcc'
+ error('MESON_SKIP_TEST: Elbrus compiler does not support PCH.')
+endif
+
+exe = executable('prog', 'prog.c',
+ include_directories: 'include',
+ c_pch : ['pch/prog_pch.c', 'pch/prog.h'])
diff --git a/test cases/common/13 pch/withIncludeDirectories/pch/prog.h b/test cases/common/13 pch/withIncludeDirectories/pch/prog.h
new file mode 100644
index 0000000..383b2c5
--- /dev/null
+++ b/test cases/common/13 pch/withIncludeDirectories/pch/prog.h
@@ -0,0 +1 @@
+#include<lib/lib.h>
diff --git a/test cases/common/13 pch/withIncludeDirectories/pch/prog_pch.c b/test cases/common/13 pch/withIncludeDirectories/pch/prog_pch.c
new file mode 100644
index 0000000..4960505
--- /dev/null
+++ b/test cases/common/13 pch/withIncludeDirectories/pch/prog_pch.c
@@ -0,0 +1,5 @@
+#if !defined(_MSC_VER)
+#error "This file is only for use with MSVC."
+#endif
+
+#include "prog.h"
diff --git a/test cases/common/13 pch/withIncludeDirectories/prog.c b/test cases/common/13 pch/withIncludeDirectories/prog.c
new file mode 100644
index 0000000..0ce3d0a
--- /dev/null
+++ b/test cases/common/13 pch/withIncludeDirectories/prog.c
@@ -0,0 +1,10 @@
+// No includes here, they need to come from the PCH
+
+void func() {
+ fprintf(stdout, "This is a function that fails if stdio is not #included.\n");
+}
+
+int main(int argc, char **argv) {
+ return 0;
+}
+