Normally when using a tool from the construction environment,
several different search locations are checked by default.
This includes the SCons/Tools/
directory
that is part of the scons distribution
and the directory site_scons/site_tools
relative to the root SConstruct
file.
# Builtin tool or tool located within site_tools env = Environment(tools=['SomeTool']) env.SomeTool(targets, sources) # The search locations would include by default SCons/Tool/SomeTool.py SCons/Tool/SomeTool/__init__.py ./site_scons/site_tools/SomeTool.py ./site_scons/site_tools/SomeTool/__init__.py
In some cases you may want to specify a different location to search for tools.
The Environment
function contains an option for this called
toolpath
This can be used to add additional search directories.
# Tool located within the toolpath directory option env = Environment( tools=['SomeTool'], toolpath=['/opt/SomeToolPath', '/opt/SomeToolPath2'] ) env.SomeTool(targets, sources) # The search locations in this example would include: /opt/SomeToolPath/SomeTool.py /opt/SomeToolPath/SomeTool/__init__.py /opt/SomeToolPath2/SomeTool.py /opt/SomeToolPath2/SomeTool/__init__.py SCons/Tool/SomeTool.py SCons/Tool/SomeTool/__init__.py ./site_scons/site_tools/SomeTool.py ./site_scons/site_tools/SomeTool/__init__.py
Since SCons 3.0, a Builder may be located within a sub-directory / sub-package of the toolpath. This is similar to namespacing within Python. With nested or namespaced tools we can use the dot notation to specify a sub-directory that the tool is located under.
# namespaced target env = Environment( tools=['SubDir1.SubDir2.SomeTool'], toolpath=['/opt/SomeToolPath'] ) env.SomeTool(targets, sources) # With this example the search locations would include /opt/SomeToolPath/SubDir1/SubDir2/SomeTool.py /opt/SomeToolPath/SubDir1/SubDir2/SomeTool/__init__.py SCons/Tool/SubDir1/SubDir2/SomeTool.py SCons/Tool/SubDir1/SubDir2/SomeTool/__init__.py ./site_scons/site_tools/SubDir1/SubDir2/SomeTool.py ./site_scons/site_tools/SubDir1/SubDir2/SomeTool/__init__.py
If we want to access tools external to scons which are findable
via sys.path
(for example, tools installed via Python's pip package manager),
it is possible to use sys.path
with the toolpath.
One thing to watch out for with this approach is that
sys.path
can sometimes contains paths to .egg
files instead of directories.
So we need to filter those out with this approach.
# namespaced target using sys.path within toolpath searchpaths = [] for item in sys.path: if os.path.isdir(item): searchpaths.append(item) env = Environment( tools=['someinstalledpackage.SomeTool'], toolpath=searchpaths ) env.SomeTool(targets, sources)
By using sys.path
with the toolpath argument
and by using the nested syntax we can have scons search
packages installed via pip for Tools.
# For Windows based on the python version and install directory, this may be something like C:\Python35\Lib\site-packages\someinstalledpackage\SomeTool.py C:\Python35\Lib\site-packages\someinstalledpackage\SomeTool\__init__.py # For Linux this could be something like: /usr/lib/python3/dist-packages/someinstalledpackage/SomeTool.py /usr/lib/python3/dist-packages/someinstalledpackage/SomeTool/__init__.py
In some cases you may want to use a tool
located within a installed external pip package.
This is possible by the use of
sys.path
with the toolpath.
However in that situation you need to provide a prefix to the toolname
to indicate where it is located within sys.path
.
searchpaths = [] for item in sys.path: if os.path.isdir(item): searchpaths.append(item) env = Environment( tools=['tools_example.subdir1.subdir2.SomeTool'], toolpath=searchpaths ) env.SomeTool(targets, sources)
To avoid the use of a prefix within the name of the tool or filtering
sys.path
for directories,
we can use PyPackageDir
function to locate the directory of
the python package.
PyPackageDir
returns a Dir object which represents the path of the
directory
for the python package / module specified as a parameter.
# namespaced target using sys.path env = Environment( tools=['SomeTool'], toolpath=[PyPackageDir('tools_example.subdir1.subdir2')] ) env.SomeTool(targets, sources)