use same compiler args for pch as for regular target

Fixes #999, #1415, #2361.
This commit is contained in:
Nicolas Schneider 2019-01-27 11:03:26 +01:00
parent da7b9df16c
commit 2044bc53b3
14 changed files with 88 additions and 12 deletions

View File

@ -428,12 +428,7 @@ int dummy;
# Generate rules for building the remaining source files in this target # Generate rules for building the remaining source files in this target
outname = self.get_target_filename(target) outname = self.get_target_filename(target)
obj_list = [] obj_list = []
use_pch = self.environment.coredata.base_options.get('b_pch', False)
is_unity = self.is_unity(target) 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 = [] header_deps = []
unity_src = [] unity_src = []
unity_deps = [] # Generated sources that must be built before compiling a Unity target. unity_deps = [] # Generated sources that must be built before compiling a Unity target.
@ -486,6 +481,12 @@ int dummy;
header_deps=header_deps) header_deps=header_deps)
obj_list.append(o) 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 # Generate compilation targets for C sources generated from Vala
# sources. This can be extended to other $LANG->C compilers later if # sources. This can be extended to other $LANG->C compilers later if
# necessary. This needs to be separate for at least Vala # necessary. This needs to be separate for at least Vala
@ -2181,12 +2182,7 @@ rule FORTRAN_DEP_HACK%s
commands += compiler.get_module_outdir_args(self.get_target_private_dir(target)) commands += compiler.get_module_outdir_args(self.get_target_private_dir(target))
element = NinjaBuildElement(self.all_outputs, rel_obj, compiler_name, rel_src) element = NinjaBuildElement(self.all_outputs, rel_obj, compiler_name, rel_src)
for d in header_deps: self.add_header_deps(target, element, 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)
for d in extra_deps: for d in extra_deps:
element.add_dep(d) element.add_dep(d)
for d in order_deps: for d in order_deps:
@ -2206,6 +2202,14 @@ rule FORTRAN_DEP_HACK%s
element.write(outfile) element.write(outfile)
return rel_obj 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): def has_dir_part(self, fname):
# FIXME FIXME: The usage of this is a terrible and unreliable hack # FIXME FIXME: The usage of this is a terrible and unreliable hack
if isinstance(fname, File): if isinstance(fname, File):
@ -2236,6 +2240,7 @@ rule FORTRAN_DEP_HACK%s
just_name = os.path.basename(header) just_name = os.path.basename(header)
(objname, pch_args) = compiler.gen_pch_args(just_name, source, dst) (objname, pch_args) = compiler.gen_pch_args(just_name, source, dst)
commands += pch_args commands += pch_args
commands += self._generate_single_compile(target, compiler)
commands += self.get_compile_debugfile_args(compiler, target, objname) commands += self.get_compile_debugfile_args(compiler, target, objname)
dep = dst + '.' + compiler.get_depfile_suffix() dep = dst + '.' + compiler.get_depfile_suffix()
return commands, dep, dst, [objname] return commands, dep, dst, [objname]
@ -2251,7 +2256,7 @@ rule FORTRAN_DEP_HACK%s
dep = dst + '.' + compiler.get_depfile_suffix() dep = dst + '.' + compiler.get_depfile_suffix()
return commands, dep, dst, [] # Gcc does not create an object file during pch generation. 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 = '' cstr = ''
pch_objects = [] pch_objects = []
if target.is_cross: if target.is_cross:
@ -2282,6 +2287,7 @@ rule FORTRAN_DEP_HACK%s
elem = NinjaBuildElement(self.all_outputs, dst, rulename, src) elem = NinjaBuildElement(self.all_outputs, dst, rulename, src)
if extradep is not None: if extradep is not None:
elem.add_dep(extradep) elem.add_dep(extradep)
self.add_header_deps(target, elem, header_deps)
elem.add_item('ARGS', commands) elem.add_item('ARGS', commands)
elem.add_item('DEPFILE', dep) elem.add_item('DEPFILE', dep)
elem.write(outfile) elem.write(outfile)

View File

@ -0,0 +1,5 @@
#!/usr/bin/env python3
import sys
with open(sys.argv[1], 'w') as f:
f.write("#define FOO 0")

View File

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

View File

@ -0,0 +1 @@
#define BAR 0

View File

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

View File

@ -0,0 +1,2 @@
#include "generated_customTarget.h"
#include "generated_generator.h"

View File

@ -0,0 +1,5 @@
#if !defined(_MSC_VER)
#error "This file is only for use with MSVC."
#endif
#include "prog.h"

View File

@ -0,0 +1,6 @@
// No includes here, they need to come from the PCH
int main(int argc, char **argv) {
return FOO + BAR;
}

View File

@ -2,6 +2,8 @@ project('pch test', 'c', 'cpp')
subdir('c') subdir('c')
subdir('cpp') subdir('cpp')
subdir('generated')
subdir('withIncludeDirectories')
if meson.backend() == 'xcode' if meson.backend() == 'xcode'
warning('Xcode backend only supports one precompiled header per target. Skipping "mixed" which has various precompiled headers.') warning('Xcode backend only supports one precompiled header per target. Skipping "mixed" which has various precompiled headers.')

View File

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

View File

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

View File

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

View File

@ -0,0 +1,5 @@
#if !defined(_MSC_VER)
#error "This file is only for use with MSVC."
#endif
#include "prog.h"

View File

@ -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;
}