diff options
author | Nicolas Schneider <nioncode+git@gmail.com> | 2016-03-12 02:02:36 +0100 |
---|---|---|
committer | Nicolas Schneider <nioncode+git@gmail.com> | 2016-03-12 02:02:36 +0100 |
commit | 49418cfe8ab1f42fa28ca9f408f60050bf56c5dc (patch) | |
tree | 759e245ac71403190805dd7a5241f5923cab8b03 | |
parent | 5ba7680a0d5c275efe57ec531635caf2db3a0237 (diff) | |
download | meson-49418cfe8ab1f42fa28ca9f408f60050bf56c5dc.zip meson-49418cfe8ab1f42fa28ca9f408f60050bf56c5dc.tar.gz meson-49418cfe8ab1f42fa28ca9f408f60050bf56c5dc.tar.bz2 |
vs2010: support multiple precompiled headers (one per language)
This creates the PrecompiledHeader properties for every source file in the
project if multiple languages are present. Otherwise, the global pch
settings are used.
The pch to use is determined by checking the suffix of the source file.
-rw-r--r-- | mesonbuild/backend/vs2010backend.py | 62 |
1 files changed, 49 insertions, 13 deletions
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index 7a427f0..217bb69 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -14,6 +14,8 @@ import os, sys import pickle + +from mesonbuild import compilers from . import backends from .. import build from .. import dependencies @@ -312,6 +314,24 @@ class Vs2010Backend(backends.Backend): tree = ET.ElementTree(root) tree.write(ofname, encoding='utf-8', xml_declaration=True) + def add_pch(self, inc_cl, proj_to_src_dir, pch_sources, source_file): + if len(pch_sources) <= 1: + # We only need per file precompiled headers if we have more than 1 language. + return + if source_file.split('.')[-1] in compilers.c_suffixes: + lang = 'c' + elif source_file.split('.')[-1] in compilers.cpp_suffixes: + lang = 'cpp' + else: + return + header = os.path.join(proj_to_src_dir, pch_sources[lang][0]) + pch_file = ET.SubElement(inc_cl, 'PrecompiledHeaderFile') + pch_file.text = header + pch_include = ET.SubElement(inc_cl, 'ForcedIncludeFiles') + pch_include.text = header + ';%(ForcedIncludeFiles)' + pch_out = ET.SubElement(inc_cl, 'PrecompiledHeaderOutputFile') + pch_out.text = '$(IntDir)$(TargetName)-%s.pch' % lang + def gen_vcxproj(self, target, ofname, guid, compiler): mlog.debug('Generating vcxproj %s.' % target.name) entrypoint = 'WinMainCRTStartup' @@ -427,19 +447,25 @@ class Vs2010Backend(backends.Backend): funclink = ET.SubElement(clconf, 'FunctionLevelLinking') funclink.text = 'true' pch_node = ET.SubElement(clconf, 'PrecompiledHeader') - pch_sources = [] + pch_sources = {} for lang in ['c', 'cpp']: pch = target.get_pch(lang) if len(pch) == 0: continue - if len(pch_sources) > 0: - raise MesonException('VS2010 backend does not support multiple precompiled header files.') pch_node.text = 'Use' + pch_sources[lang] = [pch[0], pch[1], lang] + 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. + pch_source = list(pch_sources.values())[0] + header = os.path.join(proj_to_src_dir, pch_source[0]) pch_file = ET.SubElement(clconf, 'PrecompiledHeaderFile') - pch_file.text = pch[0] + pch_file.text = header pch_include = ET.SubElement(clconf, 'ForcedIncludeFiles') - pch_include.text = pch[0] + ';%(ForcedIncludeFiles)' - pch_sources.append(pch[1]) + pch_include.text = header + ';%(ForcedIncludeFiles)' + pch_out = ET.SubElement(clconf, 'PrecompiledHeaderOutputFile') + pch_out.text = '$(IntDir)$(TargetName)-%s.pch' % pch_source[2] + warnings = ET.SubElement(clconf, 'WarningLevel') warnings.text = 'Level3' debinfo = ET.SubElement(clconf, 'DebugInformationFormat') @@ -504,15 +530,25 @@ class Vs2010Backend(backends.Backend): inc_src = ET.SubElement(root, 'ItemGroup') for s in sources: relpath = s.rel_to_builddir(proj_to_src_root) - ET.SubElement(inc_src, 'CLCompile', Include=relpath) - for s in pch_sources: - relpath = os.path.join(proj_to_src_dir, s) - comp_pch = ET.SubElement(inc_src, 'CLCompile', Include=relpath) - pch = ET.SubElement(comp_pch, 'PrecompiledHeader') - pch.text = 'Create' + inc_cl = ET.SubElement(inc_src, 'CLCompile', Include=relpath) + self.add_pch(inc_cl, proj_to_src_dir, pch_sources, s) for s in gen_src: relpath = self.relpath(s, target.subdir) - ET.SubElement(inc_src, 'CLCompile', Include=relpath) + inc_cl = ET.SubElement(inc_src, 'CLCompile', Include=relpath) + self.add_pch(inc_cl, proj_to_src_dir, pch_sources, s) + for lang in pch_sources: + header, impl, suffix = pch_sources[lang] + relpath = os.path.join(proj_to_src_dir, impl) + inc_cl = ET.SubElement(inc_src, 'CLCompile', Include=relpath) + pch = ET.SubElement(inc_cl, 'PrecompiledHeader') + pch.text = 'Create' + pch_out = ET.SubElement(inc_cl, 'PrecompiledHeaderOutputFile') + pch_out.text = '$(IntDir)$(TargetName)-%s.pch' % suffix + pch_file = ET.SubElement(inc_cl, 'PrecompiledHeaderFile') + # MSBuild searches for the header relative from the implementation, so we have to use + # just the file name instead of the relative path to the file. + pch_file.text = os.path.split(header)[1] + if len(objects) > 0: # Do not add gen_objs to project file. Those are automatically used by MSBuild, because they are part of # the CustomBuildStep Outputs. |