aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2018-07-27 14:38:50 +0300
committerGitHub <noreply@github.com>2018-07-27 14:38:50 +0300
commit8c735069b36b5e1ad1a2f3feac3d67e2bad492b7 (patch)
tree7359f9ff5ac795170e24dd6e7301d68f0a4a47ed
parente7dcf5cf16fdab2621bacde0bfebdac88131cdb5 (diff)
parent7bb5f8273601ad84e2d70794157d29557d80e841 (diff)
downloadmeson-8c735069b36b5e1ad1a2f3feac3d67e2bad492b7.zip
meson-8c735069b36b5e1ad1a2f3feac3d67e2bad492b7.tar.gz
meson-8c735069b36b5e1ad1a2f3feac3d67e2bad492b7.tar.bz2
Merge pull request #3898 from mesonbuild/vsinstall
Add install target to VS
-rw-r--r--mesonbuild/backend/backends.py224
-rw-r--r--mesonbuild/backend/ninjabackend.py223
-rw-r--r--mesonbuild/backend/vs2010backend.py77
-rw-r--r--mesonbuild/coredata.py1
4 files changed, 303 insertions, 222 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 0e2389d..ee67462 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -23,7 +23,7 @@ import subprocess
from ..mesonlib import MesonException, OrderedSet
from ..mesonlib import classify_unity_sources
from ..mesonlib import File
-from ..compilers import CompilerArgs
+from ..compilers import CompilerArgs, get_macos_dylib_install_name
from collections import OrderedDict
import shlex
@@ -922,3 +922,225 @@ class Backend:
for s in self.build.postconf_scripts:
cmd = s['exe'] + s['args']
subprocess.check_call(cmd, env=child_env)
+
+ def create_install_data_files(self):
+ install_data_file = os.path.join(self.environment.get_scratch_dir(), 'install.dat')
+
+ if self.environment.is_cross_build():
+ bins = self.environment.cross_info.config['binaries']
+ if 'strip' not in bins:
+ mlog.warning('Cross file does not specify strip binary, result will not be stripped.')
+ strip_bin = None
+ else:
+ strip_bin = mesonlib.stringlistify(bins['strip'])
+ else:
+ strip_bin = self.environment.native_strip_bin
+ d = InstallData(self.environment.get_source_dir(),
+ self.environment.get_build_dir(),
+ self.environment.get_prefix(),
+ strip_bin,
+ self.environment.coredata.get_builtin_option('install_umask'),
+ self.environment.get_build_command() + ['introspect'])
+ self.generate_depmf_install(d)
+ self.generate_target_install(d)
+ self.generate_header_install(d)
+ self.generate_man_install(d)
+ self.generate_data_install(d)
+ self.generate_custom_install_script(d)
+ self.generate_subdir_install(d)
+ with open(install_data_file, 'wb') as ofile:
+ pickle.dump(d, ofile)
+
+ def get_target_install_dirs(self, t):
+ # Find the installation directory.
+ if isinstance(t, build.SharedModule):
+ default_install_dir = self.environment.get_shared_module_dir()
+ elif isinstance(t, build.SharedLibrary):
+ default_install_dir = self.environment.get_shared_lib_dir()
+ elif isinstance(t, build.StaticLibrary):
+ default_install_dir = self.environment.get_static_lib_dir()
+ elif isinstance(t, build.Executable):
+ default_install_dir = self.environment.get_bindir()
+ elif isinstance(t, build.CustomTarget):
+ default_install_dir = None
+ else:
+ assert(isinstance(t, build.BuildTarget))
+ # XXX: Add BuildTarget-specific install dir cases here
+ default_install_dir = self.environment.get_libdir()
+ outdirs = t.get_custom_install_dir()
+ if outdirs[0] is not None and outdirs[0] != default_install_dir and outdirs[0] is not True:
+ # Either the value is set to a non-default value, or is set to
+ # False (which means we want this specific output out of many
+ # outputs to not be installed).
+ custom_install_dir = True
+ else:
+ custom_install_dir = False
+ outdirs[0] = default_install_dir
+ return outdirs, custom_install_dir
+
+ def get_target_link_deps_mappings(self, t, prefix):
+ '''
+ On macOS, we need to change the install names of all built libraries
+ that a target depends on using install_name_tool so that the target
+ continues to work after installation. For this, we need a dictionary
+ mapping of the install_name value to the new one, so we can change them
+ on install.
+ '''
+ result = {}
+ if isinstance(t, build.StaticLibrary):
+ return result
+ for ld in t.get_all_link_deps():
+ if ld is t or not isinstance(ld, build.SharedLibrary):
+ continue
+ old = get_macos_dylib_install_name(ld.prefix, ld.name, ld.suffix, ld.soversion)
+ if old in result:
+ continue
+ fname = ld.get_filename()
+ outdirs, _ = self.get_target_install_dirs(ld)
+ new = os.path.join(prefix, outdirs[0], fname)
+ result.update({old: new})
+ return result
+
+ def generate_target_install(self, d):
+ for t in self.build.get_targets().values():
+ if not t.should_install():
+ continue
+ outdirs, custom_install_dir = self.get_target_install_dirs(t)
+ # Sanity-check the outputs and install_dirs
+ num_outdirs, num_out = len(outdirs), len(t.get_outputs())
+ if num_outdirs != 1 and num_outdirs != num_out:
+ m = 'Target {!r} has {} outputs: {!r}, but only {} "install_dir"s were found.\n' \
+ "Pass 'false' for outputs that should not be installed and 'true' for\n" \
+ 'using the default installation directory for an output.'
+ raise MesonException(m.format(t.name, num_out, t.get_outputs(), num_outdirs))
+ install_mode = t.get_custom_install_mode()
+ # Install the target output(s)
+ if isinstance(t, build.BuildTarget):
+ should_strip = self.get_option_for_target('strip', t)
+ # Install primary build output (library/executable/jar, etc)
+ # Done separately because of strip/aliases/rpath
+ if outdirs[0] is not False:
+ mappings = self.get_target_link_deps_mappings(t, d.prefix)
+ i = TargetInstallData(self.get_target_filename(t), outdirs[0],
+ t.get_aliases(), should_strip, mappings,
+ t.install_rpath, install_mode)
+ d.targets.append(i)
+ # On toolchains/platforms that use an import library for
+ # linking (separate from the shared library with all the
+ # code), we need to install that too (dll.a/.lib).
+ if isinstance(t, (build.SharedLibrary, build.SharedModule, build.Executable)) and t.get_import_filename():
+ if custom_install_dir:
+ # If the DLL is installed into a custom directory,
+ # install the import library into the same place so
+ # it doesn't go into a surprising place
+ implib_install_dir = outdirs[0]
+ else:
+ implib_install_dir = self.environment.get_import_lib_dir()
+ # Install the import library.
+ i = TargetInstallData(self.get_target_filename_for_linking(t),
+ implib_install_dir, {}, False, {}, '', install_mode)
+ d.targets.append(i)
+ # Install secondary outputs. Only used for Vala right now.
+ if num_outdirs > 1:
+ for output, outdir in zip(t.get_outputs()[1:], outdirs[1:]):
+ # User requested that we not install this output
+ if outdir is False:
+ continue
+ f = os.path.join(self.get_target_dir(t), output)
+ i = TargetInstallData(f, outdir, {}, False, {}, None, install_mode)
+ d.targets.append(i)
+ elif isinstance(t, build.CustomTarget):
+ # If only one install_dir is specified, assume that all
+ # outputs will be installed into it. This is for
+ # backwards-compatibility and because it makes sense to
+ # avoid repetition since this is a common use-case.
+ #
+ # To selectively install only some outputs, pass `false` as
+ # the install_dir for the corresponding output by index
+ if num_outdirs == 1 and num_out > 1:
+ for output in t.get_outputs():
+ f = os.path.join(self.get_target_dir(t), output)
+ i = TargetInstallData(f, outdirs[0], {}, False, {}, None, install_mode)
+ d.targets.append(i)
+ else:
+ for output, outdir in zip(t.get_outputs(), outdirs):
+ # User requested that we not install this output
+ if outdir is False:
+ continue
+ f = os.path.join(self.get_target_dir(t), output)
+ i = TargetInstallData(f, outdir, {}, False, {}, None, install_mode)
+ d.targets.append(i)
+
+ def generate_custom_install_script(self, d):
+ result = []
+ srcdir = self.environment.get_source_dir()
+ builddir = self.environment.get_build_dir()
+ for i in self.build.install_scripts:
+ exe = i['exe']
+ args = i['args']
+ fixed_args = []
+ for a in args:
+ a = a.replace('@SOURCE_ROOT@', srcdir)
+ a = a.replace('@BUILD_ROOT@', builddir)
+ fixed_args.append(a)
+ result.append(build.RunScript(exe, fixed_args))
+ d.install_scripts = result
+
+ def generate_header_install(self, d):
+ incroot = self.environment.get_includedir()
+ headers = self.build.get_headers()
+
+ srcdir = self.environment.get_source_dir()
+ builddir = self.environment.get_build_dir()
+ for h in headers:
+ outdir = h.get_custom_install_dir()
+ if outdir is None:
+ outdir = os.path.join(incroot, h.get_install_subdir())
+ for f in h.get_sources():
+ if not isinstance(f, File):
+ msg = 'Invalid header type {!r} can\'t be installed'
+ raise MesonException(msg.format(f))
+ abspath = f.absolute_path(srcdir, builddir)
+ i = [abspath, outdir, h.get_custom_install_mode()]
+ d.headers.append(i)
+
+ def generate_man_install(self, d):
+ manroot = self.environment.get_mandir()
+ man = self.build.get_man()
+ for m in man:
+ for f in m.get_sources():
+ num = f.split('.')[-1]
+ subdir = m.get_custom_install_dir()
+ if subdir is None:
+ subdir = os.path.join(manroot, 'man' + num)
+ srcabs = f.absolute_path(self.environment.get_source_dir(), self.environment.get_build_dir())
+ dstabs = os.path.join(subdir, os.path.basename(f.fname) + '.gz')
+ i = [srcabs, dstabs, m.get_custom_install_mode()]
+ d.man.append(i)
+
+ def generate_data_install(self, d):
+ data = self.build.get_data()
+ srcdir = self.environment.get_source_dir()
+ builddir = self.environment.get_build_dir()
+ for de in data:
+ assert(isinstance(de, build.Data))
+ subdir = de.install_dir
+ if not subdir:
+ subdir = os.path.join(self.environment.get_datadir(), self.interpreter.build.project_name)
+ for src_file, dst_name in zip(de.sources, de.rename):
+ assert(isinstance(src_file, mesonlib.File))
+ dst_abs = os.path.join(subdir, dst_name)
+ i = [src_file.absolute_path(srcdir, builddir), dst_abs, de.install_mode]
+ d.data.append(i)
+
+ def generate_subdir_install(self, d):
+ for sd in self.build.get_install_subdirs():
+ src_dir = os.path.join(self.environment.get_source_dir(),
+ sd.source_subdir,
+ sd.installable_subdir).rstrip('/')
+ dst_dir = os.path.join(self.environment.get_prefix(),
+ sd.install_dir)
+ if not sd.strip_directory:
+ dst_dir = os.path.join(dst_dir, os.path.basename(src_dir))
+ d.install_subdirs.append([src_dir, dst_dir, sd.install_mode,
+ sd.exclude])
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index c248ae8..855564c 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -28,7 +28,7 @@ from .. import build
from .. import mlog
from .. import dependencies
from .. import compilers
-from ..compilers import CompilerArgs, CCompiler, get_macos_dylib_install_name
+from ..compilers import CompilerArgs, CCompiler
from ..linkers import ArLinker
from ..mesonlib import File, MesonException, OrderedSet
from ..mesonlib import get_compiler_for_source, has_path_sep
@@ -668,235 +668,16 @@ int dummy;
self.create_target_alias('meson-coverage-html', outfile)
def generate_install(self, outfile):
- install_data_file = os.path.join(self.environment.get_scratch_dir(), 'install.dat')
- if self.environment.is_cross_build():
- bins = self.environment.cross_info.config['binaries']
- if 'strip' not in bins:
- mlog.warning('Cross file does not specify strip binary, result will not be stripped.')
- strip_bin = None
- else:
- strip_bin = mesonlib.stringlistify(bins['strip'])
- else:
- strip_bin = self.environment.native_strip_bin
- d = InstallData(self.environment.get_source_dir(),
- self.environment.get_build_dir(),
- self.environment.get_prefix(),
- strip_bin,
- self.environment.coredata.get_builtin_option('install_umask'),
- self.environment.get_build_command() + ['introspect'])
+ self.create_install_data_files()
elem = NinjaBuildElement(self.all_outputs, 'meson-install', 'CUSTOM_COMMAND', 'PHONY')
elem.add_dep('all')
elem.add_item('DESC', 'Installing files.')
elem.add_item('COMMAND', self.environment.get_build_command() + ['install', '--no-rebuild'])
elem.add_item('pool', 'console')
- self.generate_depmf_install(d)
- self.generate_target_install(d)
- self.generate_header_install(d)
- self.generate_man_install(d)
- self.generate_data_install(d)
- self.generate_custom_install_script(d)
- self.generate_subdir_install(d)
elem.write(outfile)
# Alias that runs the target defined above
self.create_target_alias('meson-install', outfile)
- with open(install_data_file, 'wb') as ofile:
- pickle.dump(d, ofile)
-
- def get_target_install_dirs(self, t):
- # Find the installation directory.
- if isinstance(t, build.SharedModule):
- default_install_dir = self.environment.get_shared_module_dir()
- elif isinstance(t, build.SharedLibrary):
- default_install_dir = self.environment.get_shared_lib_dir()
- elif isinstance(t, build.StaticLibrary):
- default_install_dir = self.environment.get_static_lib_dir()
- elif isinstance(t, build.Executable):
- default_install_dir = self.environment.get_bindir()
- elif isinstance(t, build.CustomTarget):
- default_install_dir = None
- else:
- assert(isinstance(t, build.BuildTarget))
- # XXX: Add BuildTarget-specific install dir cases here
- default_install_dir = self.environment.get_libdir()
- outdirs = t.get_custom_install_dir()
- if outdirs[0] is not None and outdirs[0] != default_install_dir and outdirs[0] is not True:
- # Either the value is set to a non-default value, or is set to
- # False (which means we want this specific output out of many
- # outputs to not be installed).
- custom_install_dir = True
- else:
- custom_install_dir = False
- outdirs[0] = default_install_dir
- return outdirs, custom_install_dir
-
- def get_target_link_deps_mappings(self, t, prefix):
- '''
- On macOS, we need to change the install names of all built libraries
- that a target depends on using install_name_tool so that the target
- continues to work after installation. For this, we need a dictionary
- mapping of the install_name value to the new one, so we can change them
- on install.
- '''
- result = {}
- if isinstance(t, build.StaticLibrary):
- return result
- for ld in t.get_all_link_deps():
- if ld is t or not isinstance(ld, build.SharedLibrary):
- continue
- old = get_macos_dylib_install_name(ld.prefix, ld.name, ld.suffix, ld.soversion)
- if old in result:
- continue
- fname = ld.get_filename()
- outdirs, _ = self.get_target_install_dirs(ld)
- new = os.path.join(prefix, outdirs[0], fname)
- result.update({old: new})
- return result
-
- def generate_target_install(self, d):
- for t in self.build.get_targets().values():
- if not t.should_install():
- continue
- outdirs, custom_install_dir = self.get_target_install_dirs(t)
- # Sanity-check the outputs and install_dirs
- num_outdirs, num_out = len(outdirs), len(t.get_outputs())
- if num_outdirs != 1 and num_outdirs != num_out:
- m = 'Target {!r} has {} outputs: {!r}, but only {} "install_dir"s were found.\n' \
- "Pass 'false' for outputs that should not be installed and 'true' for\n" \
- 'using the default installation directory for an output.'
- raise MesonException(m.format(t.name, num_out, t.get_outputs(), num_outdirs))
- install_mode = t.get_custom_install_mode()
- # Install the target output(s)
- if isinstance(t, build.BuildTarget):
- should_strip = self.get_option_for_target('strip', t)
- # Install primary build output (library/executable/jar, etc)
- # Done separately because of strip/aliases/rpath
- if outdirs[0] is not False:
- mappings = self.get_target_link_deps_mappings(t, d.prefix)
- i = TargetInstallData(self.get_target_filename(t), outdirs[0],
- t.get_aliases(), should_strip, mappings,
- t.install_rpath, install_mode)
- d.targets.append(i)
- # On toolchains/platforms that use an import library for
- # linking (separate from the shared library with all the
- # code), we need to install that too (dll.a/.lib).
- if isinstance(t, (build.SharedLibrary, build.SharedModule, build.Executable)) and t.get_import_filename():
- if custom_install_dir:
- # If the DLL is installed into a custom directory,
- # install the import library into the same place so
- # it doesn't go into a surprising place
- implib_install_dir = outdirs[0]
- else:
- implib_install_dir = self.environment.get_import_lib_dir()
- # Install the import library.
- i = TargetInstallData(self.get_target_filename_for_linking(t),
- implib_install_dir, {}, False, {}, '', install_mode)
- d.targets.append(i)
- # Install secondary outputs. Only used for Vala right now.
- if num_outdirs > 1:
- for output, outdir in zip(t.get_outputs()[1:], outdirs[1:]):
- # User requested that we not install this output
- if outdir is False:
- continue
- f = os.path.join(self.get_target_dir(t), output)
- i = TargetInstallData(f, outdir, {}, False, {}, None, install_mode)
- d.targets.append(i)
- elif isinstance(t, build.CustomTarget):
- # If only one install_dir is specified, assume that all
- # outputs will be installed into it. This is for
- # backwards-compatibility and because it makes sense to
- # avoid repetition since this is a common use-case.
- #
- # To selectively install only some outputs, pass `false` as
- # the install_dir for the corresponding output by index
- if num_outdirs == 1 and num_out > 1:
- for output in t.get_outputs():
- f = os.path.join(self.get_target_dir(t), output)
- i = TargetInstallData(f, outdirs[0], {}, False, {}, None, install_mode)
- d.targets.append(i)
- else:
- for output, outdir in zip(t.get_outputs(), outdirs):
- # User requested that we not install this output
- if outdir is False:
- continue
- f = os.path.join(self.get_target_dir(t), output)
- i = TargetInstallData(f, outdir, {}, False, {}, None, install_mode)
- d.targets.append(i)
-
- def generate_custom_install_script(self, d):
- result = []
- srcdir = self.environment.get_source_dir()
- builddir = self.environment.get_build_dir()
- for i in self.build.install_scripts:
- exe = i['exe']
- args = i['args']
- fixed_args = []
- for a in args:
- a = a.replace('@SOURCE_ROOT@', srcdir)
- a = a.replace('@BUILD_ROOT@', builddir)
- fixed_args.append(a)
- result.append(build.RunScript(exe, fixed_args))
- d.install_scripts = result
-
- def generate_header_install(self, d):
- incroot = self.environment.get_includedir()
- headers = self.build.get_headers()
-
- srcdir = self.environment.get_source_dir()
- builddir = self.environment.get_build_dir()
- for h in headers:
- outdir = h.get_custom_install_dir()
- if outdir is None:
- outdir = os.path.join(incroot, h.get_install_subdir())
- for f in h.get_sources():
- if not isinstance(f, File):
- msg = 'Invalid header type {!r} can\'t be installed'
- raise MesonException(msg.format(f))
- abspath = f.absolute_path(srcdir, builddir)
- i = [abspath, outdir, h.get_custom_install_mode()]
- d.headers.append(i)
-
- def generate_man_install(self, d):
- manroot = self.environment.get_mandir()
- man = self.build.get_man()
- for m in man:
- for f in m.get_sources():
- num = f.split('.')[-1]
- subdir = m.get_custom_install_dir()
- if subdir is None:
- subdir = os.path.join(manroot, 'man' + num)
- srcabs = f.absolute_path(self.environment.get_source_dir(), self.environment.get_build_dir())
- dstabs = os.path.join(subdir, os.path.basename(f.fname) + '.gz')
- i = [srcabs, dstabs, m.get_custom_install_mode()]
- d.man.append(i)
-
- def generate_data_install(self, d):
- data = self.build.get_data()
- srcdir = self.environment.get_source_dir()
- builddir = self.environment.get_build_dir()
- for de in data:
- assert(isinstance(de, build.Data))
- subdir = de.install_dir
- if not subdir:
- subdir = os.path.join(self.environment.get_datadir(), self.interpreter.build.project_name)
- for src_file, dst_name in zip(de.sources, de.rename):
- assert(isinstance(src_file, mesonlib.File))
- dst_abs = os.path.join(subdir, dst_name)
- i = [src_file.absolute_path(srcdir, builddir), dst_abs, de.install_mode]
- d.data.append(i)
-
- def generate_subdir_install(self, d):
- for sd in self.build.get_install_subdirs():
- src_dir = os.path.join(self.environment.get_source_dir(),
- sd.source_subdir,
- sd.installable_subdir).rstrip('/')
- dst_dir = os.path.join(self.environment.get_prefix(),
- sd.install_dir)
- if not sd.strip_directory:
- dst_dir = os.path.join(dst_dir, os.path.basename(src_dir))
- d.install_subdirs.append([src_dir, dst_dir, sd.install_mode,
- sd.exclude])
-
def generate_tests(self, outfile):
self.serialize_tests()
cmd = self.environment.get_build_command(True) + ['test', '--no-rebuild']
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index d42e91d..abbab80 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -163,6 +163,7 @@ class Vs2010Backend(backends.Backend):
sln_filename = os.path.join(self.environment.get_build_dir(), self.build.project_name + '.sln')
projlist = self.generate_projects()
self.gen_testproj('RUN_TESTS', os.path.join(self.environment.get_build_dir(), 'RUN_TESTS.vcxproj'))
+ self.gen_installproj('RUN_INSTALL', os.path.join(self.environment.get_build_dir(), 'RUN_INSTALL.vcxproj'))
self.gen_regenproj('REGEN', os.path.join(self.environment.get_build_dir(), 'REGEN.vcxproj'))
self.generate_solution(sln_filename, projlist)
self.generate_regen_info()
@@ -298,6 +299,11 @@ class Vs2010Backend(backends.Backend):
self.environment.coredata.regen_guid)
ofile.write(regen_line)
ofile.write('EndProject\n')
+ install_line = prj_templ % (self.environment.coredata.lang_guids['default'],
+ 'RUN_INSTALL', 'RUN_INSTALL.vcxproj',
+ self.environment.coredata.install_guid)
+ ofile.write(install_line)
+ ofile.write('EndProject\n')
ofile.write('Global\n')
ofile.write('\tGlobalSection(SolutionConfigurationPlatforms) = '
'preSolution\n')
@@ -328,6 +334,9 @@ class Vs2010Backend(backends.Backend):
ofile.write('\t\t{%s}.%s|%s.ActiveCfg = %s|%s\n' %
(self.environment.coredata.test_guid, self.buildtype,
self.platform, self.buildtype, self.platform))
+ ofile.write('\t\t{%s}.%s|%s.ActiveCfg = %s|%s\n' %
+ (self.environment.coredata.install_guid, self.buildtype,
+ self.platform, self.buildtype, self.platform))
ofile.write('\tEndGlobalSection\n')
ofile.write('\tGlobalSection(SolutionProperties) = preSolution\n')
ofile.write('\t\tHideSolutionNode = FALSE\n')
@@ -1273,6 +1282,74 @@ if %%errorlevel%% neq 0 goto :VCEnd'''
ET.SubElement(root, 'Import', Project='$(VCTargetsPath)\Microsoft.Cpp.targets')
self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname)
+ def gen_installproj(self, target_name, ofname):
+ self.create_install_data_files()
+ project_name = target_name
+ root = ET.Element('Project', {'DefaultTargets': "Build",
+ 'ToolsVersion': '4.0',
+ 'xmlns': 'http://schemas.microsoft.com/developer/msbuild/2003'})
+ confitems = ET.SubElement(root, 'ItemGroup', {'Label': 'ProjectConfigurations'})
+ prjconf = ET.SubElement(confitems, 'ProjectConfiguration',
+ {'Include': self.buildtype + '|' + self.platform})
+ p = ET.SubElement(prjconf, 'Configuration')
+ p.text = self.buildtype
+ pl = ET.SubElement(prjconf, 'Platform')
+ pl.text = self.platform
+ globalgroup = ET.SubElement(root, 'PropertyGroup', Label='Globals')
+ guidelem = ET.SubElement(globalgroup, 'ProjectGuid')
+ guidelem.text = '{%s}' % self.environment.coredata.install_guid
+ kw = ET.SubElement(globalgroup, 'Keyword')
+ kw.text = self.platform + 'Proj'
+ p = ET.SubElement(globalgroup, 'Platform')
+ p.text = self.platform
+ pname = ET.SubElement(globalgroup, 'ProjectName')
+ pname.text = project_name
+ if self.windows_target_platform_version:
+ ET.SubElement(globalgroup, 'WindowsTargetPlatformVersion').text = self.windows_target_platform_version
+ ET.SubElement(root, 'Import', Project='$(VCTargetsPath)\Microsoft.Cpp.Default.props')
+ type_config = ET.SubElement(root, 'PropertyGroup', Label='Configuration')
+ ET.SubElement(type_config, 'ConfigurationType')
+ ET.SubElement(type_config, 'CharacterSet').text = 'MultiByte'
+ ET.SubElement(type_config, 'UseOfMfc').text = 'false'
+ if self.platform_toolset:
+ ET.SubElement(type_config, 'PlatformToolset').text = self.platform_toolset
+ ET.SubElement(root, 'Import', Project='$(VCTargetsPath)\Microsoft.Cpp.props')
+ direlem = ET.SubElement(root, 'PropertyGroup')
+ fver = ET.SubElement(direlem, '_ProjectFileVersion')
+ fver.text = self.project_file_version
+ outdir = ET.SubElement(direlem, 'OutDir')
+ outdir.text = '.\\'
+ intdir = ET.SubElement(direlem, 'IntDir')
+ intdir.text = 'install-temp\\'
+ tname = ET.SubElement(direlem, 'TargetName')
+ tname.text = target_name
+
+ action = ET.SubElement(root, 'ItemDefinitionGroup')
+ midl = ET.SubElement(action, 'Midl')
+ ET.SubElement(midl, "AdditionalIncludeDirectories").text = '%(AdditionalIncludeDirectories)'
+ ET.SubElement(midl, "OutputDirectory").text = '$(IntDir)'
+ ET.SubElement(midl, 'HeaderFileName').text = '%(Filename).h'
+ ET.SubElement(midl, 'TypeLibraryName').text = '%(Filename).tlb'
+ ET.SubElement(midl, 'InterfaceIdentifierFilename').text = '%(Filename)_i.c'
+ ET.SubElement(midl, 'ProxyFileName').text = '%(Filename)_p.c'
+ postbuild = ET.SubElement(action, 'PostBuildEvent')
+ ET.SubElement(postbuild, 'Message')
+ # FIXME: No benchmarks?
+ test_command = self.environment.get_build_command() + ['install', '--no-rebuild']
+ cmd_templ = '''setlocal
+"%s"
+if %%errorlevel%% neq 0 goto :cmEnd
+:cmEnd
+endlocal & call :cmErrorLevel %%errorlevel%% & goto :cmDone
+:cmErrorLevel
+exit /b %%1
+:cmDone
+if %%errorlevel%% neq 0 goto :VCEnd'''
+ ET.SubElement(postbuild, 'Command').text =\
+ cmd_templ % ('" "'.join(test_command))
+ ET.SubElement(root, 'Import', Project='$(VCTargetsPath)\Microsoft.Cpp.targets')
+ self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname)
+
def generate_debug_information(self, link):
# valid values for vs2015 is 'false', 'true', 'DebugFastLink'
ET.SubElement(link, 'GenerateDebugInformation').text = 'true'
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index b26516c..4c24dbd 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -211,6 +211,7 @@ class CoreData:
}
self.test_guid = str(uuid.uuid4()).upper()
self.regen_guid = str(uuid.uuid4()).upper()
+ self.install_guid = str(uuid.uuid4()).upper()
self.target_guids = {}
self.version = version
self.init_builtins()