Search code examples
pythonshared-librarieswaf

Is it possible to compile library with waf using make install?


I'm trying to compile a library with waf when I configure and build my project.

To be more exact the library is Cryptopp. The thing is that I have added the source code like a git-submodule and I would like to compile and install it when some user download it from GitHub.

Is it possible to execute "make" and "make install" with waf during the "python waf configure"?


Solution

  • I did this once for systemc, the code is below. You will have to adopt it a bit for the cryptopp. The important parts are:

    • The build is executed in the source folder (could not work around that)
    • The build library is copied to the build folder as task output
    • the "autotools_make" feature has a link_task, so you can use it in other targets (use="systemc")

    I also would recommend to do the build of the library actually in the build step.

    import sys, os
    
    from waflib.Task import Task
    from waflib.TaskGen import feature
    
    class run_make(Task):
        def run(self):
            ret = self.exec_command(
                    '%s; %s; %s' % (self.env.ACLOCAL, self.env.AUTOCONF, self.env.AUTOMAKE),
                    cwd = self.cwd, stdout=sys.stdout)
            if ret != 0:
                return ret
            ret = self.exec_command('./configure', cwd = self.cwd, stdout=sys.stdout)
            if ret != 0:
                return ret
            ret = self.exec_command('make install -i', cwd=self.cwd, stdout=sys.stdout)
            self.exec_command('cp src/libsystemc.a %s' % self.outputs[0].abspath(), cwd=self.cwd)
            print "COPY"
            return ret
    
    @feature("autotools_make")
    def autotools_make(self):
        self.link_task = self.create_task('run_make',
                self.path.get_src().ant_glob('src/**/*.(cpp|h)'),
                [ self.path.get_bld().find_or_declare('libsystemc.a') ])
        self.link_task.cwd = self.path.get_src().abspath()
        self.target = self.name
    
    
    def options(opt):
        opt.load('compiler_cxx')
    
    def configure(cfg):
        cfg.load('compiler_cxx')
    
        cfg.find_program('aclocal',  mandatory=True)
        cfg.find_program('autoconf', mandatory=True)
        cfg.find_program('automake', mandatory=True)
    
    def spring_cleaning(bld):
        cwd = bld.path.get_src().abspath()
        bld.exec_command('make clean', cwd=cwd)
        bld.exec_command('make uninstall', cwd=cwd)
        bld.exec_command('find . -name "*.a" -exec rm -f {} \;', cwd=cwd)
        bld.exec_command('rm -rf aclocal.m4 Makefile Makefile.in configure *.log', cwd=cwd)
    
    def build(bld):
        bld(name='systemc',
            features='autotools_make')
    
        if bld.cmd == 'clean':
            spring_cleaning(bld)