Fix some build problems
[senf.git] / senfscons / InstallIncludes.py
1 ## \file
2 # \brief InstallIncludes builder
3
4 ## \package senfscons.InstallIncludes
5 # \brief Install all include files which some targets depend upon
6 #
7 # \ingroup builder
8
9 import SCons.Builder, SCons.Action, SCons.Environment, SCons.Node.FS
10 try:
11     from SCons.Tool.install import installFunc, stringFunc
12 except:
13     installFunc = SCons.Environment.installFunc
14     stringFunc = SCons.Environment.installString
15
16 def recursiveChildren(f):
17     rv = {}
18     map(rv.setdefault,f)    
19     for c in f:
20         if c is not None : map(rv.setdefault,recursiveChildren(c.children()))
21     return rv.keys()
22
23 def filterIncludes(files, extensions):
24     return [ f for f in files
25              if f is not None and f.get_suffix() in extensions ]
26
27 def filterIncludesInv(files, extensions):
28     return [ f for f in files
29              if f is not None and  '.' + str(f).split('.',1)[-1] not in extensions ]
30
31 def filterDirectory(files, dir):
32     return [ f for f in files
33              if f is not None and f.abspath.startswith(dir.abspath) ]
34
35 def excludeDirectories(files, dirs):
36     return [ f for f in files
37              if not [ True for d in dirs if files.abspath.startswith(dirs.abspath) ] ]
38
39 def emitter(target, source, env):
40     source = recursiveChildren(source)
41     source = filterIncludes(source, env['CPP_INCLUDE_EXTENSIONS'])
42     source = filterIncludesInv(source, env['CPP_EXCLUDE_EXTENSIONS'])
43     source = filterDirectory(source, env['INSTALL_BASE'])
44     source = excludeDirectories(source, env['INCLUDE_IGNORED_DIRECTORIES'])
45
46     # Build target file by appending the path of 'src' relative to INSTALL_BASE to target[0]
47     target = [ target[0].File(src.get_path(env.Dir(env['INSTALL_BASE'])))
48                for src in source ]
49
50     return (target, source)
51
52 class Installer:
53     def __init__(self, target, source):
54         self.target = target;
55         self.source = source
56
57     def __call__(self, target, source, env):
58         installFunc([self.target], [self.source], env)
59
60 def generator(target, source, env, for_signature):
61     return [ SCons.Action.Action( Installer(trg, src),
62                                   lambda a,b,c,s=stringFunc([trg], [src], env):s )
63              for trg, src in zip(target,source) ]
64
65 InstallIncludes = SCons.Builder.Builder(emitter = emitter,
66                                         generator = generator,
67                                         source_factory = SCons.Node.FS.Entry,
68                                         target_factory = SCons.Node.FS.Dir,
69                                         name = 'InstallIncludesBuilder',
70                                         )
71
72 def generate(env):
73     env['BUILDERS']['InstallIncludes'] = InstallIncludes
74     env['INSTALL_BASE'] = '#'
75     env['INCLUDE_IGNORED_DIRECTORIES'] = []
76
77 def exists(env):
78     return 1