From 19003e49d0c5aefd3a2a56f6b5ab48ab4c9d01e4 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Wed, 4 Nov 2015 20:00:04 +0200 Subject: [PATCH] Generate a standin vcxproject to regenerate build definitions when the project setup changes. --- coredata.py | 1 + regen_checker.py | 24 ++++++++++++++ vs2010backend.py | 85 ++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 103 insertions(+), 7 deletions(-) create mode 100644 regen_checker.py diff --git a/coredata.py b/coredata.py index 4c244c063..711dddf8b 100644 --- a/coredata.py +++ b/coredata.py @@ -42,6 +42,7 @@ class CoreData(): def __init__(self, options): self.guid = str(uuid.uuid4()).upper() self.test_guid = str(uuid.uuid4()).upper() + self.regen_guid = str(uuid.uuid4()).upper() self.target_guids = {} self.version = version self.prefix = options.prefix diff --git a/regen_checker.py b/regen_checker.py new file mode 100644 index 000000000..13adc3f01 --- /dev/null +++ b/regen_checker.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 + +# Copyright 2015 The Meson development team + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys + +print('I am a script that checks whether VS solution should be regenerated.') +print('Currently I do nothing.') + +# This could also be used for XCode. + +sys.exit(0) \ No newline at end of file diff --git a/vs2010backend.py b/vs2010backend.py index 68e8e6c0b..c4dbe9d53 100644 --- a/vs2010backend.py +++ b/vs2010backend.py @@ -1,4 +1,4 @@ -# Copyright 2014 The Meson development team +# Copyright 2014-2015 The Meson development team # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -68,6 +68,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_regenproj('REGEN', os.path.join(self.environment.get_build_dir(), 'REGEN.vcxproj')) self.generate_solution(sln_filename, projlist) def get_obj_target_deps(self, obj_list): @@ -94,22 +95,28 @@ class Vs2010Backend(backends.Backend): gen_exe = gendep.generator.get_exe() if isinstance(gen_exe, build.Executable): all_deps[gen_exe.get_id()] = True - if len(all_deps) > 0: - ofile.write('\tProjectSection(ProjectDependencies) = postProject\n') - for dep in all_deps.keys(): - guid = self.environment.coredata.target_guids[dep] - ofile.write('\t\t{%s} = {%s}\n' % (guid, guid)) - ofile.write('EndProjectSection\n') + ofile.write('\tProjectSection(ProjectDependencies) = postProject\n') + regen_guid = self.environment.coredata.regen_guid + ofile.write('\t\t{%s} = {%s}\n' % (regen_guid, regen_guid)) + for dep in all_deps.keys(): + guid = self.environment.coredata.target_guids[dep] + ofile.write('\t\t{%s} = {%s}\n' % (guid, guid)) + ofile.write('EndProjectSection\n') ofile.write('EndProject\n') test_line = prj_templ % (self.environment.coredata.guid, 'RUN_TESTS', 'RUN_TESTS.vcxproj', self.environment.coredata.test_guid) ofile.write(test_line) + regen_line = prj_templ % (self.environment.coredata.guid, + 'REGEN', 'REGEN.vcxproj', self.environment.coredata.regen_guid) + ofile.write(regen_line) ofile.write('EndProject\n') ofile.write('Global\n') ofile.write('\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n') ofile.write('\t\tDebug|Win32 = Debug|Win32\n') ofile.write('\tEndGlobalSection\n') ofile.write('\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n') + ofile.write('\t\t{%s}.Debug|Win32.ActiveCfg = Debug|Win32\n' % regen_guid) + ofile.write('\t\t{%s}.Debug|Win32.Build.0 = Debug|Win32\n' % regen_guid) for p in projlist: ofile.write('\t\t{%s}.Debug|Win32.ActiveCfg = Debug|Win32\n' % p[2]) ofile.write('\t\t{%s}.Debug|Win32.Build.0 = Debug|Win32\n' % p[2]) @@ -331,6 +338,70 @@ class Vs2010Backend(backends.Backend): txt = open(ofname, 'r').read() open(ofname, 'w').write(txt.replace('"', '"')) + def gen_regenproj(self, project_name, ofname): + buildtype = self.environment.coredata.buildtype + platform = "Win32" + 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' : 'Debug|Win32'}) + p = ET.SubElement(prjconf, 'Configuration') + p.text= buildtype + pl = ET.SubElement(prjconf, 'Platform') + pl.text = platform + globalgroup = ET.SubElement(root, 'PropertyGroup', Label='Globals') + guidelem = ET.SubElement(globalgroup, 'ProjectGuid') + guidelem.text = self.environment.coredata.test_guid + kw = ET.SubElement(globalgroup, 'Keyword') + kw.text = 'Win32Proj' + p = ET.SubElement(globalgroup, 'Platform') + p.text= platform + pname= ET.SubElement(globalgroup, 'ProjectName') + pname.text = project_name + 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' + 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 = 'test-temp\\' + tname = ET.SubElement(direlem, 'TargetName') + tname.text = project_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') + script_root = self.environment.get_script_dir() + regen_script = os.path.join(script_root, 'regen_checker.py') + private_dir = self.environment.get_scratch_dir() + cmd_templ = '''setlocal +"%s" "%s" "%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 % (sys.executable, regen_script, private_dir) + ET.SubElement(root, 'Import', Project='$(VCTargetsPath)\Microsoft.Cpp.targets') + tree = ET.ElementTree(root) + tree.write(ofname, encoding='utf-8', xml_declaration=True) + def gen_testproj(self, target_name, ofname): buildtype = self.environment.coredata.buildtype platform = "Win32"