Clone in a terminal:
"""bavala is a build-tool for Vala based on doit (http://pydoit.org)"""

import glob
from os.path import join

from doit.action import CmdAction


def cmd(name, *args):
    """create string for command line"""
    parts = [name]
    for item in args:
        if isinstance(item, basestring):
            parts.append(item)
        elif isinstance(item, dict):
            for param, value in item.iteritems():
                if isinstance(value, basestring):
                    value = [value]
                parts.extend('--{0} {1}'.format(param, v) for v in value)
        else:
            parts.extend(item)
    return ' '.join(parts)



class Vala(object):
    """helper to generate tasks to compile vala code"""

    def __init__(self, src, build, pkg_libs, library=None, vala_deps=None):
        self.src = src
        self.build = build
        self.library = library
        self.pkg_libs = pkg_libs
        self.vala_deps = vala_deps or []

        self.vala = list(glob.glob(src + '/*.vala'))
        self.c = list(glob.glob(src + '/*.c')) # copy regular c sources
        self.cc = [join(build, f) for f in self.c]
        self.cc += [join(build, f.replace('.vala', '.c')) for f in self.vala]
        self.obj = [f.replace('.c', '.o') for f in self.cc]
        self.obj += [join(build, f.replace('.vala', '.o')) for f in self.vala]
        
        if library:
            self.header = join(build, library) + '.h'
            self.vapi = join(build, library) + '.vapi'
            self.so = join(build, src) + '.so'


    def gen_c(self, opts):
        """translate code from vala to C and create .vapi"""
        options = ['--ccode', '--save-temps']
        options.extend(opts)
        params = {
            'basedir': join(self.build, self.src),
            'vapidir': './',
            'pkg': self.pkg_libs,
            }
        if self.library:
            params['library'] = self.library
            params['vapi'] = self.vapi
            params['header'] = self.header

        dep_vapi = [d.vapi for d in self.vala_deps]
        action = cmd('valac', options, params, dep_vapi, self.vala)
        targets = self.cc[:]
        if self.library:
            targets += [self.header, self.vapi]
        
        for f in self.c:
            yield {
                'name': 'copy_c',
                'actions': [ 
                    'mkdir -p '+  self.build + '/' + self.src + '/', 
                    'cp ' + f + ' ' + self.build + '/' + self.src + '/'
                    ],
                }
                                    
        yield {
            'name': 'compile_c',
            'actions': [ action ],
            'file_dep': self.vala + dep_vapi,
            'targets': targets,
            }


    def gen_o(self, opts):
        """compile C files to obj `.o` """
        def compile_cmd(conf, opts, libs, pos):
            flags = [conf[l].strip() for l in libs]
            return cmd('gcc', opts, flags, pos)

        for cc, obj in zip(self.cc, self.obj):
            pos = ["-c " + cc, "-o " + obj ]
            cmd_args = {'libs':self.pkg_libs, 'opts':opts, 'pos':pos}
            action = CmdAction((compile_cmd, [], cmd_args))
            yield {
                'name': obj.rsplit('/')[-1],
                'file_dep': [ cc ],
                'actions': [ action ],
                'getargs': { 'conf': ('pkg_flags', 'out') },
                'targets': [ obj ],
                }


    def gen_so(self):
        """generate ".so" lib file"""
        def compile_cmd(conf, libs):
            obj_glob = join(self.build, self.src, '*.o')
            opts = ['-shared ' + obj_glob,
                    '-o ' + self.so ]
            flags = [conf[l].strip() for l in libs]
            return cmd('gcc', opts, flags)

        return {
            'name': self.so.rsplit('/')[-1],
            'actions': [ CmdAction((compile_cmd, [], {'libs':self.pkg_libs})) ],
            'getargs': { 'conf': ('pkg_flags', 'out') },
            'file_dep': self.obj,
            'targets': [ self.so ],
            }


    def gen_bin(self, opts):
        """generate binary"""
        def compile_cmd(conf, opts, libs):
            flags = [conf[l].strip() for l in libs]
            return cmd('gcc', opts, flags)

        bin_path = join(self.build, 'bin')
        target = join(bin_path, self.src)
        opts = (self.cc + opts +
                ['-o ' + target, '-I ' + self.build, '-L ' + self.build] +
                ['-l ' + d.library for d in self.vala_deps])
        action = CmdAction((compile_cmd, [], {'opts':opts, 'libs':self.pkg_libs}))
        yield {
            'name': "bin",
            'actions': [ 'mkdir -p %s' % bin_path, action ],
            'getargs': { 'conf': ('pkg_flags', 'out') },
            'file_dep': self.cc + [ d.so for d in self.vala_deps ],
            'targets': [ target ],
            }



Contact

Email: johan.mattsson.m@gmail.com
Mastodon: typo.social/@birdfont
GitHub: johanmattssonm
LinkedIn: johan-mattsson-2ab324112