root/trunk/libffado/support/tools/ffado-sandbox-install.py

Revision 2746, 13.5 kB (checked in by jwoithe, 6 years ago)

[PATCH 10/13] tools: Fix python file indents in a separate commit.

From Nicolas Boulenguez.

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