2 # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
4 # Permission is hereby granted, free of charge, to any person obtaining
5 # a copy of this software and associated documentation files (the
6 # "Software"), to deal in the Software without restriction, including
7 # without limitation the rights to use, copy, modify, merge, publish,
8 # distribute, sublicense, and/or sell copies of the Software, and to
9 # permit persons to whom the Software is furnished to do so, subject to
10 # the following conditions:
12 # The above copyright notice and this permission notice shall be included
13 # in all copies or substantial portions of the Software.
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
16 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
17 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 __revision__ = "src/setup.py 3842 2008/12/20 22:59:52 scons"
40 (head, tail) = os.path.split(sys.argv[0])
47 if not sys.platform == 'win32':
49 if sys.argv[1] == 'bdist_wininst':
59 import distutils.command.install
60 import distutils.command.install_data
61 import distutils.command.install_lib
62 import distutils.command.install_scripts
63 import distutils.command.build_scripts
65 sys.stderr.write("""Could not import distutils.
67 Building or installing SCons from this package requires that the Python
68 distutils be installed. See the README or README.txt file from this
69 package for instructions on where to find distutils for installation on
70 your system, or on how to install SCons from a different package.
74 _install = distutils.command.install.install
75 _install_data = distutils.command.install_data.install_data
76 _install_lib = distutils.command.install_lib.install_lib
77 _install_scripts = distutils.command.install_scripts.install_scripts
78 _build_scripts = distutils.command.build_scripts.build_scripts
87 def set_explicitly(name, args):
89 Return if the installation directory was set explicitly by the
90 user on the command line. This is complicated by the fact that
91 "install --install-lib=/foo" gets turned into "install_lib
92 --install-dir=/foo" internally.
94 if args[0] == "install_" + name:
97 # The command is something else (usually "install")
98 s = "--install-%s=" % name
107 class install(_install):
108 user_options = _install.user_options + [
109 ('no-scons-script', None,
110 "don't install 'scons', only install 'scons-%s'" % Version),
111 ('no-version-script', None,
112 "don't install 'scons-%s', only install 'scons'" % Version),
113 ('install-bat', None,
114 "install 'scons.bat' script"),
115 ('no-install-bat', None,
116 "do not install 'scons.bat' script"),
117 ('install-man', None,
118 "install SCons man pages"),
119 ('no-install-man', None,
120 "do not install SCons man pages"),
121 ('standard-lib', None,
122 "install SCons library in standard Python location"),
123 ('standalone-lib', None,
124 "install SCons library in separate standalone directory"),
125 ('version-lib', None,
126 "install SCons library in version-numbered directory"),
128 boolean_options = _install.boolean_options + [
140 if hasattr(os, 'symlink'):
142 ('hardlink-scons', None,
143 "hard link 'scons' to the version-numbered script, don't make a separate 'scons' copy"),
145 boolean_options.append('hardlink-script')
147 if hasattr(os, 'symlink'):
149 ('symlink-scons', None,
150 "make 'scons' a symbolic link to the version-numbered script, don't make a separate 'scons' copy"),
152 boolean_options.append('symlink-script')
154 def initialize_options(self):
155 _install.initialize_options(self)
156 self.no_scons_script = 0
157 self.no_version_script = 0
159 self.no_install_bat = not is_win32
161 self.no_install_man = is_win32
162 self.standard_lib = 0
163 self.standalone_lib = 0
165 self.hardlink_scons = 0
166 self.symlink_scons = 0
167 # Don't warn about having to put the library directory in the
171 def finalize_options(self):
172 _install.finalize_options(self)
174 Options.install_bat = 1
176 Options.install_bat = not self.no_install_bat
178 Options.install_man = 1
180 Options.install_man = not self.no_install_man
181 Options.standard_lib = self.standard_lib
182 Options.standalone_lib = self.standalone_lib
183 Options.version_lib = self.version_lib
184 Options.install_scons_script = not self.no_scons_script
185 Options.install_version_script = not self.no_version_script
186 Options.hardlink_scons = self.hardlink_scons
187 Options.symlink_scons = self.symlink_scons
189 def get_scons_prefix(libdir, is_win32):
191 Return the right prefix for SCons library installation. Find
192 this by starting with the library installation directory
193 (.../site-packages, most likely) and crawling back up until we reach
194 a directory name beginning with "python" (or "Python").
196 drive, head = os.path.splitdrive(libdir)
200 head, tail = os.path.split(head)
201 if string.lower(tail)[:6] == "python":
202 # Found the Python library directory...
204 # ...on Win32 systems, "scons" goes in the directory:
205 # C:\PythonXX => C:\PythonXX\scons
206 return os.path.join(drive + head, tail)
208 # ...on other systems, "scons" goes above the directory:
209 # /usr/lib/pythonX.X => /usr/lib/scons
210 return os.path.join(drive + head)
213 def force_to_usr_local(self):
215 A hack to decide if we need to "force" the installation directories
216 to be under /usr/local. This is because Mac Os X Tiger and
217 Leopard, by default, put the libraries and scripts in their own
218 directories under /Library or /System/Library.
220 return (sys.platform[:6] == 'darwin' and
221 (self.install_dir[:9] == '/Library/' or
222 self.install_dir[:16] == '/System/Library/'))
224 class install_lib(_install_lib):
225 def finalize_options(self):
226 _install_lib.finalize_options(self)
227 if force_to_usr_local(self):
228 self.install_dir = '/usr/local/lib'
229 args = self.distribution.script_args
230 if not set_explicitly("lib", args):
231 # They didn't explicitly specify the installation
232 # directory for libraries...
233 is_win32 = sys.platform == "win32" or args[0] == 'bdist_wininst'
234 prefix = get_scons_prefix(self.install_dir, is_win32)
235 if Options.standalone_lib:
236 # ...but they asked for a standalone directory.
237 self.install_dir = os.path.join(prefix, "scons")
238 elif Options.version_lib or not Options.standard_lib:
239 # ...they asked for a version-specific directory,
240 # or they get it by default.
241 self.install_dir = os.path.join(prefix, "scons-%s" % Version)
243 msg = "Installed SCons library modules into %s" % self.install_dir
244 Installed.append(msg)
246 class install_scripts(_install_scripts):
247 def finalize_options(self):
248 _install_scripts.finalize_options(self)
249 if force_to_usr_local(self):
250 self.install_dir = '/usr/local/bin'
251 self.build_dir = os.path.join('build', 'scripts')
252 msg = "Installed SCons scripts into %s" % self.install_dir
253 Installed.append(msg)
255 def do_nothing(self, *args, **kw):
258 def hardlink_scons(self, src, dst, ver):
263 def symlink_scons(self, src, dst, ver):
266 os.symlink(os.path.split(ver)[1], dst)
268 def copy_scons(self, src, dst, *args):
271 self.copy_file(src, dst)
272 self.outfiles.append(dst)
274 def report(self, msg, args):
275 # Wrapper around self.announce, used by older distutils versions.
276 self.announce(msg % args)
279 # This "skip_build/build_scripts" block is cut-and-paste from
281 if not self.skip_build:
282 self.run_command('build_scripts')
284 # Custom SCons installation stuff.
285 if Options.hardlink_scons:
286 create_basename_script = self.hardlink_scons
287 elif Options.symlink_scons:
288 create_basename_script = self.symlink_scons
289 elif Options.install_scons_script:
290 create_basename_script = self.copy_scons
292 create_basename_script = self.do_nothing
294 if Options.install_version_script:
295 create_version_script = self.copy_scons
297 create_version_script = self.do_nothing
299 inputs = self.get_inputs()
300 bat_scripts = filter(lambda x: x[-4:] == '.bat', inputs)
301 non_bat_scripts = filter(lambda x: x[-4:] != '.bat', inputs)
304 self.mkpath(self.install_dir)
306 for src in non_bat_scripts:
307 base = os.path.basename(src)
308 scons = os.path.join(self.install_dir, base)
309 scons_ver = scons + '-' + Version
310 create_version_script(src, scons_ver)
311 create_basename_script(src, scons, scons_ver)
313 if Options.install_bat:
315 bat_install_dir = get_scons_prefix(self.install_dir, is_win32)
317 bat_install_dir = self.install_dir
318 for src in bat_scripts:
319 scons_bat = os.path.join(bat_install_dir, 'scons.bat')
320 scons_version_bat = os.path.join(bat_install_dir,
321 'scons-' + Version + '.bat')
322 self.copy_scons(src, scons_bat)
323 self.copy_scons(src, scons_version_bat)
325 # This section is cut-and-paste from distutils, modulo being
327 if os.name == 'posix':
328 try: report = distutils.log.info
329 except AttributeError: report = self.report
330 # Set the executable bits (owner, group, and world) on
331 # all the scripts we just installed.
332 for file in self.get_outputs():
334 report("changing mode of %s", file)
336 mode = ((os.stat(file)[stat.ST_MODE]) | 0555) & 07777
337 report("changing mode of %s", file)
340 class build_scripts(_build_scripts):
341 def finalize_options(self):
342 _build_scripts.finalize_options(self)
343 self.build_dir = os.path.join('build', 'scripts')
345 class install_data(_install_data):
346 def initialize_options(self):
347 _install_data.initialize_options(self)
348 def finalize_options(self):
349 _install_data.finalize_options(self)
350 if force_to_usr_local(self):
351 self.install_dir = '/usr/local'
352 if Options.install_man:
356 dir = os.path.join('man', 'man1')
357 self.data_files = [(dir, man_pages)]
358 man_dir = os.path.join(self.install_dir, dir)
359 msg = "Installed SCons man pages into %s" % man_dir
360 Installed.append(msg)
364 description = "Open Source next-generation build tool."
366 long_description = """Open Source next-generation build tool.
367 Improved, cross-platform substitute for the classic Make
368 utility. In short, SCons is an easier, more reliable
369 and faster way to build software."""
376 # We include scons.bat in the list of scripts, even on UNIX systems,
377 # because we provide an option to allow it be installed explicitly,
378 # for example if you're installing from UNIX on a share that's
379 # accessible to Windows and you want the scons.bat.
384 # scripts = scripts + [
385 # 'script/scons-post-install.py'
391 'description' : description,
392 'long_description' : long_description,
393 'author' : 'Steven Knight',
394 'author_email' : 'knight@baldmt.com',
395 'url' : "http://www.scons.org/",
396 'packages' : ["SCons",
404 "SCons.Tool.packaging",
407 'package_dir' : {'' : 'engine'},
408 'data_files' : [('man/man1', man_pages)],
410 'cmdclass' : {'install' : install,
411 'install_lib' : install_lib,
412 'install_data' : install_data,
413 'install_scripts' : install_scripts,
414 'build_scripts' : build_scripts}
417 apply(distutils.core.setup, (), arguments)
420 print string.join(Installed, '\n')