diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2016-03-20 21:24:48 +0200 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2016-03-20 21:24:48 +0200 |
commit | c1a0bd9a52509858350f05802f1a85517be3d5c6 (patch) | |
tree | 7913231e81d8b912007bbe668dd8981b49c766c5 | |
parent | 8b619420f994f5c77eb6540262277a0e668d7899 (diff) | |
parent | 2511ff0970b9ff7730c0660585abf6408ca3345f (diff) | |
download | meson-c1a0bd9a52509858350f05802f1a85517be3d5c6.zip meson-c1a0bd9a52509858350f05802f1a85517be3d5c6.tar.gz meson-c1a0bd9a52509858350f05802f1a85517be3d5c6.tar.bz2 |
Merge pull request #441 from nioncode/vs-compile-args
vs2010: fix compile args
-rw-r--r-- | mesonbuild/backend/vs2010backend.py | 91 |
1 files changed, 64 insertions, 27 deletions
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index 8d9d4e8..5542a8b 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -220,14 +220,21 @@ class Vs2010Backend(backends.Backend): sources = [] headers = [] objects = [] + languages = [] for i in srclist: if self.environment.is_header(i): headers.append(i) elif self.environment.is_object(i): objects.append(i) - else: + elif self.environment.is_source(i): sources.append(i) - return (sources, headers, objects) + lang = self.lang_from_source_file(i) + if lang not in languages: + languages.append(lang) + else: + # Everything that is not an object or source file is considered a header. + headers.append(i) + return (sources, headers, objects, languages) def target_to_build_root(self, target): if target.subdir == '': @@ -314,16 +321,20 @@ class Vs2010Backend(backends.Backend): tree = ET.ElementTree(root) 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): 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 + lang = Vs2010Backend.lang_from_source_file(source_file) header = os.path.join(proj_to_src_dir, pch_sources[lang][0]) pch_file = ET.SubElement(inc_cl, 'PrecompiledHeaderFile') pch_file.text = header @@ -332,6 +343,13 @@ class Vs2010Backend(backends.Backend): pch_out = ET.SubElement(inc_cl, 'PrecompiledHeaderOutputFile') 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): mlog.debug('Generating vcxproj %s.' % target.name) entrypoint = 'WinMainCRTStartup' @@ -355,7 +373,7 @@ class Vs2010Backend(backends.Backend): down = self.target_to_build_root(target) 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) - (sources, headers, objects) = self.split_sources(target.sources) + (sources, headers, objects, languages) = self.split_sources(target.sources) buildtype = self.buildtype project_name = target.name target_name = target.name @@ -388,7 +406,7 @@ class Vs2010Backend(backends.Backend): ET.SubElement(type_config, 'UseDebugLibraries').text = 'true' ET.SubElement(root, 'Import', Project='$(VCTargetsPath)\Microsoft.Cpp.props') 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') fver = ET.SubElement(direlem, '_ProjectFileVersion') fver.text = self.project_file_version @@ -410,28 +428,44 @@ class Vs2010Backend(backends.Backend): if cur_dir == '': cur_dir= '.' inc_dirs.append(cur_dir) - extra_args = [] - # SUCKS, VS can not handle per-language type flags, so just use - # them all. - extra_args += compiler.get_buildtype_args(self.buildtype) - for l in self.environment.coredata.external_args.values(): - for a in l: - extra_args.append(a) - for l in self.build.global_args.values(): - for a in l: - extra_args.append(a) - for l in target.extra_args.values(): - for a in l: - extra_args.append(a) + + extra_args = {'c': [], 'cpp': []} + for l, args in self.environment.coredata.external_args.items(): + if l in extra_args: + extra_args[l] += args + for l, args in self.build.global_args.items(): + if l in extra_args: + extra_args[l] += args + for l, args in target.extra_args.items(): + if l in extra_args: + extra_args[l] += args + general_args = compiler.get_buildtype_args(self.buildtype) # 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 # 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 # here. - extra_args = compiler.get_option_compile_args(self.environment.coredata.compiler_options) - if len(extra_args) > 0: - extra_args.append('%(AdditionalOptions)') - ET.SubElement(clconf, "AdditionalOptions").text = ' '.join(extra_args) + general_args += compiler.get_option_compile_args(self.environment.coredata.compiler_options) + for d in target.get_external_deps(): + try: + general_args += d.compile_args + except AttributeError: + pass + + 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: + if len(languages) == 0: + extra_args = [] + else: + extra_args = extra_args[languages[0]] + extra_args = general_args + extra_args + if len(extra_args) > 0: + extra_args.append('%(AdditionalOptions)') + ET.SubElement(clconf, "AdditionalOptions").text = ' '.join(extra_args) + additional_options_set = True + for d in target.include_dirs: for i in d.incdirs: curdir = os.path.join(d.curdir, i) @@ -533,10 +567,12 @@ class Vs2010Backend(backends.Backend): relpath = s.rel_to_builddir(proj_to_src_root) inc_cl = ET.SubElement(inc_src, 'CLCompile', Include=relpath) 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: relpath = self.relpath(s, target.subdir) inc_cl = ET.SubElement(inc_src, 'CLCompile', Include=relpath) 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: header, impl, suffix = pch_sources[lang] relpath = os.path.join(proj_to_src_dir, impl) @@ -549,6 +585,7 @@ class Vs2010Backend(backends.Backend): # 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] + self.add_additional_options(impl, inc_cl, extra_args, additional_options_set) if len(objects) + len(additional_objects) > 0: # Do not add gen_objs to project file. Those are automatically used by MSBuild, because they are part of |