aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Schneider <nioncode+git@gmail.com>2016-03-12 02:02:36 +0100
committerNicolas Schneider <nioncode+git@gmail.com>2016-03-12 02:02:36 +0100
commit49418cfe8ab1f42fa28ca9f408f60050bf56c5dc (patch)
tree759e245ac71403190805dd7a5241f5923cab8b03
parent5ba7680a0d5c275efe57ec531635caf2db3a0237 (diff)
downloadmeson-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.py62
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.