|
|
@ -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 |
|
|
|