s3:rpc_server: Initialize array
[Samba.git] / third_party / waf / waflib / extras / codelite.py
blob523302c05cfefae3e7f6b14d37ae450203a49086
1 #! /usr/bin/env python
2 # encoding: utf-8
3 # CodeLite Project
4 # Christian Klein (chrikle@berlios.de)
5 # Created: Jan 2012
6 # As templete for this file I used the msvs.py
7 # I hope this template will work proper
9 """
10 Redistribution and use in source and binary forms, with or without
11 modification, are permitted provided that the following conditions
12 are met:
14 1. Redistributions of source code must retain the above copyright
15 notice, this list of conditions and the following disclaimer.
17 2. Redistributions in binary form must reproduce the above copyright
18 notice, this list of conditions and the following disclaimer in the
19 documentation and/or other materials provided with the distribution.
21 3. The name of the author may not be used to endorse or promote products
22 derived from this software without specific prior written permission.
24 THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
25 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
28 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
33 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 POSSIBILITY OF SUCH DAMAGE.
35 """
37 """
40 To add this tool to your project:
41 def options(conf):
42 opt.load('codelite')
44 It can be a good idea to add the sync_exec tool too.
46 To generate solution files:
47 $ waf configure codelite
49 To customize the outputs, provide subclasses in your wscript files:
51 from waflib.extras import codelite
52 class vsnode_target(codelite.vsnode_target):
53 def get_build_command(self, props):
54 # likely to be required
55 return "waf.bat build"
56 def collect_source(self):
57 # likely to be required
58 ...
59 class codelite_bar(codelite.codelite_generator):
60 def init(self):
61 codelite.codelite_generator.init(self)
62 self.vsnode_target = vsnode_target
64 The codelite class re-uses the same build() function for reading the targets (task generators),
65 you may therefore specify codelite settings on the context object:
67 def build(bld):
68 bld.codelite_solution_name = 'foo.workspace'
69 bld.waf_command = 'waf.bat'
70 bld.projects_dir = bld.srcnode.make_node('')
71 bld.projects_dir.mkdir()
74 ASSUMPTIONS:
75 * a project can be either a directory or a target, project files are written only for targets that have source files
76 * each project is a vcxproj file, therefore the project uuid needs only to be a hash of the absolute path
77 """
79 import os, re, sys
80 import uuid # requires python 2.5
81 from waflib.Build import BuildContext
82 from waflib import Utils, TaskGen, Logs, Task, Context, Node, Options
84 HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)'
86 PROJECT_TEMPLATE = r'''<?xml version="1.0" encoding="utf-8"?>
87 <CodeLite_Project Name="${project.name}" InternalType="Library">
88 <Plugins>
89 <Plugin Name="qmake">
90 <![CDATA[00010001N0005Release000000000000]]>
91 </Plugin>
92 </Plugins>
93 <Description/>
94 <Dependencies/>
95 <VirtualDirectory Name="src">
96 ${for x in project.source}
97 ${if (project.get_key(x)=="sourcefile")}
98 <File Name="${x.abspath()}"/>
99 ${endif}
100 ${endfor}
101 </VirtualDirectory>
102 <VirtualDirectory Name="include">
103 ${for x in project.source}
104 ${if (project.get_key(x)=="headerfile")}
105 <File Name="${x.abspath()}"/>
106 ${endif}
107 ${endfor}
108 </VirtualDirectory>
109 <Settings Type="Dynamic Library">
110 <GlobalSettings>
111 <Compiler Options="" C_Options="">
112 <IncludePath Value="."/>
113 </Compiler>
114 <Linker Options="">
115 <LibraryPath Value="."/>
116 </Linker>
117 <ResourceCompiler Options=""/>
118 </GlobalSettings>
119 <Configuration Name="Release" CompilerType="gnu gcc" ReleasegerType="GNU gdb Releaseger" Type="Dynamic Library" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
120 <Compiler Options="" C_Options="" Required="yes" PreCompiledHeader="" PCHInCommandLine="no" UseDifferentPCHFlags="no" PCHFlags="">
121 <IncludePath Value="."/>
122 <IncludePath Value="."/>
123 </Compiler>
124 <Linker Options="" Required="yes">
125 <LibraryPath Value=""/>
126 </Linker>
127 <ResourceCompiler Options="" Required="no"/>
128 <General OutputFile="${xml:project.build_properties[0].output_file}" IntermediateDirectory="" Command="" CommandArguments="" PauseExecWhenProcTerminates="yes"/>
129 <Environment EnvVarSetName="&lt;Use Defaults&gt;" DbgSetName="&lt;Use Defaults&gt;">
130 <![CDATA[]]>
131 </Environment>
132 <Releaseger IsRemote="no" RemoteHostName="" RemoteHostPort="" ReleasegerPath="">
133 <PostConnectCommands/>
134 <StartupCommands/>
135 </Releaseger>
136 <PreBuild/>
137 <PostBuild/>
138 <CustomBuild Enabled="yes">
139 $b = project.build_properties[0]}
140 <RebuildCommand>${xml:project.get_rebuild_command(project.build_properties[0])}</RebuildCommand>
141 <CleanCommand>${xml:project.get_clean_command(project.build_properties[0])}</CleanCommand>
142 <BuildCommand>${xml:project.get_build_command(project.build_properties[0])}</BuildCommand>
143 <Target Name="Install">${xml:project.get_install_command(project.build_properties[0])}</Target>
144 <Target Name="Build and Install">${xml:project.get_build_and_install_command(project.build_properties[0])}</Target>
145 <Target Name="Build All">${xml:project.get_build_all_command(project.build_properties[0])}</Target>
146 <Target Name="Rebuild All">${xml:project.get_rebuild_all_command(project.build_properties[0])}</Target>
147 <Target Name="Clean All">${xml:project.get_clean_all_command(project.build_properties[0])}</Target>
148 <Target Name="Build and Install All">${xml:project.get_build_and_install_all_command(project.build_properties[0])}</Target>
149 <PreprocessFileCommand/>
150 <SingleFileCommand/>
151 <MakefileGenerationCommand/>
152 <ThirdPartyToolName>None</ThirdPartyToolName>
153 <WorkingDirectory/>
154 </CustomBuild>
155 <AdditionalRules>
156 <CustomPostBuild/>
157 <CustomPreBuild/>
158 </AdditionalRules>
159 <Completion>
160 <ClangCmpFlags/>
161 <ClangPP/>
162 <SearchPaths/>
163 </Completion>
164 </Configuration>
165 <Configuration Name="Release" CompilerType="gnu gcc" ReleasegerType="GNU gdb Releaseger" Type="" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
166 <Compiler Options="" C_Options="" Required="yes" PreCompiledHeader="" PCHInCommandLine="no" UseDifferentPCHFlags="no" PCHFlags="">
167 <IncludePath Value="."/>
168 </Compiler>
169 <Linker Options="" Required="yes"/>
170 <ResourceCompiler Options="" Required="no"/>
171 <General OutputFile="" IntermediateDirectory="./Release" Command="" CommandArguments="" UseSeparateReleaseArgs="no" ReleaseArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes"/>
172 <Environment EnvVarSetName="&lt;Use Defaults&gt;" DbgSetName="&lt;Use Defaults&gt;">
173 <![CDATA[
178 </Environment>
179 <Releaseger IsRemote="no" RemoteHostName="" RemoteHostPort="" ReleasegerPath="">
180 <PostConnectCommands/>
181 <StartupCommands/>
182 </Releaseger>
183 <PreBuild/>
184 <PostBuild/>
185 <CustomBuild Enabled="no">
186 <RebuildCommand/>
187 <CleanCommand/>
188 <BuildCommand/>
189 <PreprocessFileCommand/>
190 <SingleFileCommand/>
191 <MakefileGenerationCommand/>
192 <ThirdPartyToolName/>
193 <WorkingDirectory/>
194 </CustomBuild>
195 <AdditionalRules>
196 <CustomPostBuild/>
197 <CustomPreBuild/>
198 </AdditionalRules>
199 <Completion>
200 <ClangCmpFlags/>
201 <ClangPP/>
202 <SearchPaths/>
203 </Completion>
204 </Configuration>
205 </Settings>
206 </CodeLite_Project>'''
211 SOLUTION_TEMPLATE = '''<?xml version="1.0" encoding="utf-8"?>
212 <CodeLite_Workspace Name="${getattr(project, 'codelite_solution_name', None)[:-10]}" Database="./${getattr(project, 'codelite_solution_name', None)[:-10]}.tags">
213 ${for p in project.all_projects}
214 <Project Name = "${p.name}" Path = "${p.title}" Active="No"/>
215 ${endfor}
216 <BuildMatrix>
217 <WorkspaceConfiguration Name="Release" Selected="yes">
218 ${for p in project.all_projects}
219 <Project Name="${p.name}" ConfigName="Release"/>
220 ${endfor}
221 </WorkspaceConfiguration>
222 </BuildMatrix>
223 </CodeLite_Workspace>'''
227 COMPILE_TEMPLATE = '''def f(project):
228 lst = []
229 def xml_escape(value):
230 return value.replace("&", "&amp;").replace('"', "&quot;").replace("'", "&apos;").replace("<", "&lt;").replace(">", "&gt;")
234 #f = open('cmd.txt', 'w')
235 #f.write(str(lst))
236 #f.close()
237 return ''.join(lst)
239 reg_act = re.compile(r"(?P<backslash>\\)|(?P<dollar>\$\$)|(?P<subst>\$\{(?P<code>[^}]*?)\})", re.M)
240 def compile_template(line):
242 Compile a template expression into a python function (like jsps, but way shorter)
244 extr = []
245 def repl(match):
246 g = match.group
247 if g('dollar'):
248 return "$"
249 elif g('backslash'):
250 return "\\"
251 elif g('subst'):
252 extr.append(g('code'))
253 return "<<|@|>>"
254 return None
256 line2 = reg_act.sub(repl, line)
257 params = line2.split('<<|@|>>')
258 assert(extr)
261 indent = 0
262 buf = []
263 app = buf.append
265 def app(txt):
266 buf.append(indent * '\t' + txt)
268 for x in range(len(extr)):
269 if params[x]:
270 app("lst.append(%r)" % params[x])
272 f = extr[x]
273 if f.startswith(('if', 'for')):
274 app(f + ':')
275 indent += 1
276 elif f.startswith('py:'):
277 app(f[3:])
278 elif f.startswith(('endif', 'endfor')):
279 indent -= 1
280 elif f.startswith(('else', 'elif')):
281 indent -= 1
282 app(f + ':')
283 indent += 1
284 elif f.startswith('xml:'):
285 app('lst.append(xml_escape(%s))' % f[4:])
286 else:
287 #app('lst.append((%s) or "cannot find %s")' % (f, f))
288 app('lst.append(%s)' % f)
290 if extr:
291 if params[-1]:
292 app("lst.append(%r)" % params[-1])
294 fun = COMPILE_TEMPLATE % "\n\t".join(buf)
295 #print(fun)
296 return Task.funex(fun)
299 re_blank = re.compile('(\n|\r|\\s)*\n', re.M)
300 def rm_blank_lines(txt):
301 txt = re_blank.sub('\r\n', txt)
302 return txt
304 BOM = '\xef\xbb\xbf'
305 try:
306 BOM = bytes(BOM, 'latin-1') # python 3
307 except (TypeError, NameError):
308 pass
310 def stealth_write(self, data, flags='wb'):
311 try:
312 unicode
313 except NameError:
314 data = data.encode('utf-8') # python 3
315 else:
316 data = data.decode(sys.getfilesystemencoding(), 'replace')
317 data = data.encode('utf-8')
319 if self.name.endswith('.project'):
320 data = BOM + data
322 try:
323 txt = self.read(flags='rb')
324 if txt != data:
325 raise ValueError('must write')
326 except (IOError, ValueError):
327 self.write(data, flags=flags)
328 else:
329 Logs.debug('codelite: skipping %r', self)
330 Node.Node.stealth_write = stealth_write
332 re_quote = re.compile("[^a-zA-Z0-9-]")
333 def quote(s):
334 return re_quote.sub("_", s)
336 def xml_escape(value):
337 return value.replace("&", "&amp;").replace('"', "&quot;").replace("'", "&apos;").replace("<", "&lt;").replace(">", "&gt;")
339 def make_uuid(v, prefix = None):
341 simple utility function
343 if isinstance(v, dict):
344 keys = list(v.keys())
345 keys.sort()
346 tmp = str([(k, v[k]) for k in keys])
347 else:
348 tmp = str(v)
349 d = Utils.md5(tmp.encode()).hexdigest().upper()
350 if prefix:
351 d = '%s%s' % (prefix, d[8:])
352 gid = uuid.UUID(d, version = 4)
353 return str(gid).upper()
355 def diff(node, fromnode):
356 # difference between two nodes, but with "(..)" instead of ".."
357 c1 = node
358 c2 = fromnode
360 c1h = c1.height()
361 c2h = c2.height()
363 lst = []
364 up = 0
366 while c1h > c2h:
367 lst.append(c1.name)
368 c1 = c1.parent
369 c1h -= 1
371 while c2h > c1h:
372 up += 1
373 c2 = c2.parent
374 c2h -= 1
376 while id(c1) != id(c2):
377 lst.append(c1.name)
378 up += 1
380 c1 = c1.parent
381 c2 = c2.parent
383 for i in range(up):
384 lst.append('(..)')
385 lst.reverse()
386 return tuple(lst)
388 class build_property(object):
389 pass
391 class vsnode(object):
393 Abstract class representing visual studio elements
394 We assume that all visual studio nodes have a uuid and a parent
396 def __init__(self, ctx):
397 self.ctx = ctx # codelite context
398 self.name = '' # string, mandatory
399 self.vspath = '' # path in visual studio (name for dirs, absolute path for projects)
400 self.uuid = '' # string, mandatory
401 self.parent = None # parent node for visual studio nesting
403 def get_waf(self):
405 Override in subclasses...
407 return '%s/%s' % (self.ctx.srcnode.abspath(), getattr(self.ctx, 'waf_command', 'waf'))
409 def ptype(self):
411 Return a special uuid for projects written in the solution file
413 pass
415 def write(self):
417 Write the project file, by default, do nothing
419 pass
421 def make_uuid(self, val):
423 Alias for creating uuid values easily (the templates cannot access global variables)
425 return make_uuid(val)
427 class vsnode_vsdir(vsnode):
429 Nodes representing visual studio folders (which do not match the filesystem tree!)
431 VS_GUID_SOLUTIONFOLDER = "2150E333-8FDC-42A3-9474-1A3956D46DE8"
432 def __init__(self, ctx, uuid, name, vspath=''):
433 vsnode.__init__(self, ctx)
434 self.title = self.name = name
435 self.uuid = uuid
436 self.vspath = vspath or name
438 def ptype(self):
439 return self.VS_GUID_SOLUTIONFOLDER
441 class vsnode_project(vsnode):
443 Abstract class representing visual studio project elements
444 A project is assumed to be writable, and has a node representing the file to write to
446 VS_GUID_VCPROJ = "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942"
447 def ptype(self):
448 return self.VS_GUID_VCPROJ
450 def __init__(self, ctx, node):
451 vsnode.__init__(self, ctx)
452 self.path = node
453 self.uuid = make_uuid(node.abspath())
454 self.name = node.name
455 self.title = self.path.abspath()
456 self.source = [] # list of node objects
457 self.build_properties = [] # list of properties (nmake commands, output dir, etc)
459 def dirs(self):
461 Get the list of parent folders of the source files (header files included)
462 for writing the filters
464 lst = []
465 def add(x):
466 if x.height() > self.tg.path.height() and x not in lst:
467 lst.append(x)
468 add(x.parent)
469 for x in self.source:
470 add(x.parent)
471 return lst
473 def write(self):
474 Logs.debug('codelite: creating %r', self.path)
475 #print "self.name:",self.name
477 # first write the project file
478 template1 = compile_template(PROJECT_TEMPLATE)
479 proj_str = template1(self)
480 proj_str = rm_blank_lines(proj_str)
481 self.path.stealth_write(proj_str)
483 # then write the filter
484 #template2 = compile_template(FILTER_TEMPLATE)
485 #filter_str = template2(self)
486 #filter_str = rm_blank_lines(filter_str)
487 #tmp = self.path.parent.make_node(self.path.name + '.filters')
488 #tmp.stealth_write(filter_str)
490 def get_key(self, node):
492 required for writing the source files
494 name = node.name
495 if name.endswith(('.cpp', '.c')):
496 return 'sourcefile'
497 return 'headerfile'
499 def collect_properties(self):
501 Returns a list of triplet (configuration, platform, output_directory)
503 ret = []
504 for c in self.ctx.configurations:
505 for p in self.ctx.platforms:
506 x = build_property()
507 x.outdir = ''
509 x.configuration = c
510 x.platform = p
512 x.preprocessor_definitions = ''
513 x.includes_search_path = ''
515 # can specify "deploy_dir" too
516 ret.append(x)
517 self.build_properties = ret
519 def get_build_params(self, props):
520 opt = ''
521 return (self.get_waf(), opt)
523 def get_build_command(self, props):
524 return "%s build %s" % self.get_build_params(props)
526 def get_clean_command(self, props):
527 return "%s clean %s" % self.get_build_params(props)
529 def get_rebuild_command(self, props):
530 return "%s clean build %s" % self.get_build_params(props)
532 def get_install_command(self, props):
533 return "%s install %s" % self.get_build_params(props)
534 def get_build_and_install_command(self, props):
535 return "%s build install %s" % self.get_build_params(props)
537 def get_build_and_install_all_command(self, props):
538 return "%s build install" % self.get_build_params(props)[0]
540 def get_clean_all_command(self, props):
541 return "%s clean" % self.get_build_params(props)[0]
543 def get_build_all_command(self, props):
544 return "%s build" % self.get_build_params(props)[0]
546 def get_rebuild_all_command(self, props):
547 return "%s clean build" % self.get_build_params(props)[0]
549 def get_filter_name(self, node):
550 lst = diff(node, self.tg.path)
551 return '\\'.join(lst) or '.'
553 class vsnode_alias(vsnode_project):
554 def __init__(self, ctx, node, name):
555 vsnode_project.__init__(self, ctx, node)
556 self.name = name
557 self.output_file = ''
559 class vsnode_build_all(vsnode_alias):
561 Fake target used to emulate the behaviour of "make all" (starting one process by target is slow)
562 This is the only alias enabled by default
564 def __init__(self, ctx, node, name='build_all_projects'):
565 vsnode_alias.__init__(self, ctx, node, name)
566 self.is_active = True
568 class vsnode_install_all(vsnode_alias):
570 Fake target used to emulate the behaviour of "make install"
572 def __init__(self, ctx, node, name='install_all_projects'):
573 vsnode_alias.__init__(self, ctx, node, name)
575 def get_build_command(self, props):
576 return "%s build install %s" % self.get_build_params(props)
578 def get_clean_command(self, props):
579 return "%s clean %s" % self.get_build_params(props)
581 def get_rebuild_command(self, props):
582 return "%s clean build install %s" % self.get_build_params(props)
584 class vsnode_project_view(vsnode_alias):
586 Fake target used to emulate a file system view
588 def __init__(self, ctx, node, name='project_view'):
589 vsnode_alias.__init__(self, ctx, node, name)
590 self.tg = self.ctx() # fake one, cannot remove
591 self.exclude_files = Node.exclude_regs + '''
592 waf-2*
593 waf3-2*/**
594 .waf-2*
595 .waf3-2*/**
596 **/*.sdf
597 **/*.suo
598 **/*.ncb
599 **/%s
600 ''' % Options.lockfile
602 def collect_source(self):
603 # this is likely to be slow
604 self.source = self.ctx.srcnode.ant_glob('**', excl=self.exclude_files)
606 def get_build_command(self, props):
607 params = self.get_build_params(props) + (self.ctx.cmd,)
608 return "%s %s %s" % params
610 def get_clean_command(self, props):
611 return ""
613 def get_rebuild_command(self, props):
614 return self.get_build_command(props)
616 class vsnode_target(vsnode_project):
618 CodeLite project representing a targets (programs, libraries, etc) and bound
619 to a task generator
621 def __init__(self, ctx, tg):
623 A project is more or less equivalent to a file/folder
625 base = getattr(ctx, 'projects_dir', None) or tg.path
626 node = base.make_node(quote(tg.name) + ctx.project_extension) # the project file as a Node
627 vsnode_project.__init__(self, ctx, node)
628 self.name = quote(tg.name)
629 self.tg = tg # task generator
631 def get_build_params(self, props):
633 Override the default to add the target name
635 opt = ''
636 if getattr(self, 'tg', None):
637 opt += " --targets=%s" % self.tg.name
638 return (self.get_waf(), opt)
640 def collect_source(self):
641 tg = self.tg
642 source_files = tg.to_nodes(getattr(tg, 'source', []))
643 include_dirs = Utils.to_list(getattr(tg, 'codelite_includes', []))
644 include_files = []
645 for x in include_dirs:
646 if isinstance(x, str):
647 x = tg.path.find_node(x)
648 if x:
649 lst = [y for y in x.ant_glob(HEADERS_GLOB, flat=False)]
650 include_files.extend(lst)
652 # remove duplicates
653 self.source.extend(list(set(source_files + include_files)))
654 self.source.sort(key=lambda x: x.abspath())
656 def collect_properties(self):
658 CodeLite projects are associated with platforms and configurations (for building especially)
660 super(vsnode_target, self).collect_properties()
661 for x in self.build_properties:
662 x.outdir = self.path.parent.abspath()
663 x.preprocessor_definitions = ''
664 x.includes_search_path = ''
666 try:
667 tsk = self.tg.link_task
668 except AttributeError:
669 pass
670 else:
671 x.output_file = tsk.outputs[0].abspath()
672 x.preprocessor_definitions = ';'.join(tsk.env.DEFINES)
673 x.includes_search_path = ';'.join(self.tg.env.INCPATHS)
675 class codelite_generator(BuildContext):
676 '''generates a CodeLite workspace'''
677 cmd = 'codelite'
678 fun = 'build'
680 def init(self):
682 Some data that needs to be present
684 if not getattr(self, 'configurations', None):
685 self.configurations = ['Release'] # LocalRelease, RemoteDebug, etc
686 if not getattr(self, 'platforms', None):
687 self.platforms = ['Win32']
688 if not getattr(self, 'all_projects', None):
689 self.all_projects = []
690 if not getattr(self, 'project_extension', None):
691 self.project_extension = '.project'
692 if not getattr(self, 'projects_dir', None):
693 self.projects_dir = self.srcnode.make_node('')
694 self.projects_dir.mkdir()
696 # bind the classes to the object, so that subclass can provide custom generators
697 if not getattr(self, 'vsnode_vsdir', None):
698 self.vsnode_vsdir = vsnode_vsdir
699 if not getattr(self, 'vsnode_target', None):
700 self.vsnode_target = vsnode_target
701 if not getattr(self, 'vsnode_build_all', None):
702 self.vsnode_build_all = vsnode_build_all
703 if not getattr(self, 'vsnode_install_all', None):
704 self.vsnode_install_all = vsnode_install_all
705 if not getattr(self, 'vsnode_project_view', None):
706 self.vsnode_project_view = vsnode_project_view
708 self.numver = '11.00'
709 self.vsver = '2010'
711 def execute(self):
713 Entry point
715 self.restore()
716 if not self.all_envs:
717 self.load_envs()
718 self.recurse([self.run_dir])
720 # user initialization
721 self.init()
723 # two phases for creating the solution
724 self.collect_projects() # add project objects into "self.all_projects"
725 self.write_files() # write the corresponding project and solution files
727 def collect_projects(self):
729 Fill the list self.all_projects with project objects
730 Fill the list of build targets
732 self.collect_targets()
733 #self.add_aliases()
734 #self.collect_dirs()
735 default_project = getattr(self, 'default_project', None)
736 def sortfun(x):
737 if x.name == default_project:
738 return ''
739 return getattr(x, 'path', None) and x.path.abspath() or x.name
740 self.all_projects.sort(key=sortfun)
742 def write_files(self):
744 Write the project and solution files from the data collected
745 so far. It is unlikely that you will want to change this
747 for p in self.all_projects:
748 p.write()
750 # and finally write the solution file
751 node = self.get_solution_node()
752 node.parent.mkdir()
753 Logs.warn('Creating %r', node)
754 #a = dir(self.root)
755 #for b in a:
756 # print b
757 #print self.group_names
758 #print "Hallo2: ",self.root.listdir()
759 #print getattr(self, 'codelite_solution_name', None)
760 template1 = compile_template(SOLUTION_TEMPLATE)
761 sln_str = template1(self)
762 sln_str = rm_blank_lines(sln_str)
763 node.stealth_write(sln_str)
765 def get_solution_node(self):
767 The solution filename is required when writing the .vcproj files
768 return self.solution_node and if it does not exist, make one
770 try:
771 return self.solution_node
772 except:
773 pass
775 codelite_solution_name = getattr(self, 'codelite_solution_name', None)
776 if not codelite_solution_name:
777 codelite_solution_name = getattr(Context.g_module, Context.APPNAME, 'project') + '.workspace'
778 setattr(self, 'codelite_solution_name', codelite_solution_name)
779 if os.path.isabs(codelite_solution_name):
780 self.solution_node = self.root.make_node(codelite_solution_name)
781 else:
782 self.solution_node = self.srcnode.make_node(codelite_solution_name)
783 return self.solution_node
785 def project_configurations(self):
787 Helper that returns all the pairs (config,platform)
789 ret = []
790 for c in self.configurations:
791 for p in self.platforms:
792 ret.append((c, p))
793 return ret
795 def collect_targets(self):
797 Process the list of task generators
799 for g in self.groups:
800 for tg in g:
801 if not isinstance(tg, TaskGen.task_gen):
802 continue
804 if not hasattr(tg, 'codelite_includes'):
805 tg.codelite_includes = tg.to_list(getattr(tg, 'includes', [])) + tg.to_list(getattr(tg, 'export_includes', []))
806 tg.post()
807 if not getattr(tg, 'link_task', None):
808 continue
810 p = self.vsnode_target(self, tg)
811 p.collect_source() # delegate this processing
812 p.collect_properties()
813 self.all_projects.append(p)
815 def add_aliases(self):
817 Add a specific target that emulates the "make all" necessary for Visual studio when pressing F7
818 We also add an alias for "make install" (disabled by default)
820 base = getattr(self, 'projects_dir', None) or self.tg.path
822 node_project = base.make_node('build_all_projects' + self.project_extension) # Node
823 p_build = self.vsnode_build_all(self, node_project)
824 p_build.collect_properties()
825 self.all_projects.append(p_build)
827 node_project = base.make_node('install_all_projects' + self.project_extension) # Node
828 p_install = self.vsnode_install_all(self, node_project)
829 p_install.collect_properties()
830 self.all_projects.append(p_install)
832 node_project = base.make_node('project_view' + self.project_extension) # Node
833 p_view = self.vsnode_project_view(self, node_project)
834 p_view.collect_source()
835 p_view.collect_properties()
836 self.all_projects.append(p_view)
838 n = self.vsnode_vsdir(self, make_uuid(self.srcnode.abspath() + 'build_aliases'), "build_aliases")
839 p_build.parent = p_install.parent = p_view.parent = n
840 self.all_projects.append(n)
842 def collect_dirs(self):
844 Create the folder structure in the CodeLite project view
846 seen = {}
847 def make_parents(proj):
848 # look at a project, try to make a parent
849 if getattr(proj, 'parent', None):
850 # aliases already have parents
851 return
852 x = proj.iter_path
853 if x in seen:
854 proj.parent = seen[x]
855 return
857 # There is not vsnode_vsdir for x.
858 # So create a project representing the folder "x"
859 n = proj.parent = seen[x] = self.vsnode_vsdir(self, make_uuid(x.abspath()), x.name)
860 n.iter_path = x.parent
861 self.all_projects.append(n)
863 # recurse up to the project directory
864 if x.height() > self.srcnode.height() + 1:
865 make_parents(n)
867 for p in self.all_projects[:]: # iterate over a copy of all projects
868 if not getattr(p, 'tg', None):
869 # but only projects that have a task generator
870 continue
872 # make a folder for each task generator
873 p.iter_path = p.tg.path
874 make_parents(p)