Call CompileCheck builder from BoostUnitTest
[senf.git] / senfscons / SENFSCons.py
1 import os.path, glob
2 import SCons.Options, SCons.Environment, SCons.Script.SConscript, SCons.Node.FS
3 import SCons.Defaults, SCons.Action
4 from SCons.Script import *
5
6 def GlobSources(env, exclude=[], subdirs=[]):
7     testSources = glob.glob("*.test.cc")
8     sources = [ x for x in glob.glob("*.cc") if x not in testSources and x not in exclude ]
9     for subdir in subdirs:
10         testSources += glob.glob(os.path.join(subdir,"*.test.cc"))
11         sources += [ x for x in glob.glob(os.path.join(subdir,"*.cc"))
12                      if x not in testSources and x not in exclude ]
13     return (sources, testSources)
14
15 def GlobIncludes(env, exclude=[], subdirs=[]):
16     includes = []
17     for d in [ '.' ] + subdirs:
18         for f in os.listdir(d):
19             ext = '.' + f.split('.',1)[-1]
20             p = os.path.join(d,f)
21             if ext in env['CPP_INCLUDE_EXTENSIONS'] \
22                and ext not in env['CPP_EXCLUDE_EXTENSIONS'] \
23                and p not in exclude:
24                 includes.append(p)
25     return includes
26
27 def Glob(env, exclude=[], subdirs=[]):
28     return ( GlobSources(env, exclude, subdirs),
29              GlobIncludes(env, exclude, subdirs) )
30
31 def Test(env, sources):
32     test=env.BoostUnitTest( target = 'test', source = sources )
33     env.Alias('all_tests', test)
34     return test
35     
36 def Objects(env, sources, testSources = None):
37     if type(sources) == type(()):
38         testSources = sources[1]
39         sources = sources[0]
40     if type(sources) is not type([]):
41         sources = [ sources ]
42
43     objects = env.Object(sources)
44
45     if testSources:
46         Test(env, testSources)
47
48     return objects
49
50 def Doxygen(env, doxyfile = "Doxyfile", extra_sources = []):
51     # There is one small problem we need to solve with this builder: The Doxygen builder reads
52     # the Doxyfile and thus depends on the environment variables set by doclib/doxygen.sh. We
53     # thus have to provide all necessary definitions here manually via DOXYENV !
54
55     if type(doxyfile) is type(""):
56         doxyfile = env.File(doxyfile)
57
58     # Module name is derived from the doxyfile path
59     # Utils/Console/Doxyfile -> Utils_Console
60     module = doxyfile.dir.abspath[len(env.Dir('#').abspath)+1:].replace('/','_')
61     if not module : module = "Main"
62
63     # Rule to generate tagfile
64     # (need to exclude the 'clean' case, otherwise we'll have duplicate nodes)
65     if not env.GetOption('clean'):
66         tagfile = env.Doxygen(doxyfile,
67                               DOXYOPTS = [ '--tagfile-name', '"${MODULE}.tag"',
68                                            '--tagfile' ],
69                               DOXYENV  = { 'TOPDIR'          : env.Dir('#').abspath,
70                                            'output_dir'      : 'doc',
71                                            'html_dir'        : 'html',
72                                            'html'            : 'NO',
73                                            'generate_tagfile': 'doc/${MODULE}.tag' },
74                               MODULE   = module )
75         env.Append(ALL_TAGFILES = tagfile[0].abspath)
76         env.Depends(tagfile, env.File('#/doclib/doxygen.sh'))
77
78     # Rule to generate HTML documentation
79     doc = env.Doxygen(doxyfile,
80                       DOXYOPTS = [ '--tagfiles', '"$ALL_TAGFILES"',
81                                    '--tagfile-name', '"${MODULE}.tag"',
82                                    '--html' ],
83                       MODULE   = module,
84                       DOXYENV  = { 'TOPDIR'          : env.Dir('#').abspath,
85                                    'tagfiles'        : '${ALL_TAGFILES}',
86                                    'output_dir'      : 'doc',
87                                    'html_dir'        : 'html',
88                                    'html'            : 'YES' } )
89     env.Depends(doc, env.File('#/doclib/doxygen.sh'))
90
91     # Copy the extra_sources (the images) into the documentation directory
92     # (need to exclude the 'clean' case otherwise there are multiple ways to clean the copies)
93     if not env.GetOption('clean'):
94         if extra_sources:
95             env.Depends(doc,
96                         [ env.CopyToDir( source=source, target=doc[0].dir )
97                           for source in extra_sources ])
98
99     # Install documentation into DOCINSTALLDIR
100     l = len(env.Dir('#').abspath)
101     env.Alias('install_all',
102               env.Command('$DOCINSTALLDIR' + doc[0].dir.abspath[l:], doc[0].dir,
103                           [ SCons.Defaults.Copy('$TARGET','$SOURCE') ]))
104
105     # Useful aliases
106     env.Alias('all_docs', doc)
107     env.Clean('all_docs', doc)
108     env.Clean('all', doc)
109
110     return doc
111
112 def Lib(env, sources, testSources = None, OBJECTS = []):
113     objects = Objects(env,sources,testSources)
114     env.Append(ALLOBJECTS = objects)
115     return objects
116
117 def Object(env, target, sources, testSources = None, OBJECTS = []):
118     objects = Objects(env,sources,testSources)
119     ob = env.Command(target+"${OBJADDSUFFIX}${OBJSUFFIX}", objects+OBJECTS, 
120                      [ "ld -r -o $TARGET $SOURCES" ])
121     env.Default(ob)
122     env.Alias('default', ob)
123     env.Alias('install_all', env.Install("$OBJINSTALLDIR", ob))
124     return ob
125
126 def Binary(env, binary, sources, testSources = None, OBJECTS = []):
127     objects = Objects(env, sources, testSources)
128     program = env.Program(target = binary, 
129                           source = objects+OBJECTS,
130                           LIBS   = [ '$LIBSENF$LIBADDSUFFIX' ] + env['LIBS'])
131     env.Default(program)
132     env.Alias('default', program)
133     env.Alias('install_all', env.Install('$BININSTALLDIR', program))
134     return program
135
136 def AllIncludesHH(env, headers):
137     headers.sort()
138     target = env.File("all_includes.hh")
139     file(target.abspath,"w").write("".join([ '#include "%s"\n' % f
140                                              for f in headers ]))
141     env.Clean('all', target)
142
143 def PhonyTarget(env, target, action, sources=[]):
144     env.AlwaysBuild(env.Alias(target, sources, env.Action(action)))