Simple custom targets work in VS2010.

pull/278/head
Jussi Pakkanen 9 years ago
parent d7ad8c601b
commit e8cca681ca
  1. 42
      backends.py
  2. 38
      ninjabackend.py
  3. 86
      vs2010backend.py

@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import os, pickle
import os, pickle, re
import build
import dependencies
import mesonlib
@ -350,3 +350,43 @@ class Backend():
if os.path.isfile(fname):
deps.append(os.path.join(self.build_to_src, sp, 'meson_options.txt'))
return deps
def eval_custom_target_command(self, target):
ofilenames = [os.path.join(self.get_target_dir(target), i) for i in target.output]
srcs = []
for i in target.sources:
if isinstance(i, str):
srcs.append(os.path.join(self.build_to_src, target.subdir, i))
else:
srcs.append(i.rel_to_builddir(self.build_to_src))
cmd = []
for i in target.command:
if isinstance(i, build.CustomTarget):
# GIR scanner will attempt to execute this binary but
# it assumes that it is in path, so always give it a full path.
tmp = i.get_filename()[0]
i = os.path.join(self.get_target_dir(i), tmp)
for (j, src) in enumerate(srcs):
i = i.replace('@INPUT%d@' % j, src)
for (j, res) in enumerate(ofilenames):
i = i.replace('@OUTPUT%d@' % j, res)
if i == '@INPUT@':
cmd += srcs
elif i == '@OUTPUT@':
cmd += ofilenames
else:
if '@OUTDIR@' in i:
i = i.replace('@OUTDIR@', self.get_target_dir(target))
elif '@PRIVATE_OUTDIR_' in i:
match = re.search('@PRIVATE_OUTDIR_(ABS_)?([-a-zA-Z0-9.@:]*)@', i)
source = match.group(0)
if match.group(1) is None:
lead_dir = ''
else:
lead_dir = self.environment.get_build_dir()
target_id = match.group(2)
i = i.replace(source,
os.path.join(lead_dir,
self.get_target_dir(self.build.targets[target_id])))
cmd.append(i)
return (srcs, ofilenames, cmd)

@ -287,19 +287,13 @@ class NinjaBackend(backends.Backend):
self.generate_target(t, outfile)
def generate_custom_target(self, target, outfile):
ofilenames = [os.path.join(self.get_target_dir(target), i) for i in target.output]
(srcs, ofilenames, cmd) = self.eval_custom_target_command(target)
deps = []
for i in target.get_dependencies():
# FIXME, should not grab element at zero but rather expand all.
if isinstance(i, list):
i = i[0]
deps.append(os.path.join(self.get_target_dir(i), i.get_filename()[0]))
srcs = []
for i in target.sources:
if isinstance(i, str):
srcs.append(os.path.join(self.build_to_src, target.subdir, i))
else:
srcs.append(i.rel_to_builddir(self.build_to_src))
if target.build_always:
deps.append('PHONY')
elem = NinjaBuildElement(ofilenames, 'CUSTOM_COMMAND', srcs)
@ -315,36 +309,6 @@ class NinjaBackend(backends.Backend):
tmp = [tmp]
for fname in tmp:
elem.add_dep(os.path.join(self.get_target_dir(d), fname))
cmd = []
for i in target.command:
if isinstance(i, build.CustomTarget):
# GIR scanner will attempt to execute this binary but
# it assumes that it is in path, so always give it a full path.
tmp = i.get_filename()[0]
i = os.path.join(self.get_target_dir(i), tmp)
for (j, src) in enumerate(srcs):
i = i.replace('@INPUT%d@' % j, src)
for (j, res) in enumerate(ofilenames):
i = i.replace('@OUTPUT%d@' % j, res)
if i == '@INPUT@':
cmd += srcs
elif i == '@OUTPUT@':
cmd += ofilenames
else:
if '@OUTDIR@' in i:
i = i.replace('@OUTDIR@', self.get_target_dir(target))
elif '@PRIVATE_OUTDIR_' in i:
match = re.search('@PRIVATE_OUTDIR_(ABS_)?([-a-zA-Z0-9.@:]*)@', i)
source = match.group(0)
if match.group(1) is None:
lead_dir = ''
else:
lead_dir = self.environment.get_build_dir()
target_id = match.group(2)
i = i.replace(source,
os.path.join(lead_dir,
self.get_target_dir(self.build.targets[target_id])))
cmd.append(i)
elem.add_item('COMMAND', cmd)
elem.add_item('description', 'Generating %s with a custom command.' % target.name)

@ -15,6 +15,7 @@
import os, sys
import pickle
import backends, build
import mlog
import xml.etree.ElementTree as ET
import xml.dom.minidom
from coredata import MesonException
@ -37,6 +38,9 @@ class Vs2010Backend(backends.Backend):
idgroup = ET.SubElement(parent_node, 'ItemDefinitionGroup')
all_output_files = []
for genlist in target.get_generated_sources():
if isinstance(genlist, build.CustomTarget):
all_output_files += [os.path.join(self.get_target_dir(genlist), i) for i in genlist.output]
else:
generator = genlist.get_generator()
exe = generator.get_exe()
infilelist = genlist.get_infilelist()
@ -99,6 +103,26 @@ class Vs2010Backend(backends.Backend):
result[o.target.get_basename()] = True
return result.keys()
def determine_deps(self, p):
all_deps = {}
target = self.build.targets[p[0]]
if isinstance(target, build.CustomTarget):
for d in target.dependencies:
all_deps[d.get_id()] = True
return all_deps
for ldep in target.link_targets:
all_deps[ldep.get_id()] = True
for objdep in self.get_obj_target_deps(target.objects):
all_deps[objdep] = True
for gendep in target.generated:
if isinstance(gendep, build.CustomTarget):
all_deps[gendep.get_id()] = True
else:
gen_exe = gendep.generator.get_exe()
if isinstance(gen_exe, build.Executable):
all_deps[gen_exe.get_id()] = True
return all_deps
def generate_solution(self, sln_filename, projlist):
ofile = open(sln_filename, 'w')
ofile.write('Microsoft Visual Studio Solution File, Format Version 11.00\n')
@ -107,15 +131,7 @@ class Vs2010Backend(backends.Backend):
for p in projlist:
prj_line = prj_templ % (self.environment.coredata.guid, p[0], p[1], p[2])
ofile.write(prj_line)
all_deps = {}
for ldep in self.build.targets[p[0]].link_targets:
all_deps[ldep.get_id()] = True
for objdep in self.get_obj_target_deps(self.build.targets[p[0]].objects):
all_deps[objdep] = True
for gendep in self.build.targets[p[0]].generated:
gen_exe = gendep.generator.get_exe()
if isinstance(gen_exe, build.Executable):
all_deps[gen_exe.get_id()] = True
all_deps = self.determine_deps(p)
ofile.write('\tProjectSection(ProjectDependencies) = postProject\n')
regen_guid = self.environment.coredata.regen_guid
ofile.write('\t\t{%s} = {%s}\n' % (regen_guid, regen_guid))
@ -191,9 +207,57 @@ class Vs2010Backend(backends.Backend):
return ['"%s"' % i for i in arr]
def gen_custom_target_vcxproj(self, target, ofname, guid):
raise NotImplementedError('Custom target not implemented yet. Sorry.')
buildtype = self.environment.coredata.buildtype
platform = "Win32"
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' : '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 = target.name
action = ET.SubElement(root, 'ItemDefinitionGroup')
customstep = ET.SubElement(action, 'CustomBuildStep')
(srcs, ofilenames, cmd) = self.eval_custom_target_command(target)
cmd_templ = '''"%s" '''*len(cmd)
ET.SubElement(customstep, 'Command').text = cmd_templ % tuple(cmd)
ET.SubElement(customstep, 'Outputs').text = ';'.join([os.path.join(self.environment.get_build_dir(), i)\
for i in ofilenames])
ET.SubElement(customstep, 'Inputs').text = ';'.join([os.path.join(self.environment.get_build_dir(), i) \
for i in srcs])
ET.SubElement(root, 'Import', Project='$(VCTargetsPath)\Microsoft.Cpp.targets')
tree = ET.ElementTree(root)
tree.write(ofname, encoding='utf-8', xml_declaration=True)
def gen_vcxproj(self, target, ofname, guid, compiler):
mlog.debug('Generating vcxproj %s.' % target.name)
entrypoint = 'WinMainCRTStartup'
subsystem = 'Windows'
if isinstance(target, build.Executable):
@ -207,7 +271,7 @@ class Vs2010Backend(backends.Backend):
conftype = 'DynamicLibrary'
entrypoint = '_DllMainCrtStartup'
elif isinstance(target, build.CustomTarget):
self.gen_custom_target_vcxproj(target, ofname, guid)
return self.gen_custom_target_vcxproj(target, ofname, guid)
else:
raise MesonException('Unknown target type for %s' % target.get_basename())
down = self.target_to_build_root(target)

Loading…
Cancel
Save