diff options
Diffstat (limited to 'mesonbuild')
-rw-r--r-- | mesonbuild/backend/backends.py | 17 | ||||
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 17 | ||||
-rw-r--r-- | mesonbuild/backend/vs2010backend.py | 27 | ||||
-rw-r--r-- | mesonbuild/build.py | 2 |
4 files changed, 49 insertions, 14 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 14b189b..5062767 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -515,6 +515,23 @@ class Backend: args += compiler.get_pch_use_args(pchpath, p[0]) return includeargs + args + def create_msvc_pch_implementation(self, target, lang, pch_header): + # We have to include the language in the file name, otherwise + # pch.c and pch.cpp will both end up as pch.obj in VS backends. + impl_name = 'meson_pch-%s.%s' % (lang, lang) + pch_rel_to_build = os.path.join(self.get_target_private_dir(target), impl_name) + # Make sure to prepend the build dir, since the working directory is + # not defined. Otherwise, we might create the file in the wrong path. + pch_file = os.path.join(self.build_dir, pch_rel_to_build) + os.makedirs(os.path.dirname(pch_file), exist_ok=True) + + content = '#include "%s"' % os.path.basename(pch_header) + pch_file_tmp = pch_file + '.tmp' + with open(pch_file_tmp, 'w') as f: + f.write(content) + mesonlib.replace_if_different(pch_file, pch_file_tmp) + return pch_rel_to_build + @staticmethod def escape_extra_args(compiler, args): # No extra escaping/quoting needed when not running on Windows diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 5958af8..1e0bb8b 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -2252,22 +2252,28 @@ rule FORTRAN_DEP_HACK%s return [os.path.join(self.get_target_dir(lt), lt.get_filename()) for lt in target.link_targets] def generate_msvc_pch_command(self, target, compiler, pch): - if len(pch) != 2: - raise MesonException('MSVC requires one header and one source to produce precompiled headers.') header = pch[0] - source = pch[1] pchname = compiler.get_pch_name(header) dst = os.path.join(self.get_target_private_dir(target), pchname) commands = [] commands += self.generate_basic_compiler_args(target, compiler) + + if len(pch) == 1: + # Auto generate PCH. + source = self.create_msvc_pch_implementation(target, compiler.get_language(), pch[0]) + pch_header_dir = os.path.dirname(os.path.join(self.build_to_src, target.get_source_subdir(), header)) + commands += compiler.get_include_args(pch_header_dir, False) + else: + source = os.path.join(self.build_to_src, target.get_source_subdir(), pch[1]) + 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] + return commands, dep, dst, [objname], source def generate_gcc_pch_command(self, target, compiler, pch): commands = self._generate_single_compile(target, compiler) @@ -2296,8 +2302,7 @@ rule FORTRAN_DEP_HACK%s raise InvalidArguments(msg) compiler = target.compilers[lang] if isinstance(compiler, VisualStudioCCompiler): - src = os.path.join(self.build_to_src, target.get_source_subdir(), pch[-1]) - (commands, dep, dst, objs) = self.generate_msvc_pch_command(target, compiler, pch) + (commands, dep, dst, objs, src) = self.generate_msvc_pch_command(target, compiler, pch) extradep = os.path.join(self.build_to_src, target.get_source_subdir(), pch[0]) elif compiler.id == 'intel': # Intel generates on target generation diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index 2a50dd2..dd99125 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import copy import os import pickle import xml.dom.minidom @@ -1035,13 +1036,18 @@ class Vs2010Backend(backends.Backend): continue pch_node.text = 'Use' if compiler.id == 'msvc': - if len(pch) != 2: - raise MesonException('MSVC requires one header and one source to produce precompiled headers.') - pch_sources[lang] = [pch[0], pch[1], lang] + if len(pch) == 1: + # Auto generate PCH. + src = os.path.join(down, self.create_msvc_pch_implementation(target, lang, pch[0])) + pch_header_dir = os.path.dirname(os.path.join(proj_to_src_dir, pch[0])) + else: + src = os.path.join(proj_to_src_dir, pch[1]) + pch_header_dir = None + pch_sources[lang] = [pch[0], src, lang, pch_header_dir] else: # I don't know whether its relevant but let's handle other compilers # used with a vs backend - pch_sources[lang] = [pch[0], None, lang] + pch_sources[lang] = [pch[0], None, lang, None] if len(pch_sources) == 1: # If there is only 1 language with precompiled headers, we can use it for the entire project, which # is cleaner than specifying it for each source file. @@ -1205,14 +1211,19 @@ class Vs2010Backend(backends.Backend): self.add_preprocessor_defines(lang, inc_cl, file_defines) self.add_include_dirs(lang, inc_cl, file_inc_dirs) for lang in pch_sources: - header, impl, suffix = pch_sources[lang] + impl = pch_sources[lang][1] if impl: - relpath = os.path.join(proj_to_src_dir, impl) - inc_cl = ET.SubElement(inc_src, 'CLCompile', Include=relpath) + inc_cl = ET.SubElement(inc_src, 'CLCompile', Include=impl) self.create_pch(pch_sources, lang, inc_cl) self.add_additional_options(lang, inc_cl, file_args) self.add_preprocessor_defines(lang, inc_cl, file_defines) - self.add_include_dirs(lang, inc_cl, file_inc_dirs) + pch_header_dir = pch_sources[lang][3] + if pch_header_dir: + inc_dirs = copy.deepcopy(file_inc_dirs) + inc_dirs[lang] = [pch_header_dir] + inc_dirs[lang] + else: + inc_dirs = file_inc_dirs + self.add_include_dirs(lang, inc_cl, inc_dirs) if self.has_objects(objects, additional_objects, gen_objs): inc_objs = ET.SubElement(root, 'ItemGroup') diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 2187d3e..9a1d158 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -1096,6 +1096,8 @@ You probably should put it in link_with instead.''') if (os.path.dirname(pchlist[0]) != os.path.dirname(pchlist[1])): raise InvalidArguments('PCH files must be stored in the same folder.') + + mlog.warning('PCH source files are deprecated, only a single header file should be used.') elif len(pchlist) > 2: raise InvalidArguments('PCH definition may have a maximum of 2 files.') for f in pchlist: |