Merge pull request #3372 from NickeZ/vs-sol-folders

Use visual studio solution directories
pull/3481/head
Jussi Pakkanen 7 years ago committed by GitHub
commit 9c073620aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 88
      mesonbuild/backend/vs2010backend.py
  2. 8
      mesonbuild/coredata.py
  3. 8
      mesonbuild/minit.py

@ -16,6 +16,8 @@ import os
import pickle import pickle
import xml.dom.minidom import xml.dom.minidom
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
import uuid
from pathlib import Path, PurePath
from . import backends from . import backends
from .. import build from .. import build
@ -81,6 +83,7 @@ class Vs2010Backend(backends.Backend):
self.platform_toolset = None self.platform_toolset = None
self.vs_version = '2010' self.vs_version = '2010'
self.windows_target_platform_version = None self.windows_target_platform_version = None
self.subdirs = {}
def generate_custom_generator_commands(self, target, parent_node): def generate_custom_generator_commands(self, target, parent_node):
generator_output_files = [] generator_output_files = []
@ -225,6 +228,26 @@ class Vs2010Backend(backends.Backend):
ret.update(all_deps) ret.update(all_deps)
return ret return ret
def generate_solution_dirs(self, ofile, parents):
prj_templ = 'Project("{%s}") = "%s", "%s", "{%s}"\n'
iterpaths = reversed(parents)
# Skip first path
next(iterpaths)
for path in iterpaths:
if path not in self.subdirs:
basename = path.name
identifier = str(uuid.uuid4()).upper()
# top-level directories have None as their parent_dir
parent_dir = path.parent
parent_identifier = self.subdirs[parent_dir][0] \
if parent_dir != PurePath('.') else None
self.subdirs[path] = (identifier, parent_identifier)
prj_line = prj_templ % (
self.environment.coredata.lang_guids['directory'],
basename, basename, self.subdirs[path][0])
ofile.write(prj_line)
ofile.write('EndProject\n')
def generate_solution(self, sln_filename, projlist): def generate_solution(self, sln_filename, projlist):
default_projlist = self.get_build_by_default_targets() default_projlist = self.get_build_by_default_targets()
with open(sln_filename, 'w', encoding='utf-8') as ofile: with open(sln_filename, 'w', encoding='utf-8') as ofile:
@ -232,16 +255,26 @@ class Vs2010Backend(backends.Backend):
'Version 11.00\n') 'Version 11.00\n')
ofile.write('# Visual Studio ' + self.vs_version + '\n') ofile.write('# Visual Studio ' + self.vs_version + '\n')
prj_templ = 'Project("{%s}") = "%s", "%s", "{%s}"\n' prj_templ = 'Project("{%s}") = "%s", "%s", "{%s}"\n'
for p in projlist: for prj in projlist:
prj_line = prj_templ % (self.environment.coredata.guid, coredata = self.environment.coredata
p[0], p[1], p[2]) if coredata.get_builtin_option('layout') == 'mirror':
self.generate_solution_dirs(ofile, prj[1].parents)
target = self.build.targets[prj[0]]
lang = 'default'
if hasattr(target, 'compilers') and target.compilers:
for (lang_out, _) in target.compilers.items():
lang = lang_out
break
prj_line = prj_templ % (
self.environment.coredata.lang_guids[lang],
prj[0], prj[1], prj[2])
ofile.write(prj_line) ofile.write(prj_line)
target = self.build.targets[p[0]] target_dict = {target.get_id(): target}
t = {target.get_id(): target}
# Get direct deps # Get direct deps
all_deps = self.get_target_deps(t) all_deps = self.get_target_deps(target_dict)
# Get recursive deps # Get recursive deps
recursive_deps = self.get_target_deps(t, recursive=True) recursive_deps = self.get_target_deps(
target_dict, recursive=True)
ofile.write('\tProjectSection(ProjectDependencies) = ' ofile.write('\tProjectSection(ProjectDependencies) = '
'postProject\n') 'postProject\n')
regen_guid = self.environment.coredata.regen_guid regen_guid = self.environment.coredata.regen_guid
@ -252,14 +285,15 @@ class Vs2010Backend(backends.Backend):
ofile.write('EndProjectSection\n') ofile.write('EndProjectSection\n')
ofile.write('EndProject\n') ofile.write('EndProject\n')
for dep, target in recursive_deps.items(): for dep, target in recursive_deps.items():
if p[0] in default_projlist: if prj[0] in default_projlist:
default_projlist[dep] = target default_projlist[dep] = target
test_line = prj_templ % (self.environment.coredata.guid,
test_line = prj_templ % (self.environment.coredata.lang_guids['default'],
'RUN_TESTS', 'RUN_TESTS.vcxproj', 'RUN_TESTS', 'RUN_TESTS.vcxproj',
self.environment.coredata.test_guid) self.environment.coredata.test_guid)
ofile.write(test_line) ofile.write(test_line)
ofile.write('EndProject\n') ofile.write('EndProject\n')
regen_line = prj_templ % (self.environment.coredata.guid, regen_line = prj_templ % (self.environment.coredata.lang_guids['default'],
'REGEN', 'REGEN.vcxproj', 'REGEN', 'REGEN.vcxproj',
self.environment.coredata.regen_guid) self.environment.coredata.regen_guid)
ofile.write(regen_line) ofile.write(regen_line)
@ -298,19 +332,33 @@ class Vs2010Backend(backends.Backend):
ofile.write('\tGlobalSection(SolutionProperties) = preSolution\n') ofile.write('\tGlobalSection(SolutionProperties) = preSolution\n')
ofile.write('\t\tHideSolutionNode = FALSE\n') ofile.write('\t\tHideSolutionNode = FALSE\n')
ofile.write('\tEndGlobalSection\n') ofile.write('\tEndGlobalSection\n')
if self.subdirs:
ofile.write('\tGlobalSection(NestedProjects) = '
'preSolution\n')
for p in projlist:
if p[1].parent != PurePath('.'):
ofile.write("\t\t{%s} = {%s}\n" % (p[2], self.subdirs[p[1].parent][0]))
for (_, subdir) in self.subdirs.items():
if subdir[1]:
ofile.write("\t\t{%s} = {%s}\n" % (subdir[0], subdir[1]))
ofile.write('\tEndGlobalSection\n')
ofile.write('EndGlobal\n') ofile.write('EndGlobal\n')
def generate_projects(self): def generate_projects(self):
projlist = [] projlist = []
for name, target in self.build.targets.items(): for name, target in self.build.targets.items():
outdir = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target)) outdir = Path(
os.makedirs(outdir, exist_ok=True) self.environment.get_build_dir(),
self.get_target_dir(target)
)
outdir.mkdir(exist_ok=True, parents=True)
fname = name + '.vcxproj' fname = name + '.vcxproj'
relname = os.path.join(target.subdir, fname) target_dir = PurePath(self.get_target_dir(target))
projfile = os.path.join(outdir, fname) relname = target_dir / fname
uuid = self.environment.coredata.target_guids[name] projfile_path = outdir / fname
self.gen_vcxproj(target, projfile, uuid) proj_uuid = self.environment.coredata.target_guids[name]
projlist.append((name, relname, uuid)) self.gen_vcxproj(target, str(projfile_path), proj_uuid)
projlist.append((name, relname, proj_uuid))
return projlist return projlist
def split_sources(self, srclist): def split_sources(self, srclist):
@ -336,10 +384,10 @@ class Vs2010Backend(backends.Backend):
return sources, headers, objects, languages return sources, headers, objects, languages
def target_to_build_root(self, target): def target_to_build_root(self, target):
if target.subdir == '': if self.get_target_dir(target) == '':
return '' return ''
directories = os.path.normpath(target.subdir).split(os.sep) directories = os.path.normpath(self.get_target_dir(target)).split(os.sep)
return os.sep.join(['..'] * len(directories)) return os.sep.join(['..'] * len(directories))
def quote_arguments(self, arr): def quote_arguments(self, arr):
@ -603,7 +651,7 @@ class Vs2010Backend(backends.Backend):
# Prefix to use to access the source tree's root from the vcxproj dir # Prefix to use to access the source tree's root from the vcxproj dir
proj_to_src_root = os.path.join(down, self.build_to_src) proj_to_src_root = os.path.join(down, self.build_to_src)
# Prefix to use to access the source tree's subdir from the vcxproj dir # Prefix to use to access the source tree's subdir from the vcxproj dir
proj_to_src_dir = os.path.join(proj_to_src_root, target.subdir) proj_to_src_dir = os.path.join(proj_to_src_root, self.get_target_dir(target))
(sources, headers, objects, languages) = self.split_sources(target.sources) (sources, headers, objects, languages) = self.split_sources(target.sources)
if self.is_unity(target): if self.is_unity(target):
sources = self.generate_unity_files(target, sources) sources = self.generate_unity_files(target, sources)

@ -166,7 +166,13 @@ This will become a hard error in the future.''')
class CoreData: class CoreData:
def __init__(self, options): def __init__(self, options):
self.guid = str(uuid.uuid4()).upper() self.lang_guids = {
'default': '8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942',
'c': '8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942',
'cpp': '8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942',
'test': '3AC096D0-A1C2-E12C-1390-A8335801FDAB',
'directory': '2150E333-8FDC-42A3-9474-1A3956D46DE8',
}
self.test_guid = str(uuid.uuid4()).upper() self.test_guid = str(uuid.uuid4()).upper()
self.regen_guid = str(uuid.uuid4()).upper() self.regen_guid = str(uuid.uuid4()).upper()
self.target_guids = {} self.target_guids = {}

@ -14,7 +14,7 @@
"""Code that creates simple startup projects.""" """Code that creates simple startup projects."""
import os, sys, argparse, re, shutil import os, sys, argparse, re, shutil, subprocess
from glob import glob from glob import glob
from mesonbuild import mesonlib from mesonbuild import mesonlib
from mesonbuild.environment import detect_ninja from mesonbuild.environment import detect_ninja
@ -471,10 +471,12 @@ def run(args):
print('Build directory already exists, deleting it.') print('Build directory already exists, deleting it.')
shutil.rmtree(options.builddir) shutil.rmtree(options.builddir)
print('Building...') print('Building...')
err = os.system('{} "{}"'.format(' '.join(mesonlib.meson_command), options.builddir)) cmd = mesonlib.meson_command + [options.builddir]
err = subprocess.call(cmd)
if err: if err:
sys.exit(1) sys.exit(1)
err = os.system('{} -C "{}"'.format(detect_ninja(), options.builddir)) cmd = [detect_ninja(), '-C', options.builddir]
err = subprocess.call(cmd)
if err: if err:
sys.exit(1) sys.exit(1)
return 0 return 0

Loading…
Cancel
Save