vs2010: support language specific extra_args

pull/441/head
Nicolas Schneider 9 years ago
parent 304c0d2cb5
commit 8eac78b861
  1. 75
      mesonbuild/backend/vs2010backend.py

@ -220,14 +220,18 @@ class Vs2010Backend(backends.Backend):
sources = [] sources = []
headers = [] headers = []
objects = [] objects = []
languages = []
for i in srclist: for i in srclist:
lang = self.lang_from_source_file(i)
if lang not in languages:
languages.append(lang)
if self.environment.is_header(i): if self.environment.is_header(i):
headers.append(i) headers.append(i)
elif self.environment.is_object(i): elif self.environment.is_object(i):
objects.append(i) objects.append(i)
else: else:
sources.append(i) sources.append(i)
return (sources, headers, objects) return (sources, headers, objects, languages)
def target_to_build_root(self, target): def target_to_build_root(self, target):
if target.subdir == '': if target.subdir == '':
@ -314,16 +318,20 @@ class Vs2010Backend(backends.Backend):
tree = ET.ElementTree(root) tree = ET.ElementTree(root)
tree.write(ofname, encoding='utf-8', xml_declaration=True) tree.write(ofname, encoding='utf-8', xml_declaration=True)
@classmethod
def lang_from_source_file(cls, src):
ext = src.split('.')[-1]
if ext in compilers.c_suffixes:
return 'c'
if ext in compilers.cpp_suffixes:
return 'cpp'
raise MesonException('Could not guess language from source file %s.' % src)
def add_pch(self, inc_cl, proj_to_src_dir, pch_sources, source_file): def add_pch(self, inc_cl, proj_to_src_dir, pch_sources, source_file):
if len(pch_sources) <= 1: if len(pch_sources) <= 1:
# We only need per file precompiled headers if we have more than 1 language. # We only need per file precompiled headers if we have more than 1 language.
return return
if source_file.split('.')[-1] in compilers.c_suffixes: lang = Vs2010Backend.lang_from_source_file(source_file)
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]) header = os.path.join(proj_to_src_dir, pch_sources[lang][0])
pch_file = ET.SubElement(inc_cl, 'PrecompiledHeaderFile') pch_file = ET.SubElement(inc_cl, 'PrecompiledHeaderFile')
pch_file.text = header pch_file.text = header
@ -332,6 +340,13 @@ class Vs2010Backend(backends.Backend):
pch_out = ET.SubElement(inc_cl, 'PrecompiledHeaderOutputFile') pch_out = ET.SubElement(inc_cl, 'PrecompiledHeaderOutputFile')
pch_out.text = '$(IntDir)$(TargetName)-%s.pch' % lang pch_out.text = '$(IntDir)$(TargetName)-%s.pch' % lang
def add_additional_options(self, source_file, parent_node, extra_args, has_additional_options_set):
if has_additional_options_set:
# We only need per file options if they were not set per project.
return
lang = Vs2010Backend.lang_from_source_file(source_file)
ET.SubElement(parent_node, "AdditionalOptions").text = ' '.join(extra_args[lang]) + ' %(AdditionalOptions)'
def gen_vcxproj(self, target, ofname, guid, compiler): def gen_vcxproj(self, target, ofname, guid, compiler):
mlog.debug('Generating vcxproj %s.' % target.name) mlog.debug('Generating vcxproj %s.' % target.name)
entrypoint = 'WinMainCRTStartup' entrypoint = 'WinMainCRTStartup'
@ -355,7 +370,7 @@ class Vs2010Backend(backends.Backend):
down = self.target_to_build_root(target) down = self.target_to_build_root(target)
proj_to_src_root = os.path.join(down, self.build_to_src) proj_to_src_root = os.path.join(down, self.build_to_src)
proj_to_src_dir = os.path.join(proj_to_src_root, target.subdir) proj_to_src_dir = os.path.join(proj_to_src_root, target.subdir)
(sources, headers, objects) = self.split_sources(target.sources) (sources, headers, objects, languages) = self.split_sources(target.sources)
buildtype = self.buildtype buildtype = self.buildtype
project_name = target.name project_name = target.name
target_name = target.name target_name = target.name
@ -388,7 +403,7 @@ class Vs2010Backend(backends.Backend):
ET.SubElement(type_config, 'UseDebugLibraries').text = 'true' ET.SubElement(type_config, 'UseDebugLibraries').text = 'true'
ET.SubElement(root, 'Import', Project='$(VCTargetsPath)\Microsoft.Cpp.props') ET.SubElement(root, 'Import', Project='$(VCTargetsPath)\Microsoft.Cpp.props')
generated_files = self.generate_custom_generator_commands(target, root) generated_files = self.generate_custom_generator_commands(target, root)
(gen_src, gen_hdrs, gen_objs) = self.split_sources(generated_files) (gen_src, gen_hdrs, gen_objs, gen_langs) = self.split_sources(generated_files)
direlem = ET.SubElement(root, 'PropertyGroup') direlem = ET.SubElement(root, 'PropertyGroup')
fver = ET.SubElement(direlem, '_ProjectFileVersion') fver = ET.SubElement(direlem, '_ProjectFileVersion')
fver.text = self.project_file_version fver.text = self.project_file_version
@ -410,28 +425,39 @@ class Vs2010Backend(backends.Backend):
if cur_dir == '': if cur_dir == '':
cur_dir= '.' cur_dir= '.'
inc_dirs.append(cur_dir) inc_dirs.append(cur_dir)
extra_args = []
# SUCKS, VS can not handle per-language type flags, so just use extra_args = {'c': [], 'cpp': []}
# them all. for l, args in self.environment.coredata.external_args.items():
extra_args += compiler.get_buildtype_args(self.buildtype) if l in extra_args:
for l in self.environment.coredata.external_args.values(): extra_args[l] += args
for a in l: for l, args in self.build.global_args.items():
extra_args.append(a) if l in extra_args:
for l in self.build.global_args.values(): extra_args[l] += args
for a in l: for l, args in target.extra_args.items():
extra_args.append(a) if l in extra_args:
for l in target.extra_args.values(): extra_args[l] += args
for a in l: for l in extra_args:
extra_args.append(a) comp_args = compiler.get_buildtype_args(self.buildtype)
# FIXME all the internal flags of VS (optimization etc) are represented # FIXME all the internal flags of VS (optimization etc) are represented
# by their own XML elements. In theory we should split all flags to those # by their own XML elements. In theory we should split all flags to those
# that have an XML element and those that don't and serialise them # that have an XML element and those that don't and serialise them
# properly. This is a crapton of work for no real gain, so just dump them # properly. This is a crapton of work for no real gain, so just dump them
# here. # here.
extra_args = compiler.get_option_compile_args(self.environment.coredata.compiler_options) comp_args += compiler.get_option_compile_args(self.environment.coredata.compiler_options)
extra_args[l] = comp_args + extra_args[l]
for d in target.get_external_deps():
extra_args[l] += d.compile_args
languages += gen_langs
has_language_specific_args = any(l != extra_args['c'] for l in extra_args.values())
additional_options_set = False
if not has_language_specific_args or len(languages) == 1:
extra_args = extra_args[languages[0]]
if len(extra_args) > 0: if len(extra_args) > 0:
extra_args.append('%(AdditionalOptions)') extra_args.append('%(AdditionalOptions)')
ET.SubElement(clconf, "AdditionalOptions").text = ' '.join(extra_args) ET.SubElement(clconf, "AdditionalOptions").text = ' '.join(extra_args)
additional_options_set = True
for d in target.include_dirs: for d in target.include_dirs:
for i in d.incdirs: for i in d.incdirs:
curdir = os.path.join(d.curdir, i) curdir = os.path.join(d.curdir, i)
@ -532,10 +558,12 @@ class Vs2010Backend(backends.Backend):
relpath = s.rel_to_builddir(proj_to_src_root) relpath = s.rel_to_builddir(proj_to_src_root)
inc_cl = 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) self.add_pch(inc_cl, proj_to_src_dir, pch_sources, s)
self.add_additional_options(s, inc_cl, extra_args, additional_options_set)
for s in gen_src: for s in gen_src:
relpath = self.relpath(s, target.subdir) relpath = self.relpath(s, target.subdir)
inc_cl = 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) self.add_pch(inc_cl, proj_to_src_dir, pch_sources, s)
self.add_additional_options(s, inc_cl, extra_args, additional_options_set)
for lang in pch_sources: for lang in pch_sources:
header, impl, suffix = pch_sources[lang] header, impl, suffix = pch_sources[lang]
relpath = os.path.join(proj_to_src_dir, impl) relpath = os.path.join(proj_to_src_dir, impl)
@ -548,6 +576,7 @@ class Vs2010Backend(backends.Backend):
# MSBuild searches for the header relative from the implementation, so we have to use # 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. # just the file name instead of the relative path to the file.
pch_file.text = os.path.split(header)[1] pch_file.text = os.path.split(header)[1]
self.add_additional_options(impl, inc_cl, extra_args, additional_options_set)
if len(objects) > 0: if len(objects) > 0:
# Do not add gen_objs to project file. Those are automatically used by MSBuild, because they are part of # Do not add gen_objs to project file. Those are automatically used by MSBuild, because they are part of

Loading…
Cancel
Save