I have a Jamfile that I am using with Boost.Python to wrap some C++ classes. I have the Jamfile automatically running a python script and loading the extension as a post-compile step:
rule run-test ( test-name : sources + )
{
import testing ;
testing.make-test run-pyd : $(sources) : : $(test-name) ;
}
Then:
PROJECT_NAME = example ;
run-test $(PROJECT_NAME) : $(PROJECT_NAME)_ext test_$(PROJECT_NAME)_ext.py ;
This would build example_ext.so, then run test_example_ext.py which does a simple "import example_ext" and then some basic testing.
The problem is that I need test_example_ext.py to be able to import some Python modules from other packages, so I need to set PYTHONPATH. From the command-line, this isn't a problem, but bjam doesn't appear to carry this through to its spawned Python process, even if exported.
In this case I'm looking for the equivalent of:
$ export PYTHONPATH=..
I.e. setting the Python search path one level above where I am running bjam.
The closest I've managed to get is to work out that this does what I want:
$ bjam pythonpath=..
This actually works. But I want to set this in the Jamfile, not rely on the command line. I've read the bjam manual which says that this is a property and I can use <pythonpath>..
somewhere. But it doesn't say where.
So my problem is that I can't work out how to specify this property in a Jamfile. Where does it go? What's the syntax? Is it part of "import python ;", or "using python ..." in user-config.jam, or part of the run-pyd or even the python-extension rule? I've tried all these randomly without understanding or success.
In boost_1_50_0/tools/build/v2/tools/python.jam
I found:
# The pythonpath feature specifies additional elements for the PYTHONPATH
# environment variable, set by run-pyd. For example, pythonpath can be used to
# access Python modules that are part of the product being built, but are not
# installed in the development system's default paths.
feature.feature pythonpath : : free optional path ;
That appears to be declaring the 'pythonpath' property (aka feature), but for what context? Where and how can it be used?
And this page demonstrates how to define a property along those lines, but not really how or where to use it.
I believe I may have found an answer to my own question.
The solution appears to be the project
rule below, with the requirements
keyword, although I haven't yet understood why it works, or the implications of specifying this.
Here's my Jamfile:
PROJECT_NAME = example ; import python ; # sets PYTHONPATH when executing run-test project : requirements <pythonpath>.. ; python-extension $(PROJECT_NAME)_ext : $(PROJECT_NAME).cpp $(PROJECT_NAME)_ext.cpp : ; # Declare test targets run-test $(PROJECT_NAME) : $(PROJECT_NAME)_ext test_$(PROJECT_NAME)_ext.py ;
For completeness, I actually have this picking up a Jamroot file one directory up, that looks like this:
import python ; # Specify the path to the Boost project. If you move this project, # adjust this path to refer to the Boost root directory. use-project boost : ./boost ; # Set up the project-wide requirements that everything uses the # boost_python library from the project whose global ID is # /boost/python. project : requirements <library>/boost/python//boost_python ; # A little "rule" (function) to clean up the syntax of declaring tests # of these extension modules. rule run-test ( test-name : sources + ) { import testing ; testing.make-test run-pyd : $(sources) : : $(test-name) ; }