#! /usr/bin/env python # encoding: UTF-8 # Peter Forai # Thomas Nagy, 2008 """ Demonstrates how to create a c++ app that runs python scripts Useful for apps providing script extensions """ VERSION='0.0.1' APPNAME='swig_test' top = '.' out = 'build' def options(opt): opt.load('g++ python') def configure(conf): conf.load('g++ python') conf.check_python_version((2,4,2)) conf.check_python_headers() conf.load('swig') if conf.check_swig_version() < (1, 2, 27): conf.fatal('this swig version is too old') try: conf.load('java') # on mandriva, at least, libjvm.so is difficult to find #conf.env.LIBPATH_JAVA = "/usr/lib/jvm/java-1.6.0-sun-1.6.0.13/jre/lib/amd64/server/" conf.check_jni_headers() conf.env.HAVE_JAVA = True except conf.errors.ConfigurationError: conf.env.HAVE_JAVA = False def build(bld): # embedding # # use swig_flags = '-c++ -python -dump_classes' for debugging obj = bld( features = 'cxx cxxprogram pyembed', source = 'embed/src1.cpp embed/bind.swig', target = 'embed/embed_demo', swig_flags = '-c++ -python -Wall', includes = '. embed') # extending # # be careful that the .py produced by swig is mandatory for using the library # # it is possible to disable 'mylib', and to add extend/a.cpp # to the source of extend/python/_test_swig_waf and remove use bld( features = 'cxx cxxshlib', source = 'extend/a.cpp', target = 'extend/mylib', includes = 'extend', export_includes = 'extend', vnum = '1.2.3', name = 'mylib') bld( features = 'cxx cxxshlib pyext', source = 'extend/python/test_swig_waf.i', target = 'extend/python/_test_swig_waf', swig_flags = '-c++ -python -Wall', includes = 'extend', vnum = '1.2.3', use = 'mylib') bld.install_files('${PREFIX}/lib', 'extend/python/test_swig_waf.py') bld.add_post_fun(exec_test_python) # some java stuff if not bld.env.HAVE_JAVA: return from waflib.extras import swig srcdir = bld.path.get_bld().make_node('extend/java/hmm') # destination for generated java file (without the packages!) #""" # BEGIN BLOCK 1 d = bld.path.make_node('extend/java') javanodes = [d.find_or_declare(x) for x in 'A.java test_swig_waf.java test_swig_wafJNI.java'.split()] dec = bld.tools['swig'].swigf #@dec <- python 2.3 does not support the @decorator notation def swig_java(tsk): tsk.outputs.extend(javanodes) bld.tools['swig'].swigf(swig_java) """ # END BLOCK 1 #"""# do not remove bld( features = 'cxx cxxshlib', source = 'extend/java/test_swig_waf.i', target = 'extend/java/_test_swig_waf', swig_flags = '-c++ -java -package foo.bar.pouet', includes = 'extend', vnum = '1.2.3', uselib = 'JAVA', use = 'mylib') #""" # BEGIN BLOCK 2 for x in javanodes: bld(rule='cp ${SRC} ${TGT}', source=x, target=srcdir.make_node('foo/bar/pouet/' + x.name), before=['javac'], after=['swig']) """ # END BLOCK 2 def move_java_files(task): import os, shutil from waflib import Utils node = srcdir.make_node('foo/bar/pouet/') node.mkdir() orig = task.inputs[0].parent.get_bld().abspath() files = Utils.listdir(orig) for x in files: if x.endswith('.java'): # create a node in the directory we want to j = node.make_node(x) # create a node shutil.copy2(orig + os.sep + x, j.abspath()) # create the physical file for the node j.sig = Utils.h_file(j.abspath()) # update the node signature # depend on the .i file to make sure the .java files are copied after swig is executed bld(name='move_and_read', rule=move_java_files, source='extend/java/test_swig_waf.i', after=['swig'], before=['javac']) #""" bld(rule='cp ${SRC} ${TGT}', source=bld.path.find_resource('extend/java/Foo.java'), target=srcdir.make_node('foo/bar/pouet/Foo.java'), before=['javac'], after=['swig']) tmp = bld.path.get_bld().make_node('maha') bld(features = 'javac jar', srcdir = srcdir, sourcepath = [], outdir = tmp, # we do need another folder here basedir = tmp, destfile = 'maha.jar' ) bld.add_post_fun(exec_test_java) ######################################### # listing the java nodes is required to ensure the swig task # is executed whenever the java files are removed from # the build directory # # to list the java files automatically, comment the starting character '#' in the lines "BEGIN BLOCK 1" and "BEGIN BLOCK 2" def exec_test_java(bld): try: bld.cmd_and_log('LD_LIBRARY_PATH=$LD_LIBRARY_PATH:build/extend/java:build/extend java -classpath "build/maha.jar:." foo.bar.pouet.Foo') except: pass def exec_test_python(bld): import os, stat try: import subprocess proc = subprocess.Popen(''' PYTHONPATH=$PYTHONPATH:build/extend/python LD_LIBRARY_PATH=$LD_LIBRARY_PATH:build/extend/python:build/extend python -c "import test_swig_waf; a=test_swig_waf.A(); print 'Testing: a.add(2, 3) ->', a.add(2, 3)" '''.replace('\n', ' '), shell=True) proc.wait() except: pass # why does this fail now on mandriva??? try: os.stat('build/embed/embed_demo') bld.cmd_and_log('PYTHONPATH=$PYTHONPATH:build/embed/ build/embed/embed_demo') except: pass