summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGary Oberbrunner <garyo@oberbrunner.com>2010-07-04 00:14:53 (GMT)
committerGary Oberbrunner <garyo@oberbrunner.com>2010-07-04 00:14:53 (GMT)
commit13c61768b4ff739e2599b0de3f90a8efe15dd9fc (patch)
treebc12280e536e0d896be304026cd1e1e0e0bd2915
parent89eaa55eb76fdb8ea6368e0a720420f6bf8624f1 (diff)
downloadSCons-13c61768b4ff739e2599b0de3f90a8efe15dd9fc.zip
SCons-13c61768b4ff739e2599b0de3f90a8efe15dd9fc.tar.gz
SCons-13c61768b4ff739e2599b0de3f90a8efe15dd9fc.tar.bz2
Add all the per-system and per-user site_scons dirs, per discussion in SEP 002.
-rw-r--r--doc/man/scons.158
-rw-r--r--doc/user/builders-writing.in26
-rw-r--r--src/CHANGES.txt4
-rw-r--r--src/RELEASE.txt5
-rw-r--r--src/engine/SCons/Script/Main.py62
-rw-r--r--test/site_scons/sysdirs.py71
6 files changed, 205 insertions, 21 deletions
diff --git a/doc/man/scons.1 b/doc/man/scons.1
index da6c918..4f3b1a3 100644
--- a/doc/man/scons.1
+++ b/doc/man/scons.1
@@ -100,17 +100,17 @@ file,
.B scons
looks for a directory named
.I site_scons
-in the directory containing the
+in various system directories (see below) and the directory containing the
.I SConstruct
-file; if it exists,
+file; for each of those dirs which exists,
.I site_scons
-is added to sys.path,
+is prepended to sys.path,
the file
.IR site_scons/site_init.py ,
is evaluated if it exists,
and the directory
.I site_scons/site_tools
-is added to the default toolpath if it exist.
+is prepended to the default toolpath if it exists.
See the
.I --no-site-dir
and
@@ -1095,13 +1095,13 @@ any out-of-date target files, but do not execute the commands.
.RI --no-site-dir
Prevents the automatic addition of the standard
.I site_scons
-dir to
+dirs to
.IR sys.path .
Also prevents loading the
.I site_scons/site_init.py
-module if it exists, and prevents adding
+modules if they exist, and prevents adding their
.I site_scons/site_tools
-to the toolpath.
+dirs to the toolpath.
.\" .TP
.\" .RI -o " file" ", --old-file=" file ", --assume-old=" file
@@ -1182,7 +1182,7 @@ Ignored for compatibility with GNU
.RI --site-dir= dir
Uses the named dir as the site dir rather than the default
.I site_scons
-dir. This dir will get prepended to
+dirs. This dir will get prepended to
.IR sys.path ,
the module
.IR dir /site_init.py
@@ -1190,6 +1190,48 @@ will get loaded if it exists, and
.IR dir /site_tools
will get added to the default toolpath.
+The default set of
+.I site_scons
+dirs used when
+.I --site-dir
+is not specified depends on the system platform, as follows. Note
+that the directories are examined in the order given, from most
+generic to most specific, so the last-executed site_init.py file is
+the most specific one (which gives it the chance to override
+everything else), and the dirs are prepended to the paths, again so
+the last dir examined comes first in the resulting path.
+
+.IP "Windows:"
+.nf
+ %ALLUSERSPROFILE/Application Data/scons/site_scons
+ %USERPROFILE%/Local Settings/Application Data/scons/site_scons
+ %APPDATA%/scons/site_scons
+ %HOME%/.scons/site_scons
+ ./site_scons
+.fi
+.IP "Mac OS X:"
+.nf
+ /Library/Application Support/SCons/site_scons
+ /opt/local/share/scons/site_scons (for MacPorts)
+ /sw/share/scons/site_scons (for Fink)
+ $HOME/Library/Application Support/SCons/site_scons
+ $HOME/.scons/site_scons
+ ./site_scons
+.fi
+.IP "Solaris:"
+.nf
+ /opt/sfw/scons/site_scons
+ /usr/share/scons/site_scons
+ $HOME/.scons/site_scons
+ ./site_scons
+.fi
+.IP "Linux, HPUX, and other Posix-like systems:"
+.nf
+ /usr/share/scons/site_scons
+ $HOME/.scons/site_scons
+ ./site_scons
+.fi
+
.TP
.RI --stack-size= KILOBYTES
Set the size stack used to run threads to
diff --git a/doc/user/builders-writing.in b/doc/user/builders-writing.in
index 1da45a5..59c1117 100644
--- a/doc/user/builders-writing.in
+++ b/doc/user/builders-writing.in
@@ -897,7 +897,7 @@ This functionality could be invoked as in the following example:
<para>
- The <filename>site_scons</filename> directory gives you a place to
+ The <filename>site_scons</filename> directories give you a place to
put Python modules you can import into your &SConscript; files
(<filename>site_scons</filename>),
add-on tools that can integrate into &SCons;
@@ -910,8 +910,18 @@ This functionality could be invoked as in the following example:
<para>
+ Each system type (Windows, Mac, Linux, etc.) searches a canonical
+ set of directories for site_scons; see the man page for details.
+ The top-level SConstruct's site_scons dir is always searched last,
+ and its dir is placed first in the tool path so it overrides all
+ others.
+
+ </para>
+
+ <para>
+
If you get a tool from somewhere (the &SCons; wiki or a third party,
- for instance) and you'd like to use it in your project, the
+ for instance) and you'd like to use it in your project, a
<filename>site_scons</filename> dir is the simplest place to put it.
Tools come in two flavors; either a Python function that operates on
an &Environment; or a Python file containing two functions,
@@ -1045,13 +1055,15 @@ This functionality could be invoked as in the following example:
<para>
- If you have a machine-wide site dir you'd like to use instead of
- <filename>./site_scons</filename>, use the
- <literal>--site-dir</literal> option to point to your dir.
+ You can use any of the user- or machine-wide site dirs such as
+ <filename>~/.scons/site_scons</filename> instead of
+ <filename>./site_scons</filename>, or use the
+ <literal>--site-dir</literal> option to point to your own dir.
<filename>site_init.py</filename> and
<filename>site_tools</filename> will be located under that dir.
- To avoid using a <filename>site_scons</filename> dir at all, even
- if it exists, use the <literal>--no-site-dir</literal> option.
+ To avoid using a <filename>site_scons</filename> dir at all,
+ even if it exists, use the <literal>--no-site-dir</literal>
+ option.
</para>
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 831546f..9435482 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -7,6 +7,10 @@
RELEASE 2.1.0.alpha.yyyymmdd - NEW DATE WILL BE INSERTED HERE
+ From Gary Oberbrunner:
+
+ - New systemwide and per-user site_scons dirs.
+
From Dirk Baechle:
- XML fixes in User's Guide.
diff --git a/src/RELEASE.txt b/src/RELEASE.txt
index a60fbd9..c2d2f60 100644
--- a/src/RELEASE.txt
+++ b/src/RELEASE.txt
@@ -31,6 +31,11 @@
NEW FUNCTIONALITY
+ - SCons now searches for site_scons dirs in several system-wide
+ and per-user locations, in addition to the SConstruct top dir.
+ This should enable much easier use of third-party (non-core)
+ Tools.
+
- List new features (presumably why a checkpoint is being released)
DEPRECATED FUNCTIONALITY
diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py
index 875da71..eed782e 100644
--- a/src/engine/SCons/Script/Main.py
+++ b/src/engine/SCons/Script/Main.py
@@ -60,6 +60,7 @@ import SCons.Errors
import SCons.Job
import SCons.Node
import SCons.Node.FS
+import SCons.Platform
import SCons.SConf
import SCons.Script
import SCons.Taskmaster
@@ -665,15 +666,15 @@ def _create_path(plist):
def _load_site_scons_dir(topdir, site_dir_name=None):
"""Load the site_scons dir under topdir.
- Adds site_scons to sys.path, imports site_scons/site_init.py,
- and adds site_scons/site_tools to default toolpath."""
+ Prepends site_scons to sys.path, imports site_scons/site_init.py,
+ and prepends site_scons/site_tools to default toolpath."""
if site_dir_name:
err_if_not_found = True # user specified: err if missing
else:
site_dir_name = "site_scons"
err_if_not_found = False
- site_dir = os.path.join(topdir.path, site_dir_name)
+ site_dir = os.path.join(topdir, site_dir_name)
if not os.path.exists(site_dir):
if err_if_not_found:
raise SCons.Errors.UserError("site dir %s not found."%site_dir)
@@ -682,6 +683,7 @@ def _load_site_scons_dir(topdir, site_dir_name=None):
site_init_filename = "site_init.py"
site_init_modname = "site_init"
site_tools_dirname = "site_tools"
+ # prepend to sys.path
sys.path = [os.path.abspath(site_dir)] + sys.path
site_init_file = os.path.join(site_dir, site_init_filename)
site_tools_dir = os.path.join(site_dir, site_tools_dirname)
@@ -723,7 +725,55 @@ def _load_site_scons_dir(topdir, site_dir_name=None):
if fp:
fp.close()
if os.path.exists(site_tools_dir):
- SCons.Tool.DefaultToolpath.append(os.path.abspath(site_tools_dir))
+ # prepend to DefaultToolpath
+ SCons.Tool.DefaultToolpath.insert(0, os.path.abspath(site_tools_dir))
+
+def _load_all_site_scons_dirs(topdir, verbose=None):
+ """Load all of the predefined site_scons dir.
+ Order is significant; we load them in order from most generic
+ (machine-wide) to most specific (topdir).
+ The verbose argument is only for testing.
+ """
+ platform = SCons.Platform.platform_default()
+
+ def homedir(d):
+ return os.path.expanduser('~/'+d)
+
+ if platform == 'win32' or platform == 'cygwin':
+ # Note we use $ here instead of %...% because older
+ # pythons (prior to 2.6?) didn't expand %...% on Windows.
+ # This set of dirs should work on XP, Vista, 7 and later.
+ sysdirs=[
+ os.path.expandvars('$ALLUSERSPROFILE\\Application Data\\scons'),
+ os.path.expandvars('$USERPROFILE\\Local Settings\\Application Data\\scons')]
+ appdatadir = os.path.expandvars('$APPDATA\\scons')
+ if appdatadir not in sysdirs:
+ sysdirs.append(appdatadir)
+ sysdirs.append(homedir('.scons'))
+
+ elif platform == 'darwin': # MacOS X
+ sysdirs=['/Library/Application Support/SCons',
+ '/opt/local/share/scons', # (for MacPorts)
+ '/sw/share/scons', # (for Fink)
+ homedir('Library/Application Support/SCons'),
+ homedir('.scons')]
+ elif platform == 'sunos': # Solaris
+ sysdirs=['/opt/sfw/scons',
+ '/usr/share/scons',
+ homedir('.scons')]
+ else: # Linux, HPUX, etc.
+ # assume posix-like, i.e. platform == 'posix'
+ sysdirs=['/usr/share/scons',
+ homedir('.scons')]
+
+ dirs=sysdirs + [topdir]
+ for d in dirs:
+ if verbose: # this is used by unit tests.
+ print "Loading site dir ", d
+ _load_site_scons_dir(d)
+
+def test_load_all_site_scons_dirs(d):
+ _load_all_site_scons_dirs(d, True)
def version_string(label, module):
version = module.__version__
@@ -860,9 +910,9 @@ def _main(parser):
progress_display.set_mode(0)
if options.site_dir:
- _load_site_scons_dir(d, options.site_dir)
+ _load_site_scons_dir(d.path, options.site_dir)
elif not options.no_site_dir:
- _load_site_scons_dir(d)
+ _load_all_site_scons_dirs(d.path)
if options.include_dir:
sys.path = options.include_dir + sys.path
diff --git a/test/site_scons/sysdirs.py b/test/site_scons/sysdirs.py
new file mode 100644
index 0000000..c05ef67
--- /dev/null
+++ b/test/site_scons/sysdirs.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import TestSCons
+
+"""
+Verify site_scons system dirs are getting loaded.
+Uses an internal test fixture to get at the site_scons dirs.
+
+TODO: it would be great to test if it can actually load site_scons
+files from the system dirs, but the test harness can't put files in
+those dirs (which may not even exist on a build system).
+"""
+
+test = TestSCons.TestSCons()
+
+test.write('SConstruct', """
+import SCons.Script
+SCons.Script.Main.test_load_all_site_scons_dirs(Dir('.').path)
+""")
+
+test.run(arguments = '-Q .')
+
+import SCons.Platform
+platform = SCons.Platform.platform_default()
+if platform in ('win32', 'cygwin'):
+ dir_to_check_for='Application Data'
+elif platform in ('darwin'):
+ dir_to_check_for='Library'
+else:
+ dir_to_check_for='.scons'
+
+if 'Loading site dir' not in test.stdout():
+ print test.stdout()
+ test.fail_test()
+if dir_to_check_for not in test.stdout():
+ print test.stdout()
+ test.fail_test()
+
+test.pass_test()
+
+# end of file
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4: