root/branches/libffado-2.0/support/tools/ffado-sandbox-install.py

Revision 1383, 13.0 kB (checked in by ppalmers, 9 years ago)

extend sandbox install tool

Line 
1 #!/usr/bin/python
2 #
3
4 #
5 # Copyright (C) 2008 Pieter Palmers
6 #
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, version 3 of the License.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 #
19
20 #
21 # A script to install FFADO in a 'sandbox', i.e. without changing the
22 # system installation.
23 #
24 import os
25
26 FFADOSBI_VERSION = '0.1'
27 LATEST_FFADO_RELEASE_URL = 'http://www.ffado.org/files/libffado-2.0-beta7.tar.gz'
28 LATEST_FFADO_RELEASE_UNPACK_DIR = 'libffado-2.0-beta7'
29 LATEST_JACK1_RELEASE_URL = 'http://jackaudio.org/downloads/jack-audio-connection-kit-0.109.2.tar.gz'
30 LATEST_JACK1_RELEASE_UNPACK_DIR = 'jack-audio-connection-kit-0.109.2'
31
32 def ask_for_dir(descr, suggestion):
33     ret_dir = None
34     while True:
35         ret_dir = raw_input("Please specify a %s directory [%s]: " % (descr, suggestion))
36         if ret_dir == "":
37             ret_dir = suggestion
38
39         if not os.path.exists(ret_dir):
40             try:
41                 os.makedirs(ret_dir)
42             except:
43                 yesno = raw_input("Could not create the %s directory. Try again? [yes/no] " % descr)
44                 if yesno == "" or yesno[0] != 'y':
45                     return None
46                 else:
47                     continue
48             break
49         else:
50             yesno = raw_input("WARNING: the %s directory at %s already exists. Do you want to overwrite it? [yes/no] " % (descr, ret_dir))
51             if yesno == "" or yesno[0] != 'y':
52                 yesno = raw_input("Specify new %s directory? [yes/no] " % descr)
53                 if yesno == "" or yesno[0] != 'y':
54                     return None
55                 else:
56                     continue
57             else:
58                 yesno = raw_input("WARNING: about to remove the old %s directory at %s. Proceed? [yes/no] " % (descr, ret_dir))
59                 if yesno == "" or yesno[0] != 'y':
60                     yesno = raw_input("Specify new %s directory? [yes/no] " % descr)
61                     if yesno == "" or yesno[0] != 'y':
62                         return None
63                     else:
64                         continue
65                 else:
66                     os.system('rm -Rf "%s"' % ret_dir)
67                     os.makedirs(ret_dir)
68                     break
69     return ret_dir
70
71 def fetch_source(build_dir, source_descriptor, target):
72     logfile = "%s/%s.log" % (build_dir, target)
73     os.system('echo "" > %s' % logfile)
74
75     if source_descriptor[1] == 'svn':
76         print " Checking out SVN repository: %s" % source_descriptor[2]
77         cwd = os.getcwd()
78         os.chdir(build_dir)
79         retval = os.system('svn co "%s" "%s" >> %s' % (source_descriptor[2], target, logfile))
80         os.chdir(cwd)
81         if retval:
82             print "  Failed to checkout the SVN repository. Inspect %s for details. (is subversion installed?)" % logfile
83             return False
84         return True
85     elif source_descriptor[1] == 'tar.gz':
86         print " Downloading tarball: %s" % source_descriptor[2]
87         import urllib
88         tmp_file = '%s/tmp.tar.gz' % build_dir
89         try:
90             urllib.urlretrieve(source_descriptor[2], tmp_file)
91         except:
92             print " Could not retrieve source tarball."
93             return False
94         cwd = os.getcwd()
95         os.chdir(build_dir)
96         print " extracting tarball..."
97         retval = os.system('tar -zxf "%s" > %s' % (tmp_file, logfile))
98         if retval:
99             print "  Failed to extract the source tarball. Inspect %s for details." % logfile
100             os.chdir(cwd)
101             return False
102         if source_descriptor[3]:
103             retval = os.system('mv "%s" "%s"' % (source_descriptor[3], target))
104             if retval:
105                 print "  Failed to move the extracted tarball"
106                 os.chdir(cwd)
107                 return False
108         os.chdir(cwd)
109         return True
110     else:
111         print "bad source type"
112         return False
113
114
115 welcome_msg = """
116 FFADO sandbox install utility """ + FFADOSBI_VERSION + """
117 =================================
118 (C) 2008 Pieter Palmers
119
120 This utility will automatically build and install a sandbox
121 environment that can be used to evaluate FFADO. The required
122 FFADO and/or jack packages are downloaded.
123
124 NOTE: The build dependencies are not automatically installed.
125 Please consult http://subversion.ffado.org/wiki/Dependencies
126 for more information. The subversion tool has to be installed.
127
128 NOTE: This tool assumes that an internet connection is available
129 while it runs. Once everything is built, no connection is
130 required.
131
132 You can exit the tool at any time using CTRL-C.
133
134 """
135
136 print welcome_msg
137
138 # get the paths to be used
139 if 'HOME' in os.environ.keys():
140     suggestion_sandbox = "%s/ffadosandbox" % os.environ['HOME']
141 else:
142     suggestion_sandbox = "/home/myuser/ffadosandbox"
143
144 sandbox_dir_msg = """
145 SANDBOX DIRECTORY
146 =================
147
148 The sandbox directory is the directory where all built files are
149 installed into. It should be writable by your user, and will
150 contain the evaluation binaries if this tool is successful. If
151 it doesn't exist, it will be created.
152
153 Once you are finished with evaluating FFADO you can simply remove
154 this directory and things are as if nothing happened.
155
156 Suggestion: %s
157
158 NOTE: if you specify a system directory here, the tool will install
159 system-wide (if run as root). This is not recommended, but can be
160 useful for automated installs. Uninstall will be a lot harder though.
161 """ % suggestion_sandbox
162
163 if 'HOME' in os.environ.keys():
164     suggestion_build = "%s/ffadobuild" % os.environ['HOME']
165 else:
166     suggestion_build = "/home/myuser/ffadobuild"
167
168 build_dir_msg = """
169 BUILD DIRECTORY
170 ===============
171
172 The build directory is where all temporary files are stored while
173 building FFADO and jack. It should be writable by your user. If
174 it doesn't exist, it will be created.
175
176 The build directory can be removed as soon as this tool has finished.
177 It is not automatically removed.
178
179 Suggestion: %s
180 """ % suggestion_build
181
182 print sandbox_dir_msg
183 sandbox_dir = ask_for_dir('sandbox', suggestion_sandbox)
184 if sandbox_dir == None:
185     print "Cannot proceed without valid sandbox directory."
186     exit(-1)
187 print(" using %s as sandbox directory" % sandbox_dir)
188
189
190 print build_dir_msg
191 build_dir = ask_for_dir('build', suggestion_build)
192 if build_dir == None:
193     print "Cannot proceed without valid build directory."
194     exit(-1)
195 print(" using %s as build directory" % build_dir)
196
197 # figure out what version of FFADO to build
198 # Note: format:
199 # ['title', type=svn or tar.gz, url, (optional) dir that contains target]
200
201 ffado_versions = {}
202 ffado_versions[0] = ['SVN trunk', 'svn', 'http://subversion.ffado.org/ffado/trunk/libffado', None]
203 ffado_versions[1] = ['SVN libffado-2.0 (recommended)', 'svn', 'http://subversion.ffado.org/ffado/branches/libffado-2.0', None]
204 ffado_versions[2] = ['latest release', 'tar.gz', LATEST_FFADO_RELEASE_URL, LATEST_FFADO_RELEASE_UNPACK_DIR]
205
206 ffado_versions_msg = """
207 Available FFADO versions:
208 """
209 for key in sorted(ffado_versions.keys()):
210     ffado_versions_msg += " %2s: %s\n" % (key, ffado_versions[key][0])
211
212 print ffado_versions_msg
213 while True:
214     ffado_version = raw_input("Please select a FFADO version: ")
215     try:
216         ffado_version_int = eval(ffado_version)
217         if ffado_version_int not in [0, 1, 2]:
218             raise
219     except:
220         yesno = raw_input("Invalid FFADO version specified. Try again? [yes/no] ")
221         if yesno == "" or yesno[0] != 'y':
222             print "Cannot proceed without valid FFADO version."
223             exit(-1)
224         else:
225             continue
226     break
227
228 use_ffado_version = ffado_versions[ffado_version_int]
229
230 # figure out what version of jack to build
231 jack_versions = {}
232 jack_versions[0] = ['jack1 SVN trunk', 'svn', 'http://subversion.jackaudio.org/jack/trunk/jack', None]
233 # note: latest release is no good.
234 #jack_versions[1] = ['jack1 latest release', 'tar.gz', LATEST_JACK1_RELEASE_URL, LATEST_JACK_RELEASE_UNPACK_DIR]
235
236 jack_versions_msg = """
237 Available jack versions:
238 """
239 for key in sorted(jack_versions.keys()):
240     jack_versions_msg += " %2s: %s\n" % (key, jack_versions[key][0])
241
242 print jack_versions_msg
243 while True:
244     jack_version = raw_input("Please select a jack version: ")
245     try:
246         jack_version_int = eval(jack_version)
247         if jack_version_int not in [0, 1, 2]:
248             raise
249     except:
250         yesno = raw_input("Invalid jack version specified. Try again? [yes/no] ")
251         if yesno == "" or yesno[0] != 'y':
252             print "Cannot proceed without valid jack version."
253             exit(-1)
254         else:
255             continue
256     break
257
258 use_jack_version = jack_versions[jack_version_int]
259
260 # print a summary
261 print """
262 SUMMARY
263 =======
264 Sandbox directory : %s
265 Build directory   : %s
266 FFADO version     : %s
267 Jack version      : %s
268
269 """ % (sandbox_dir, build_dir, use_ffado_version[0], use_jack_version[0])
270
271 # get the ffado source
272 print "Fetching FFADO source..."
273
274 if not fetch_source(build_dir, use_ffado_version, 'libffado'):
275     print "Could not fetch FFADO source"
276     exit(-1)
277 print " Successfully fetched FFADO source"
278
279 print "Fetching jack source..."
280
281 if not fetch_source(build_dir, use_jack_version, 'jack'):
282     print "Could not fetch jack source"
283     exit(-1)
284 print " Successfully fetched jack source"
285
286 cwd = os.getcwd()
287
288 ffado_log = "%s/ffadobuild.log" % build_dir
289 ffado_scons_options = "-j2" # TODO: interactive config of the build
290 os.system('echo "" > %s' % ffado_log)
291
292 # configure FFADO
293 os.chdir("%s/libffado/" % build_dir)
294 print "Building FFADO..."
295 print " Compiling..."
296 retval = os.system('scons PREFIX="%s" %s >> %s' % (sandbox_dir, ffado_scons_options, ffado_log))
297 if retval:
298     print """
299 Failed to configure/build FFADO. Most likely this is due to uninstalled dependencies.
300 Check %s for details.
301 """ % ffado_log
302     exit(-1)
303
304 # install FFADO
305 print " Installing into %s..." % sandbox_dir
306 retval = os.system('scons install >> %s' % (ffado_log))
307 if retval:
308     print "Failed to install FFADO. Check %s for details." % ffado_log
309     exit(-1)
310
311 # configure JACK
312 os.chdir("%s/jack/" % build_dir)
313 jack_log = "%s/jackbuild.log" % build_dir
314 os.system('echo "" > %s' % jack_log)
315
316 print "Building Jack..."
317 if use_jack_version[1] == 'svn':
318     print " Initializing build system..."
319     retval = os.system('./autogen.sh >> %s' % jack_log)
320     if retval:
321         print """
322 Failed to initialize the jack build system. Most likely this is due to uninstalled dependencies.
323 Check %s for details.
324 """ % jack_log
325         exit(-1)
326
327 print " Configuring build..."
328 retval = os.system('./configure --prefix="%s" >> %s' % (sandbox_dir, jack_log))
329 if retval:
330     print """
331 Failed to configure the jack build. Most likely this is due to uninstalled dependencies.
332 Check %s for details.
333 """ % jack_log
334     exit(-1)
335
336 # build and install jack
337 print " Compiling..."
338 retval = os.system('make >> %s' % (jack_log))
339 if retval:
340     print "Failed to build jack. Check %s for details." % jack_log
341     exit(-1)
342
343 print " Installing into %s..." % sandbox_dir
344 retval = os.system('make install >> %s' % (jack_log))
345 if retval:
346     print "Failed to install jack. Check %s for details." % jack_log
347     exit(-1)
348
349 # write the bashrc file
350 sandbox_bashrc = """
351 #!/bin/bash
352 #
353
354 LD_LIBRARY_PATH="%s/lib:$LD_LIBRARY_PATH"
355 PKG_CONFIG_PATH="%s/lib/pkgconfig:$PKG_CONFIG_PATH"
356 PATH="%s/bin:$PATH"
357
358 export LD_LIBRARY_PATH
359 export PKG_CONFIG_PATH
360 export PATH
361 """ % (sandbox_dir, sandbox_dir, sandbox_dir)
362
363 print "Writing shell configuration file..."
364 sandbox_rc_file = "%s/ffado.rc" % sandbox_dir
365 try:
366     fid = open(sandbox_rc_file, "w")
367     fid.write(sandbox_bashrc)
368     fid.close()
369 except:
370     print "Could not write the sandbox rc file."
371     exit(-1)
372
373 os.chdir(cwd)
374
375 print """
376 FFADO and jack are installed into %s. If you want to use the
377 versions in the sandbox, you have to alter your environment
378 such that it uses them instead of the system versions.
379
380 If you use the bash shell (or compatible) you can use the following
381 rc script: %s. The procedure to use the sandboxed ffado+jack would be:
382
383    $ source %s
384    $ jackd -R -d firewire
385
386 If you don't use the bash shell, you have to alter your environment
387 manually. Look at the %s script for inspiration.
388
389 Note that you have to source the settings script for every terminal
390 you open. If you want a client application to use the sandboxed jack
391 you have to source the settings.
392
393 E.g.:
394  terminal 1:
395    $ source %s
396    $ jackd -R -d firewire
397  terminal 2:
398    $ source %s
399    $ ardour2
400  terminal 3:
401    $ source %s
402    $ qjackctl &
403    $ hydrogen
404
405 If you want to use the sandboxed version as default, you have to ensure
406 that the default environment is changed. This can be done e.g. by adding
407 the settings script to ~/.bashrc.
408
409 The build directory %s can now be deleted. To uninstall this sandbox, delete
410 the %s directory.
411 """ % (sandbox_dir, sandbox_rc_file, sandbox_rc_file, \
412        sandbox_rc_file, sandbox_rc_file, sandbox_rc_file, \
413        sandbox_rc_file, build_dir, sandbox_dir)
Note: See TracBrowser for help on using the browser.