Include waf as an extracted source directory, rather than as a one-in-a-file script.
[ira/wip.git] / buildtools / wafadmin / Tools / cxx.py
1 #!/usr/bin/env python
2 # encoding: utf-8
3 # Thomas Nagy, 2005 (ita)
4
5 "Base for c++ programs and libraries"
6
7 import TaskGen, Task, Utils
8 from Logs import debug
9 import ccroot # <- do not remove
10 from TaskGen import feature, before, extension, after
11
12 g_cxx_flag_vars = [
13 'CXXDEPS', 'FRAMEWORK', 'FRAMEWORKPATH',
14 'STATICLIB', 'LIB', 'LIBPATH', 'LINKFLAGS', 'RPATH',
15 'CXXFLAGS', 'CCFLAGS', 'CPPPATH', 'CPPFLAGS', 'CXXDEFINES']
16 "main cpp variables"
17
18 EXT_CXX = ['.cpp', '.cc', '.cxx', '.C', '.c++']
19
20 g_cxx_type_vars=['CXXFLAGS', 'LINKFLAGS']
21
22 # TODO remove in waf 1.6
23 class cxx_taskgen(ccroot.ccroot_abstract):
24         pass
25
26 @feature('cxx')
27 @before('apply_type_vars')
28 @after('default_cc')
29 def init_cxx(self):
30         if not 'cc' in self.features:
31                 self.mappings['.c'] = TaskGen.task_gen.mappings['.cxx']
32
33         self.p_flag_vars = set(self.p_flag_vars).union(g_cxx_flag_vars)
34         self.p_type_vars = set(self.p_type_vars).union(g_cxx_type_vars)
35
36         if not self.env['CXX_NAME']:
37                 raise Utils.WafError("At least one compiler (g++, ..) must be selected")
38
39 @feature('cxx')
40 @after('apply_incpaths')
41 def apply_obj_vars_cxx(self):
42         """after apply_incpaths for INC_PATHS"""
43         env = self.env
44         app = env.append_unique
45         cxxpath_st = env['CPPPATH_ST']
46
47         # local flags come first
48         # set the user-defined includes paths
49         for i in env['INC_PATHS']:
50                 app('_CXXINCFLAGS', cxxpath_st % i.bldpath(env))
51                 app('_CXXINCFLAGS', cxxpath_st % i.srcpath(env))
52
53         # set the library include paths
54         for i in env['CPPPATH']:
55                 app('_CXXINCFLAGS', cxxpath_st % i)
56
57 @feature('cxx')
58 @after('apply_lib_vars')
59 def apply_defines_cxx(self):
60         """after uselib is set for CXXDEFINES"""
61         self.defines = getattr(self, 'defines', [])
62         lst = self.to_list(self.defines) + self.to_list(self.env['CXXDEFINES'])
63         milst = []
64
65         # now process the local defines
66         for defi in lst:
67                 if not defi in milst:
68                         milst.append(defi)
69
70         # CXXDEFINES_USELIB
71         libs = self.to_list(self.uselib)
72         for l in libs:
73                 val = self.env['CXXDEFINES_'+l]
74                 if val: milst += self.to_list(val)
75
76         self.env['DEFLINES'] = ["%s %s" % (x[0], Utils.trimquotes('='.join(x[1:]))) for x in [y.split('=') for y in milst]]
77         y = self.env['CXXDEFINES_ST']
78         self.env.append_unique('_CXXDEFFLAGS', [y%x for x in milst])
79
80 @extension(EXT_CXX)
81 def cxx_hook(self, node):
82         # create the compilation task: cpp or cc
83         if getattr(self, 'obj_ext', None):
84                 obj_ext = self.obj_ext
85         else:
86                 obj_ext = '_%d.o' % self.idx
87
88         task = self.create_task('cxx', node, node.change_ext(obj_ext))
89         try:
90                 self.compiled_tasks.append(task)
91         except AttributeError:
92                 raise Utils.WafError('Have you forgotten to set the feature "cxx" on %s?' % str(self))
93         return task
94
95 cxx_str = '${CXX} ${CXXFLAGS} ${CPPFLAGS} ${_CXXINCFLAGS} ${_CXXDEFFLAGS} ${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT}'
96 cls = Task.simple_task_type('cxx', cxx_str, color='GREEN', ext_out='.o', ext_in='.cxx', shell=False)
97 cls.scan = ccroot.scan
98 cls.vars.append('CXXDEPS')
99
100 link_str = '${LINK_CXX} ${CXXLNK_SRC_F}${SRC} ${CXXLNK_TGT_F}${TGT[0].abspath(env)} ${LINKFLAGS}'
101 cls = Task.simple_task_type('cxx_link', link_str, color='YELLOW', ext_in='.o', ext_out='.bin', shell=False)
102 cls.maxjobs = 1
103 cls.install = Utils.nada
104