1 | #!/opt/local/bin/perl |
---|
2 | #WCT was /usr/bin/perl |
---|
3 | |
---|
4 | ### = file |
---|
5 | ### osx-packager.pl |
---|
6 | ### |
---|
7 | ### = revision |
---|
8 | ### $Id$ |
---|
9 | ### |
---|
10 | ### = location |
---|
11 | # XXX Fix Me XXX |
---|
12 | ### http://svn.mythtv.org/svn/trunk/packaging/OSX/build/osx-packager.pl |
---|
13 | ### |
---|
14 | ### = description |
---|
15 | ### Tool for automating frontend builds on Mac OS X. |
---|
16 | ### Run "osx-packager.pl -man" for full documentation. |
---|
17 | |
---|
18 | use strict; |
---|
19 | use Getopt::Long qw(:config auto_abbrev); |
---|
20 | use Pod::Usage (); |
---|
21 | use Cwd (); |
---|
22 | |
---|
23 | ### Configuration settings (stuff that might change more often) |
---|
24 | |
---|
25 | # We try to auto-locate the Subversion client binaries. |
---|
26 | # If they are not in your path, we build them from source |
---|
27 | # |
---|
28 | # XXX Fix Me XXX |
---|
29 | our $git = `which git`; chomp $git; |
---|
30 | #our $svn = `which svn`; chomp $svn; |
---|
31 | |
---|
32 | # This script used to always delete the installed include and lib dirs. |
---|
33 | # That probably ensures a safe build, but when rebuilding adds minutes to |
---|
34 | # the total build time, and prevents us skipping some parts of a full build |
---|
35 | # |
---|
36 | our $cleanLibs = 1; |
---|
37 | |
---|
38 | # By default, only the frontend is built (i.e. no backend or transcoding) |
---|
39 | # |
---|
40 | our $backend = 0; |
---|
41 | our $jobtools = 0; |
---|
42 | our $feplus = 0; |
---|
43 | |
---|
44 | # Parallel makes? |
---|
45 | # |
---|
46 | #$ENV{'DISTCC_HOSTS'} = "localhost 192.168.0.6"; |
---|
47 | #$ENV{'DISTCC_VERBOSE'} = '1'; |
---|
48 | |
---|
49 | # Start with a generic address and let sourceforge |
---|
50 | # figure out which mirror is closest to us. |
---|
51 | # |
---|
52 | our $sourceforge = 'http://downloads.sourceforge.net'; |
---|
53 | |
---|
54 | # At the moment, there is mythtv plus these two |
---|
55 | our @components = ( 'myththemes', 'mythplugins' ); |
---|
56 | |
---|
57 | # The OS X programs that we are likely to be interested in. |
---|
58 | our @targets = ( 'MythFrontend' ); |
---|
59 | our @targetTW = ( 'MythAVTest', 'MythWelcome'); # WCT-make Test & Welcome options |
---|
60 | our @targetsJT = ( 'MythCommFlag', 'MythJobQueue'); |
---|
61 | our @targetsBE = ( 'MythBackend', 'MythFillDatabase', 'MythTV-Setup'); |
---|
62 | |
---|
63 | |
---|
64 | # Patches for MythTV source |
---|
65 | our %patches = (); |
---|
66 | |
---|
67 | our %depend_order = ( |
---|
68 | 'mythtv' |
---|
69 | => [ |
---|
70 | 'dvdcss', |
---|
71 | 'freetype', |
---|
72 | 'lame', |
---|
73 | 'mysqlclient', |
---|
74 | #'dbus', |
---|
75 | 'qt-4.6', |
---|
76 | ], |
---|
77 | 'mythplugins' |
---|
78 | => [ |
---|
79 | 'exif', |
---|
80 | # MythMusic needs these: |
---|
81 | 'taglib', |
---|
82 | 'libogg', |
---|
83 | 'vorbis', |
---|
84 | 'flac', |
---|
85 | ], |
---|
86 | ); |
---|
87 | |
---|
88 | our %depend = ( |
---|
89 | |
---|
90 | 'freetype' => |
---|
91 | { |
---|
92 | 'url' => "$sourceforge/sourceforge/freetype/freetype-2.1.10.tar.gz", |
---|
93 | }, |
---|
94 | |
---|
95 | 'lame' => |
---|
96 | { |
---|
97 | 'url' |
---|
98 | => "$sourceforge/sourceforge/lame/lame-3.96.1.tar.gz", |
---|
99 | 'conf' |
---|
100 | => [ |
---|
101 | '--disable-frontend', |
---|
102 | ], |
---|
103 | }, |
---|
104 | |
---|
105 | 'libmad' => |
---|
106 | { |
---|
107 | 'url' => "$sourceforge/sourceforge/mad/libmad-0.15.0b.tar.gz" |
---|
108 | }, |
---|
109 | |
---|
110 | 'taglib' => |
---|
111 | { |
---|
112 | 'url' => 'http://developer.kde.org/~wheeler/files/src/taglib-1.5.tar.gz', |
---|
113 | }, |
---|
114 | |
---|
115 | 'libogg' => |
---|
116 | { |
---|
117 | 'url' => 'http://downloads.xiph.org/releases/ogg/libogg-1.1.2.tar.gz' |
---|
118 | }, |
---|
119 | |
---|
120 | 'vorbis' => |
---|
121 | { |
---|
122 | 'url' => 'http://downloads.xiph.org/releases/vorbis/libvorbis-1.1.1.tar.gz' |
---|
123 | }, |
---|
124 | |
---|
125 | 'flac' => |
---|
126 | { |
---|
127 | 'url' => "$sourceforge/sourceforge/flac/flac-1.1.4.tar.gz", |
---|
128 | # Workaround Intel problem - Missing _FLAC__lpc_restore_signal_asm_ia32 |
---|
129 | 'conf' => [ '--disable-asm-optimizations' ] |
---|
130 | }, |
---|
131 | |
---|
132 | 'dvdcss' => |
---|
133 | { |
---|
134 | 'url' |
---|
135 | => 'http://download.videolan.org/pub/videolan/libdvdcss/1.2.9/libdvdcss-1.2.9.tar.bz2' |
---|
136 | }, |
---|
137 | |
---|
138 | 'mysqlclient' => |
---|
139 | { |
---|
140 | 'url' |
---|
141 | => 'http://mysql.he.net/Downloads/MySQL-5.0/mysql-5.0.89.tar.gz', |
---|
142 | 'conf' |
---|
143 | => [ |
---|
144 | '--without-debug', |
---|
145 | '--without-docs', |
---|
146 | '--without-man', |
---|
147 | '--without-bench', |
---|
148 | '--without-server', |
---|
149 | '--without-geometry', |
---|
150 | '--without-extra-tools', |
---|
151 | ], |
---|
152 | }, |
---|
153 | |
---|
154 | 'dbus' => |
---|
155 | { |
---|
156 | 'url' => 'http://dbus.freedesktop.org/releases/dbus/dbus-1.0.3.tar.gz', |
---|
157 | 'post-make' => 'mv $PREFIX/lib/dbus-1.0/include/dbus/dbus-arch-deps.h '. |
---|
158 | ' $PREFIX/include/dbus-1.0/dbus ; '. |
---|
159 | 'rm -fr $PREFIX/lib/dbus-1.0 ; '. |
---|
160 | 'cd $PREFIX/bin ; '. |
---|
161 | 'echo "#!/bin/sh |
---|
162 | if [ \"\$2\" = dbus-1 ]; then |
---|
163 | case \"\$1\" in |
---|
164 | \"--version\") echo 1.0.3 ;; |
---|
165 | \"--cflags\") echo -I$PREFIX/include/dbus-1.0 ;; |
---|
166 | \"--libs\") echo \"-L$PREFIX/lib -ldbus-1\" ;; |
---|
167 | esac |
---|
168 | fi |
---|
169 | exit 0" > pkg-config ; '. |
---|
170 | 'chmod 755 pkg-config' |
---|
171 | }, |
---|
172 | |
---|
173 | 'qt-4.6' |
---|
174 | => |
---|
175 | { |
---|
176 | 'url' |
---|
177 | => 'http://get.qt.nokia.com/qt/source/qt-everywhere-opensource-src-4.6.0.tar.gz', |
---|
178 | 'conf-cmd' |
---|
179 | => 'echo yes | MAKEFLAGS=$parallel_make_flags ./configure', |
---|
180 | 'conf' |
---|
181 | => [ |
---|
182 | '-opensource', |
---|
183 | '-prefix', '"$PREFIX"', |
---|
184 | '-release', |
---|
185 | '-fast', |
---|
186 | '-no-accessibility', |
---|
187 | '-no-stl', |
---|
188 | # When MythTV all ported: '-no-qt3support', |
---|
189 | |
---|
190 | # When MySQL 5.1 is used, its plugin.h file clashes with Qt's. |
---|
191 | # To work around that, replace these three lines: |
---|
192 | '-I"$PREFIX/include/mysql"', |
---|
193 | '-L"$PREFIX/lib/mysql"', |
---|
194 | '-qt-sql-mysql', |
---|
195 | # with: |
---|
196 | # '-qt-sql-mysql -mysql_config "$PREFIX/bin/mysql_config"', |
---|
197 | |
---|
198 | '-no-sql-sqlite', |
---|
199 | '-no-sql-odbc', |
---|
200 | '-system-zlib', |
---|
201 | '-no-libtiff', |
---|
202 | '-no-libmng', |
---|
203 | '-nomake examples -nomake demos', |
---|
204 | '-no-nis', |
---|
205 | '-no-cups', |
---|
206 | '-no-qdbus', |
---|
207 | #'-dbus-linked', |
---|
208 | '-no-framework', |
---|
209 | '-no-multimedia', |
---|
210 | '-no-phonon', |
---|
211 | '-no-svg', |
---|
212 | '-no-javascript-jit', |
---|
213 | '-no-scripttools', |
---|
214 | ], |
---|
215 | 'make' |
---|
216 | => [ |
---|
217 | 'sub-plugins-install_subtargets-ordered', |
---|
218 | 'install_qmake', |
---|
219 | 'install_mkspecs', |
---|
220 | ], |
---|
221 | # Using configure -release saves a lot of space and time, |
---|
222 | # but by default, debug builds of mythtv try to link against |
---|
223 | # debug libraries of Qt. This works around that: |
---|
224 | 'post-make' => 'cd $PREFIX/lib ; '. |
---|
225 | 'ln -sf libQt3Support.dylib libQt3Support_debug.dylib ; '. |
---|
226 | 'ln -sf libQtSql.dylib libQtSql_debug.dylib ; '. |
---|
227 | 'ln -sf libQtXml.dylib libQtXml_debug.dylib ; '. |
---|
228 | 'ln -sf libQtOpenGL.dylib libQtOpenGL_debug.dylib ; '. |
---|
229 | 'ln -sf libQtGui.dylib libQtGui_debug.dylib ; '. |
---|
230 | 'ln -sf libQtNetwork.dylib libQtNetwork_debug.dylib ; '. |
---|
231 | 'ln -sf libQtCore.dylib libQtCore_debug.dylib ; '. |
---|
232 | 'ln -sf libQtWebKit.dylib libQtWebKit_debug.dylib ; '. |
---|
233 | 'rm -f $PREFIX/bin/pkg-config ; '. |
---|
234 | '', |
---|
235 | 'parallel-make' => 'yes' |
---|
236 | }, |
---|
237 | |
---|
238 | 'exif' => |
---|
239 | { |
---|
240 | 'url' => "$sourceforge/sourceforge/libexif/libexif-0.6.17.tar.bz2", |
---|
241 | 'conf' => [ '--disable-docs' ] |
---|
242 | } |
---|
243 | ); |
---|
244 | |
---|
245 | |
---|
246 | =head1 NAME |
---|
247 | |
---|
248 | osx-packager.pl - build OS X binary packages for MythTV |
---|
249 | |
---|
250 | =head1 SYNOPSIS |
---|
251 | |
---|
252 | osx-packager.pl [options] |
---|
253 | |
---|
254 | Options: |
---|
255 | -help print the usage message |
---|
256 | -man print full documentation |
---|
257 | -verbose print informative messages during the process |
---|
258 | -version <str> custom version suffix (defaults to "svnYYYYMMDD") |
---|
259 | -noversion don't use any version (for building release versions) |
---|
260 | -distclean throw away all intermediate files and exit |
---|
261 | -thirdclean do a clean rebuild of third party packages |
---|
262 | -thirdskip don't rebuild the third party packages |
---|
263 | -mythtvskip don't rebuild/install mythtv |
---|
264 | -pluginskip don't rebuild/install mythplugins |
---|
265 | -themeskip don't install the extra themes from myththemes |
---|
266 | -clean do a clean rebuild of MythTV |
---|
267 | # XXX Fix Me XXX |
---|
268 | -svnbranch <str> build a specified Subversion branch, instead of HEAD |
---|
269 | -svnrev <str> build a specified Subversion revision, instead of HEAD |
---|
270 | -svntag <str> build a specified release, instead of Subversion HEAD |
---|
271 | -nohead don't update to HEAD revision of MythTV before building |
---|
272 | -usehdimage perform build inside of a case-sensitive disk image |
---|
273 | -leavehdimage leave disk image mounted on exit |
---|
274 | -enable-feplus build MythAVTest and MythWelcome as well as the frontend |
---|
275 | -enable-backend build the backend server as well as the frontend |
---|
276 | -enable-jobtools build commflag/jobqueue as well as the frontend |
---|
277 | -profile build with compile-type=profile |
---|
278 | -debug build with compile-type=debug |
---|
279 | -m32 build for a 32-bit environment |
---|
280 | -plugins <str> comma-separated list of plugins to include |
---|
281 | -srcdir <path> build using (fresh copy of) provided root mythtv directory |
---|
282 | # XXX Fix Me XXX |
---|
283 | -force do not check for SVN validity |
---|
284 | -noclean use with -nohead, do not re-run configure nor clean |
---|
285 | |
---|
286 | =head1 DESCRIPTION |
---|
287 | |
---|
288 | This script builds a MythTV frontend and all necessary dependencies, along |
---|
289 | with plugins as specified, as a standalone binary package for Mac OS X. |
---|
290 | |
---|
291 | It was designed for building daily snapshots, |
---|
292 | but can also be used to create release builds. |
---|
293 | |
---|
294 | All intermediate files go into an '.osx-packager' directory in the current |
---|
295 | working directory. The finished application is named 'MythFrontend.app' and |
---|
296 | placed in the current working directory. |
---|
297 | |
---|
298 | =head1 EXAMPLES |
---|
299 | |
---|
300 | Building two snapshots, one with plugins and one without: |
---|
301 | |
---|
302 | osx-packager.pl -clean -plugins mythvideo,mythweather |
---|
303 | mv MythFrontend.app MythFrontend-plugins.app |
---|
304 | osx-packager.pl -nohead |
---|
305 | mv MythFrontend.app MythFrontend-noplugins.app |
---|
306 | |
---|
307 | Building a "fixes" branch: |
---|
308 | |
---|
309 | osx-packager.pl -distclean |
---|
310 | osx-packager.pl -svnbranch release-0-22-fixes |
---|
311 | |
---|
312 | Note that this script will not build old branches. |
---|
313 | Please try the branched version instead. e.g. |
---|
314 | http://svn.mythtv.org/svn/branches/release-0-23-fixes/mythtv/contrib/OSX/osx-packager.pl |
---|
315 | |
---|
316 | =head1 CREDITS |
---|
317 | |
---|
318 | Written by Jeremiah Morris (jm@whpress.com) |
---|
319 | |
---|
320 | Special thanks to Nigel Pearson, Jan Ornstedt, Angel Li, and Andre Pang |
---|
321 | for help, code, and advice. |
---|
322 | |
---|
323 | Small modifications made by Bas Hulsken (bhulsken@hotmail.com) to allow building current svn, and allow lirc (if installed properly on before running script). The modifications are crappy, and should probably be revised by someone who can actually code in perl. However it works for the moment, and I wanted to share with other mac frontend experimenters! |
---|
324 | Mods for move to github, Craig Treleaven December 2010. |
---|
325 | |
---|
326 | =cut |
---|
327 | |
---|
328 | # Parse options |
---|
329 | our (%OPT); |
---|
330 | Getopt::Long::GetOptions(\%OPT, |
---|
331 | 'help|?', |
---|
332 | 'man', |
---|
333 | 'verbose', |
---|
334 | 'version=s', |
---|
335 | 'noversion', |
---|
336 | 'distclean', |
---|
337 | 'thirdclean', |
---|
338 | 'thirdskip', |
---|
339 | 'mythtvskip', |
---|
340 | 'pluginskip', |
---|
341 | 'themeskip', |
---|
342 | 'clean', |
---|
343 | 'svnbranch=s', |
---|
344 | 'svnrev=s', |
---|
345 | 'svntag=s', |
---|
346 | 'nohead', |
---|
347 | 'usehdimage', |
---|
348 | 'leavehdimage', |
---|
349 | 'enable-feplus', |
---|
350 | 'enable-backend', |
---|
351 | 'enable-jobtools', |
---|
352 | 'profile', |
---|
353 | 'debug', |
---|
354 | 'm32', |
---|
355 | 'plugins=s', |
---|
356 | 'srcdir=s', |
---|
357 | 'force', |
---|
358 | 'noclean', |
---|
359 | ) or Pod::Usage::pod2usage(2); |
---|
360 | Pod::Usage::pod2usage(1) if $OPT{'help'}; |
---|
361 | Pod::Usage::pod2usage('-verbose' => 2) if $OPT{'man'}; |
---|
362 | |
---|
363 | if ( $OPT{'enable-backend'} ) |
---|
364 | { $backend = 1 } |
---|
365 | |
---|
366 | if ( $OPT{'clean'} ) |
---|
367 | { $cleanLibs = 1 } |
---|
368 | |
---|
369 | if ( $OPT{'enable-jobtools'} ) |
---|
370 | { $jobtools = 1 } |
---|
371 | |
---|
372 | if ( $OPT{'enable-feplus'} ) # add MythAVTest and MythWelcome |
---|
373 | { $feplus = 1 } |
---|
374 | |
---|
375 | # Get version string sorted out |
---|
376 | if ( $OPT{'svntag'} && !$OPT{'version'} ) |
---|
377 | { |
---|
378 | $OPT{'version'} = $OPT{'svntag'}; |
---|
379 | $OPT{'version'} =~ s/-r *//; |
---|
380 | $OPT{'version'} =~ s/--revision *//; |
---|
381 | } |
---|
382 | $OPT{'version'} = '' if $OPT{'noversion'}; |
---|
383 | unless (defined $OPT{'version'}) |
---|
384 | { |
---|
385 | my @lt = gmtime(time); |
---|
386 | $OPT{'version'} = sprintf('git%04d%02d%02d', |
---|
387 | $lt[5] + 1900, $lt[4] + 1, $lt[3]); |
---|
388 | } |
---|
389 | |
---|
390 | if ( $OPT{'srcdir'} ) |
---|
391 | { |
---|
392 | $OPT{'nohead'} = 1; |
---|
393 | $OPT{'svnbranch'} = 0; |
---|
394 | } |
---|
395 | |
---|
396 | # Build our temp directories |
---|
397 | our $SCRIPTDIR = Cwd::abs_path(Cwd::getcwd()); |
---|
398 | if ( $SCRIPTDIR =~ /\s/ ) |
---|
399 | { |
---|
400 | &Complain(<<END); |
---|
401 | Working directory contains spaces |
---|
402 | |
---|
403 | Error: Your current working path: |
---|
404 | |
---|
405 | $SCRIPTDIR |
---|
406 | |
---|
407 | contains one or more spaces. This will break the compilation process, |
---|
408 | so the script cannot continue. Please re-run this script from a different |
---|
409 | directory (such as /tmp). |
---|
410 | |
---|
411 | The application produced will run from any directory, the no-spaces |
---|
412 | rule is only for the build process itself. |
---|
413 | |
---|
414 | END |
---|
415 | die; |
---|
416 | } |
---|
417 | |
---|
418 | if ( $OPT{'nohead'} && ! $OPT{'force'} ) |
---|
419 | { |
---|
420 | my $SVNTOP="$SCRIPTDIR/.osx-packager/src/myth-svn/mythtv/.svn"; |
---|
421 | |
---|
422 | if ( ! -d $SVNTOP ) |
---|
423 | { die "No source code to build?" } |
---|
424 | |
---|
425 | if ( ! `grep svn/trunk/mythtv $SVNTOP/entries` ) |
---|
426 | { die "Source code does not match SVN trunk" } |
---|
427 | } |
---|
428 | # |
---|
429 | # Trunk building has diverged from 0.23-fixes. After 0.24-fixes, disable this: |
---|
430 | # |
---|
431 | #elsif ( $OPT{'svnbranch'} ) |
---|
432 | #{ |
---|
433 | # &Complain(<<END); |
---|
434 | #This version of this script can not build old branches. |
---|
435 | #Please try the branched version instead. e.g. |
---|
436 | # XXX Fix Me XXX |
---|
437 | #http://svn.mythtv.org/svn/branches/release-0-23-fixes/packaging/OSX/build/osx-packager.pl |
---|
438 | #END |
---|
439 | # die; |
---|
440 | #} |
---|
441 | |
---|
442 | if ( $OPT{'svnbranch'} && $OPT{'svnbranch'} lt "release-0-24-fixes" ) |
---|
443 | { |
---|
444 | &Complain(<<END); |
---|
445 | This version of this script can not build old branches. |
---|
446 | Please try the branched version instead. e.g. |
---|
447 | # XXX Fix Me XXX |
---|
448 | http://svn.mythtv.org/svn/branches/release-0-21-fixes/mythtv/contrib/OSX/osx-packager.pl |
---|
449 | END |
---|
450 | die; |
---|
451 | } |
---|
452 | |
---|
453 | # |
---|
454 | # Same tests for fixes copy of this script: |
---|
455 | # |
---|
456 | if ( 0 ) |
---|
457 | { |
---|
458 | if ( $OPT{'nohead'} && ! $OPT{'force'} ) |
---|
459 | { |
---|
460 | my $SVNTOP="$SCRIPTDIR/.osx-packager/src/myth-svn/mythtv/.svn"; |
---|
461 | |
---|
462 | if ( ! -d $SVNTOP ) |
---|
463 | { die "No source code to build?" } |
---|
464 | |
---|
465 | if ( ! `grep 0-22-fixes $SVNTOP/entries` ) |
---|
466 | { die "Source code does not match release-0-22-fixes" } |
---|
467 | } |
---|
468 | elsif ( ! $OPT{'svnbranch'} && ! $OPT{'force'} ) |
---|
469 | { |
---|
470 | &Complain(<<END); |
---|
471 | This script can only build branch release-0-22-fixes. |
---|
472 | To build SVN HEAD, please try the latest version instead. e.g. |
---|
473 | http://svn.mythtv.org/svn/trunk/packaging/OSX/build/osx-packager.pl |
---|
474 | END |
---|
475 | die; |
---|
476 | } |
---|
477 | } |
---|
478 | |
---|
479 | our $WORKDIR = "$SCRIPTDIR/.osx-packager"; |
---|
480 | mkdir $WORKDIR; |
---|
481 | |
---|
482 | # Do we need to force a case-sensitive disk image? |
---|
483 | if (0 && # No. MythTV source doesn't require it at the moment. |
---|
484 | !$OPT{usehdimage} && !CaseSensitiveFilesystem()) |
---|
485 | { |
---|
486 | Verbose("Forcing -usehdimage due to case-insensitive filesystem"); |
---|
487 | $OPT{usehdimage} = 1; |
---|
488 | } |
---|
489 | |
---|
490 | if ($OPT{usehdimage}) |
---|
491 | { MountHDImage() } |
---|
492 | |
---|
493 | our $PREFIX = "$WORKDIR/build"; |
---|
494 | mkdir $PREFIX; |
---|
495 | |
---|
496 | our $SRCDIR = "$WORKDIR/src"; |
---|
497 | mkdir $SRCDIR; |
---|
498 | |
---|
499 | #our $SVNDIR = "$SRCDIR/myth-svn"; |
---|
500 | our $MYTHSRCDIR = "$SRCDIR/mythtv"; |
---|
501 | |
---|
502 | our @pluginConf; |
---|
503 | if ( $OPT{plugins} ) |
---|
504 | { |
---|
505 | @pluginConf = split /,/, $OPT{plugins}; |
---|
506 | @pluginConf = grep(s/^/--enable-/, @pluginConf); |
---|
507 | unshift @pluginConf, '--disable-all'; |
---|
508 | } |
---|
509 | else |
---|
510 | { |
---|
511 | @pluginConf = ( |
---|
512 | '--enable-opengl', |
---|
513 | '--enable-mythgallery', |
---|
514 | '--enable-exif', |
---|
515 | '--enable-new-exif', |
---|
516 | ); |
---|
517 | } |
---|
518 | |
---|
519 | |
---|
520 | # configure mythplugins, and mythtv, etc |
---|
521 | our %conf = ( |
---|
522 | 'mythplugins' |
---|
523 | => [ |
---|
524 | '--prefix=' . $PREFIX, |
---|
525 | # '--extra-cflags=-I/opt/local/include', |
---|
526 | # '--extra-ldflags=-L/opt/local/lib', |
---|
527 | @pluginConf |
---|
528 | ], |
---|
529 | 'myththemes' |
---|
530 | => [ |
---|
531 | '--prefix=' . $PREFIX, |
---|
532 | ], |
---|
533 | 'mythtv' |
---|
534 | => [ |
---|
535 | '--prefix=' . $PREFIX, |
---|
536 | '--runprefix=../Resources', |
---|
537 | # '--extra-cflags=-I/opt/local/include', |
---|
538 | # '--extra-ldflags=-L/opt/local/lib', |
---|
539 | |
---|
540 | # To "cross compile" something for a lesser Mac: |
---|
541 | #'--tune=G3', |
---|
542 | #'--disable-altivec', |
---|
543 | |
---|
544 | # Currently needed for Mac OS 10.6 builds? |
---|
545 | #WCT'--disable-mmx', '--enable-disable-mmx-for-debugging', |
---|
546 | ], |
---|
547 | ); |
---|
548 | |
---|
549 | # configure mythplugins, and mythtv, etc |
---|
550 | our %makecleanopt = ( |
---|
551 | 'mythplugins' |
---|
552 | => [ |
---|
553 | 'distclean', |
---|
554 | ], |
---|
555 | ); |
---|
556 | |
---|
557 | # Source code version.pro needs to call subversion binary |
---|
558 | # |
---|
559 | |
---|
560 | use File::Basename; |
---|
561 | |
---|
562 | our $gitpath = dirname $git; |
---|
563 | our $MYTHBRANCH = 'fixes/0.24'; # assume master is the default |
---|
564 | |
---|
565 | # Clean the environment |
---|
566 | $ENV{'PATH'} = "$PREFIX/bin:/bin:/usr/bin:/usr/sbin:/usr/local/bin:$gitpath"; |
---|
567 | $ENV{'PKG_CONFIG_PATH'} = "$PREFIX/lib/pkgconfig:"; |
---|
568 | #$ENV{'PATH'} = "$PREFIX/bin:/opt/local/bin:/bin:/usr/bin:/usr/sbin:$gitpath"; |
---|
569 | #$ENV{'PKG_CONFIG_PATH'} = "$PREFIX/lib/pkgconfig:/opt/local/bin:"; |
---|
570 | delete $ENV{'CC'}; |
---|
571 | delete $ENV{'CXX'}; |
---|
572 | delete $ENV{'CPP'}; |
---|
573 | delete $ENV{'CXXCPP'}; |
---|
574 | $ENV{'CFLAGS'} = $ENV{'CXXFLAGS'} = $ENV{'CPPFLAGS'} = "-I$PREFIX/include"; |
---|
575 | $ENV{'LDFLAGS'} = "-F/System/Library/Frameworks -L/usr/lib -L$PREFIX/lib"; |
---|
576 | #$ENV{'CFLAGS'} = $ENV{'CXXFLAGS'} = $ENV{'CPPFLAGS'} = "-I$PREFIX/include -I/opt/local/include"; |
---|
577 | #$ENV{'LDFLAGS'} = "-F/System/Library/Frameworks -L/usr/lib -L$PREFIX/lib -L/opt/local/lib"; |
---|
578 | $ENV{'PREFIX'} = $PREFIX; |
---|
579 | |
---|
580 | # set up Qt environment |
---|
581 | $ENV{'QTDIR'} = $PREFIX; |
---|
582 | |
---|
583 | # If environment is setup to use distcc, take advantage of it |
---|
584 | our $standard_make = '/usr/bin/make'; |
---|
585 | our $parallel_make = $standard_make; |
---|
586 | our $parallel_make_flags = ''; |
---|
587 | |
---|
588 | if ( $ENV{'DISTCC_HOSTS'} ) |
---|
589 | { |
---|
590 | my @hosts = split m/\s+/, $ENV{'DISTCC_HOSTS'}; |
---|
591 | my $numhosts = $#hosts + 1; |
---|
592 | &Verbose("Using ", $numhosts * 2, " DistCC jobs on $numhosts build hosts:", |
---|
593 | join ', ', @hosts); |
---|
594 | $parallel_make_flags = '-j' . $numhosts * 2; |
---|
595 | } |
---|
596 | |
---|
597 | # Ditto for multi-cpu setups: |
---|
598 | my $cmd = "/usr/bin/hostinfo | grep 'processors\$'"; |
---|
599 | &Verbose($cmd); |
---|
600 | my $cpus = `$cmd`; chomp $cpus; |
---|
601 | $cpus =~ s/.*, (\d+) processors$/$1/; |
---|
602 | if ( $cpus gt 1 ) |
---|
603 | { |
---|
604 | &Verbose("Using", $cpus+1, "jobs on $cpus parallel CPUs"); |
---|
605 | ++$cpus; |
---|
606 | $parallel_make_flags = "-j$cpus"; |
---|
607 | } |
---|
608 | |
---|
609 | $parallel_make .= " $parallel_make_flags"; |
---|
610 | |
---|
611 | # Auto-disable mixed 64/32bit: |
---|
612 | if ( `sysctl -n hw.cpu64bit_capable` eq "1\n" ) |
---|
613 | { |
---|
614 | &Verbose('OS is 64bit. Disabling 64bit for this build...'); |
---|
615 | $OPT{'m32'} = 1; |
---|
616 | } |
---|
617 | |
---|
618 | # We set 32-bit mode via environment variables. |
---|
619 | # The messier alternative would be to tweak all the configure arguments. |
---|
620 | if ( $OPT{'m32'} ) |
---|
621 | { |
---|
622 | &Verbose('Forcing 32-bit mode'); |
---|
623 | $ENV{'CFLAGS'} .= ' -m32'; |
---|
624 | $ENV{'CPPFLAGS'} .= ' -m32'; |
---|
625 | $ENV{'CXXFLAGS'} .= ' -m32'; |
---|
626 | $ENV{'ECXXFLAGS'} .= ' -m32'; # MythTV configure |
---|
627 | $ENV{'LDFLAGS'} .= ' -m32'; |
---|
628 | } |
---|
629 | |
---|
630 | ### Distclean? |
---|
631 | if ( $OPT{'distclean'} ) |
---|
632 | { |
---|
633 | &Syscall([ '/bin/rm', '-f', '$PREFIX/bin/myth*' ]); |
---|
634 | &Syscall([ '/bin/rm', '-f', '-r', '$PREFIX/lib/libmyth*' ]); |
---|
635 | &Syscall([ '/bin/rm', '-f', '-r', '$PREFIX/lib/mythtv' ]); |
---|
636 | &Syscall([ '/bin/rm', '-f', '-r', '$PREFIX/share/mythtv' ]); |
---|
637 | &Syscall([ 'find', $MYTHSRCDIR, '-name', '*.o', '-delete' ]); |
---|
638 | &Syscall([ 'find', $MYTHSRCDIR, '-name', '*.a', '-delete' ]); |
---|
639 | &Syscall([ 'find', $MYTHSRCDIR, '-name', '*.dylib', '-delete' ]); |
---|
640 | &Syscall([ 'find', $MYTHSRCDIR, '-name', '*.orig', '-delete' ]); |
---|
641 | &Syscall([ 'find', $MYTHSRCDIR, '-name', '*.rej', '-delete' ]); |
---|
642 | exit; |
---|
643 | } |
---|
644 | |
---|
645 | ### Check for app present in target location |
---|
646 | our $MFE = "$SCRIPTDIR/MythFrontend.app"; |
---|
647 | if ( -d $MFE ) |
---|
648 | { |
---|
649 | &Complain(<<END); |
---|
650 | $MFE already exists |
---|
651 | |
---|
652 | Error: a MythFrontend application exists where we were planning |
---|
653 | to build one. Please move this application away before running |
---|
654 | this script. |
---|
655 | |
---|
656 | END |
---|
657 | exit; |
---|
658 | } |
---|
659 | |
---|
660 | ### Third party packages |
---|
661 | my ( @build_depends, %seen_depends ); |
---|
662 | my @comps = ( 'mythtv', @components, 'packaging' ); |
---|
663 | |
---|
664 | # Deal with user-supplied skip arguments |
---|
665 | if ( $OPT{'mythtvskip'} ) |
---|
666 | { @comps = grep(!m/mythtv/, @comps) } |
---|
667 | if ( $OPT{'pluginskip'} ) |
---|
668 | { @comps = grep(!m/mythplugins/, @comps) } |
---|
669 | if ( $OPT{'themeskip'} ) |
---|
670 | { @comps = grep(!m/myththemes/, @comps) } |
---|
671 | |
---|
672 | if ( ! @comps ) |
---|
673 | { |
---|
674 | &Complain("Nothing to build! Too many ...skip arguments?"); |
---|
675 | exit; |
---|
676 | } |
---|
677 | |
---|
678 | &Verbose("Including components:", @comps); |
---|
679 | |
---|
680 | foreach my $comp (@comps) |
---|
681 | { |
---|
682 | foreach my $dep (@{ $depend_order{$comp} }) |
---|
683 | { |
---|
684 | unless (exists $seen_depends{$dep}) |
---|
685 | { |
---|
686 | push(@build_depends, $dep); |
---|
687 | $seen_depends{$dep} = 1; |
---|
688 | } |
---|
689 | } |
---|
690 | } |
---|
691 | foreach my $sw ( @build_depends ) |
---|
692 | { |
---|
693 | # Get info about this package |
---|
694 | my $pkg = $depend{$sw}; |
---|
695 | my $url = $pkg->{'url'}; |
---|
696 | my $filename = $url; |
---|
697 | $filename =~ s|^.+/([^/]+)$|$1|; |
---|
698 | my $dirname = $filename; |
---|
699 | $dirname =~ s|\.tar\.gz$||; |
---|
700 | $dirname =~ s|\.tar\.bz2$||; |
---|
701 | |
---|
702 | chdir($SRCDIR); |
---|
703 | |
---|
704 | # Download and decompress |
---|
705 | unless ( -e $filename ) |
---|
706 | { |
---|
707 | &Verbose("Downloading $sw"); |
---|
708 | unless (&Syscall([ '/usr/bin/curl', '-f', '-L', $url, '>', $filename ], |
---|
709 | 'munge' => 1)) |
---|
710 | { |
---|
711 | &Syscall([ '/bin/rm', $filename ]) if (-e $filename); |
---|
712 | die; |
---|
713 | } |
---|
714 | } |
---|
715 | else |
---|
716 | { &Verbose("Using previously downloaded $sw") } |
---|
717 | |
---|
718 | if ( $pkg->{'skip'} ) |
---|
719 | { next } |
---|
720 | |
---|
721 | if ( -d $dirname ) |
---|
722 | { |
---|
723 | if ( $OPT{'thirdclean'} ) |
---|
724 | { |
---|
725 | &Verbose("Removing previous build of $sw"); |
---|
726 | &Syscall([ '/bin/rm', '-f', '-r', $dirname ]) or die; |
---|
727 | } |
---|
728 | |
---|
729 | if ( $OPT{'thirdskip'} ) |
---|
730 | { |
---|
731 | &Verbose("Using previous build of $sw"); |
---|
732 | next; |
---|
733 | } |
---|
734 | |
---|
735 | &Verbose("Using previously unpacked $sw"); |
---|
736 | } |
---|
737 | else |
---|
738 | { |
---|
739 | &Verbose("Unpacking $sw"); |
---|
740 | if ( substr($filename,-3) eq ".gz" ) |
---|
741 | { &Syscall([ '/usr/bin/tar', '-xzf', $filename ]) or die } |
---|
742 | elsif ( substr($filename,-4) eq ".bz2" ) |
---|
743 | { &Syscall([ '/usr/bin/tar', '-xjf', $filename ]) or die } |
---|
744 | else |
---|
745 | { |
---|
746 | &Complain("Cannot unpack file $filename"); |
---|
747 | exit; |
---|
748 | } |
---|
749 | } |
---|
750 | |
---|
751 | # Configure |
---|
752 | chdir($dirname); |
---|
753 | unless (-e '.osx-config') |
---|
754 | { |
---|
755 | &Verbose("Configuring $sw"); |
---|
756 | if ( $pkg->{'pre-conf'} ) |
---|
757 | { &Syscall([ $pkg->{'pre-conf'} ], 'munge' => 1) or die } |
---|
758 | |
---|
759 | my (@configure, $munge); |
---|
760 | |
---|
761 | if ( $pkg->{'conf-cmd'} ) |
---|
762 | { |
---|
763 | push(@configure, $pkg->{'conf-cmd'}); |
---|
764 | $munge = 1; |
---|
765 | } |
---|
766 | else |
---|
767 | { |
---|
768 | push(@configure, './configure', |
---|
769 | '--prefix=$PREFIX', |
---|
770 | '--disable-static', |
---|
771 | '--enable-shared'); |
---|
772 | } |
---|
773 | if ( $pkg->{'conf'} ) |
---|
774 | { |
---|
775 | push(@configure, @{ $pkg->{'conf'} }); |
---|
776 | } |
---|
777 | &Syscall(\@configure, 'interpolate' => 1, 'munge' => $munge) or die; |
---|
778 | if ( $pkg->{'post-conf'} ) |
---|
779 | { |
---|
780 | &Syscall([ $pkg->{'post-conf'} ], 'munge' => 1) or die; |
---|
781 | } |
---|
782 | &Syscall([ '/usr/bin/touch', '.osx-config' ]) or die; |
---|
783 | } |
---|
784 | else |
---|
785 | { &Verbose("Using previously configured $sw") } |
---|
786 | |
---|
787 | # Build and install |
---|
788 | unless (-e '.osx-built') |
---|
789 | { |
---|
790 | &Verbose("Making $sw"); |
---|
791 | my (@make); |
---|
792 | |
---|
793 | push(@make, $standard_make); |
---|
794 | if ( $pkg->{'parallel-make'} && $parallel_make_flags ) |
---|
795 | { push(@make, $parallel_make_flags) } |
---|
796 | |
---|
797 | if ( $pkg->{'make'} ) |
---|
798 | { push(@make, @{ $pkg->{'make'} }) } |
---|
799 | else |
---|
800 | { push(@make, 'all', 'install') } |
---|
801 | |
---|
802 | &Syscall(\@make) or die; |
---|
803 | if ( $pkg->{'post-make'} ) |
---|
804 | { |
---|
805 | &Syscall([ $pkg->{'post-make'} ], 'munge' => 1) or die; |
---|
806 | } |
---|
807 | &Syscall([ '/usr/bin/touch', '.osx-built' ]) or die; |
---|
808 | } |
---|
809 | else |
---|
810 | { |
---|
811 | &Verbose("Using previously built $sw"); |
---|
812 | } |
---|
813 | } |
---|
814 | |
---|
815 | |
---|
816 | ### build MythTV |
---|
817 | |
---|
818 | # Clean any previously installed libraries |
---|
819 | if ( $cleanLibs ) |
---|
820 | { |
---|
821 | if ( $OPT{'mythtvskip'} ) |
---|
822 | { |
---|
823 | &Complain("Cannot skip building mythtv src if also cleaning"); |
---|
824 | exit; |
---|
825 | } |
---|
826 | &Verbose("Cleaning previous installs of MythTV"); |
---|
827 | my @mythlibs = glob "$PREFIX/lib/libmyth*"; |
---|
828 | if ( scalar @mythlibs ) |
---|
829 | { |
---|
830 | &Syscall([ '/bin/rm', @mythlibs ]) or die; |
---|
831 | } |
---|
832 | foreach my $dir ('include', 'lib', 'share') |
---|
833 | { |
---|
834 | if ( -d "$PREFIX/$dir/mythtv" ) |
---|
835 | { |
---|
836 | &Syscall([ '/bin/rm', '-f', '-r', "$PREFIX/$dir/mythtv" ]) or die; |
---|
837 | } |
---|
838 | } |
---|
839 | } |
---|
840 | |
---|
841 | # mkdir $SVNDIR; # Not necessary, Git creates |
---|
842 | |
---|
843 | # |
---|
844 | # Work out Subversion branches, revisions and tags. |
---|
845 | # Note these vars are unused if nohead or srcdir set! |
---|
846 | # |
---|
847 | my $svnrepository = 'http://svn.mythtv.org/svn/'; |
---|
848 | my @svnrevision = (); |
---|
849 | |
---|
850 | if ( $OPT{'svnbranch'} ) |
---|
851 | { |
---|
852 | $svnrepository .= 'branches/' . $OPT{'svnbranch'} . '/'; |
---|
853 | } |
---|
854 | elsif ( $OPT{'svntag'} ) |
---|
855 | { |
---|
856 | $svnrepository .= 'tags/' . $OPT{'svntag'} . '/'; |
---|
857 | } |
---|
858 | elsif ( $OPT{'svnrev'} ) |
---|
859 | { |
---|
860 | $svnrepository .= 'trunk/'; |
---|
861 | |
---|
862 | # This arg. could be '1234', '-r 1234', or '--revision 1234' |
---|
863 | # If the user just specified a number, add appropriate flag: |
---|
864 | if ( $OPT{'svnrev'} =~ m/^\d+$/ ) |
---|
865 | { |
---|
866 | push @svnrevision, '--revision'; |
---|
867 | } |
---|
868 | |
---|
869 | push @svnrevision, $OPT{'svnrev'}; |
---|
870 | } |
---|
871 | #elsif ( ! $OPT{'nohead'} ) |
---|
872 | #{ |
---|
873 | # # Lookup and use the HEAD revision so we are guaranteed consistent source |
---|
874 | # my $cmd = "$svn log $svnrepository --revision HEAD --xml | grep revision"; |
---|
875 | # &Verbose($cmd); |
---|
876 | # my $rev = `$cmd`; |
---|
877 | # |
---|
878 | # if ( $rev =~ m/revision="(\d+)">/ ) |
---|
879 | # { |
---|
880 | # $svnrepository .= 'trunk/'; |
---|
881 | # @svnrevision = ('--revision', $1); |
---|
882 | # } |
---|
883 | # else |
---|
884 | # { |
---|
885 | # &Complain("Cannot get head revision - Got '$rev'"); |
---|
886 | # die; |
---|
887 | # } |
---|
888 | #} |
---|
889 | |
---|
890 | # Retrieve source |
---|
891 | if ( $OPT{'srcdir'} ) |
---|
892 | { |
---|
893 | chdir($SCRIPTDIR); |
---|
894 | &Syscall(['rm', '-fr', $MYTHSRCDIR]); |
---|
895 | &Syscall(['mkdir', '-p', $MYTHSRCDIR]); |
---|
896 | foreach my $dir ('mythtv', 'mythplugins', |
---|
897 | 'myththemes', 'themes', 'packaging') |
---|
898 | { |
---|
899 | &Syscall(['cp', '-pR', "$OPT{'srcdir'}/$dir", "$MYTHSRCDIR/$dir"]); |
---|
900 | } |
---|
901 | &Syscall("mkdir -p $MYTHSRCDIR/mythtv/config") |
---|
902 | } |
---|
903 | elsif ( ! $OPT{'nohead'} ) |
---|
904 | ###################################################################### |
---|
905 | # Get the code via Git |
---|
906 | # only do 'git clone' if mythtv directory does not exist. |
---|
907 | # always do 'git checkout' to make sure we have the right branch. |
---|
908 | # then 'git pull' to get up to date. |
---|
909 | ###################################################################### |
---|
910 | { |
---|
911 | chdir($SCRIPTDIR); |
---|
912 | &Syscall(['rm', '-fr', $MYTHSRCDIR . '/mythtv/config']); |
---|
913 | if ( ! -e $MYTHSRCDIR ) |
---|
914 | { |
---|
915 | &Syscall([ $git, 'clone', 'git://github.com/MythTV/mythtv.git', |
---|
916 | $MYTHSRCDIR ]) or die; |
---|
917 | } |
---|
918 | if ( ! -e "$MYTHSRCDIR/packaging" ) |
---|
919 | { |
---|
920 | &Syscall([ $git, 'clone', 'git://github.com/MythTV/packaging.git', |
---|
921 | $MYTHSRCDIR . '/packaging' ]) or die; |
---|
922 | } |
---|
923 | |
---|
924 | chdir($MYTHSRCDIR); |
---|
925 | &Syscall([ $git, 'checkout', $MYTHBRANCH]) or die; |
---|
926 | &Syscall([ $git, 'pull']) or die; |
---|
927 | chdir("$MYTHSRCDIR/packaging"); |
---|
928 | &Syscall([ $git, 'checkout', $MYTHBRANCH]) or die; |
---|
929 | &Syscall([ $git, 'pull']) or die; |
---|
930 | } |
---|
931 | else |
---|
932 | { &Syscall("mkdir -p $MYTHSRCDIR/mythtv/config") } |
---|
933 | |
---|
934 | # Make a convenience (non-hidden) directory for editing src code: |
---|
935 | system("ln -sf $MYTHSRCDIR $SCRIPTDIR/src"); |
---|
936 | |
---|
937 | # Build MythTV and any plugins |
---|
938 | foreach my $comp (@comps) |
---|
939 | { |
---|
940 | my $compdir = "$MYTHSRCDIR/$comp/" ; |
---|
941 | |
---|
942 | chdir $compdir; |
---|
943 | |
---|
944 | if ( ! -e "$comp.pro" and ! -e 'Makefile' and ! -e 'configure' ) |
---|
945 | { |
---|
946 | &Complain("Nothing to configure/make in $compdir"); |
---|
947 | next; |
---|
948 | } |
---|
949 | |
---|
950 | if ( $OPT{'clean'} && -e 'Makefile' ) |
---|
951 | { |
---|
952 | &Verbose("Cleaning $comp"); |
---|
953 | &Syscall([ $standard_make, 'distclean' ]) or die; |
---|
954 | } |
---|
955 | #else |
---|
956 | #{ |
---|
957 | # # clean the Makefiles, as process requires PREFIX hacking |
---|
958 | # &CleanMakefiles(); |
---|
959 | #} |
---|
960 | |
---|
961 | # Apply any nasty mac-specific patches |
---|
962 | if ( $patches{$comp} ) |
---|
963 | { |
---|
964 | &Syscall([ "echo '$patches{$comp}' | patch -p0 --forward" ]); |
---|
965 | } |
---|
966 | |
---|
967 | # configure and make |
---|
968 | if ( $makecleanopt{$comp} && -e 'Makefile' && ! $OPT{'noclean'} ) |
---|
969 | { |
---|
970 | my @makecleancom = $standard_make; |
---|
971 | push(@makecleancom, @{ $makecleanopt{$comp} }) if $makecleanopt{$comp}; |
---|
972 | &Syscall([ @makecleancom ]) or die; |
---|
973 | } |
---|
974 | if ( -e 'configure' && ! $OPT{'noclean'} ) |
---|
975 | { |
---|
976 | &Verbose("Configuring $comp"); |
---|
977 | my @config = './configure'; |
---|
978 | push(@config, @{ $conf{$comp} }) if $conf{$comp}; |
---|
979 | if ( $comp eq 'mythtv' && $backend ) |
---|
980 | { |
---|
981 | push @config, '--enable-backend' |
---|
982 | } |
---|
983 | if ( $OPT{'profile'} ) |
---|
984 | { |
---|
985 | push @config, '--compile-type=profile' |
---|
986 | } |
---|
987 | if ( $OPT{'debug'} ) |
---|
988 | { |
---|
989 | push @config, '--compile-type=debug' |
---|
990 | } |
---|
991 | if ( $comp eq 'mythtv' && ! $ENV{'DISTCC_HOSTS'} ) |
---|
992 | { |
---|
993 | push @config, '--disable-distcc' |
---|
994 | } |
---|
995 | &Syscall([ @config ]) or die; |
---|
996 | } |
---|
997 | if ( -e "$comp.pro" ) |
---|
998 | { |
---|
999 | &Verbose("Running qmake for $comp"); |
---|
1000 | my @qmake_opts = ( |
---|
1001 | 'QMAKE_LFLAGS+=-Wl,-search_paths_first', |
---|
1002 | 'INCLUDEPATH+="' . $PREFIX . '/include"', |
---|
1003 | 'LIBS+=-L/usr/lib -L"' . $PREFIX . '/lib"' |
---|
1004 | ); |
---|
1005 | &Syscall([ $PREFIX . '/bin/qmake', |
---|
1006 | 'PREFIX=../Resources', |
---|
1007 | @qmake_opts, |
---|
1008 | "$comp.pro" ]) or die; |
---|
1009 | } |
---|
1010 | if ( $comp eq 'mythtv' ) |
---|
1011 | { |
---|
1012 | # Remove/add Nigel's frontend building speedup hack |
---|
1013 | &DoSpeedupHacks('programs/programs.pro', 'mythfrontend mythavtest'); |
---|
1014 | } |
---|
1015 | |
---|
1016 | &Verbose("Making $comp"); |
---|
1017 | &Syscall([ $parallel_make ]) or die; |
---|
1018 | # # install |
---|
1019 | # # This requires a change from the compiled-in relative |
---|
1020 | # # PREFIX to our absolute path of the temp install location. |
---|
1021 | # &CleanMakefiles(); |
---|
1022 | # &Verbose("Running qmake for $comp install"); |
---|
1023 | # &Syscall([ $PREFIX . '/bin/qmake', |
---|
1024 | # 'PREFIX=' . $PREFIX, |
---|
1025 | # @qmake_opts, |
---|
1026 | # "$comp.pro" ]) or die; |
---|
1027 | &Verbose("Installing $comp"); |
---|
1028 | &Syscall([ $standard_make, |
---|
1029 | 'install' ]) or die; |
---|
1030 | |
---|
1031 | if ( $cleanLibs && $comp eq 'mythtv' ) |
---|
1032 | { |
---|
1033 | # If we cleaned the libs, make install will have recopied them, |
---|
1034 | # which means any dynamic libraries that the static libraries depend on |
---|
1035 | # are newer than the table of contents. Hence we need to regenerate it: |
---|
1036 | my @mythlibs = glob "$PREFIX/lib/libmyth*.a"; |
---|
1037 | if ( scalar @mythlibs ) |
---|
1038 | { |
---|
1039 | &Verbose("Running ranlib on reinstalled static libraries"); |
---|
1040 | foreach my $lib (@mythlibs) |
---|
1041 | { &Syscall("ranlib $lib") or die } |
---|
1042 | } |
---|
1043 | } |
---|
1044 | } |
---|
1045 | |
---|
1046 | ### Build version string |
---|
1047 | our $VERS = `find $PREFIX/lib -name 'libmyth-[0-9].[0-9][0-9].[0-9].dylib'`; |
---|
1048 | chomp $VERS; |
---|
1049 | $VERS =~ s/^.*\-(.*)\.dylib$/$1/s; |
---|
1050 | $VERS .= '.' . $OPT{'version'} if $OPT{'version'}; |
---|
1051 | |
---|
1052 | ### Program which creates bundles: |
---|
1053 | our @bundler = "$MYTHSRCDIR/packaging/OSX/build/osx-bundler.pl"; |
---|
1054 | if ( $OPT{'verbose'} ) |
---|
1055 | { push @bundler, '--verbose' } |
---|
1056 | |
---|
1057 | |
---|
1058 | ### Framework that has a screwed up link dependency path |
---|
1059 | my $AVCfw = '/Developer/FireWireSDK*/Examples/' . |
---|
1060 | 'Framework/AVCVideoServices.framework'; |
---|
1061 | my @AVCfw = split / /, `ls -d $AVCfw`; |
---|
1062 | $AVCfw = pop @AVCfw; |
---|
1063 | chop $AVCfw; |
---|
1064 | |
---|
1065 | ### Create each package. |
---|
1066 | ### Note that this is a bit of a waste of disk space, |
---|
1067 | ### because there are now multiple copies of each library. |
---|
1068 | |
---|
1069 | if ( $jobtools ) |
---|
1070 | { push @targets, @targetsJT } |
---|
1071 | |
---|
1072 | if ( $feplus ) |
---|
1073 | { push @targets, @targetTW } |
---|
1074 | |
---|
1075 | if ( $backend ) |
---|
1076 | { push @targets, @targetsBE } |
---|
1077 | |
---|
1078 | foreach my $target ( @targets ) |
---|
1079 | { |
---|
1080 | my $finalTarget = "$SCRIPTDIR/$target.app"; |
---|
1081 | my $builtTarget = lc $target; |
---|
1082 | |
---|
1083 | # Get a fresh copy of the binary |
---|
1084 | &Verbose("Building self-contained $target"); |
---|
1085 | &Syscall([ 'rm', '-fr', $finalTarget ]) or die; |
---|
1086 | &Syscall([ 'cp', "$MYTHSRCDIR/mythtv/programs/$builtTarget/$builtTarget", |
---|
1087 | "$SCRIPTDIR/$target" ]) or die; |
---|
1088 | |
---|
1089 | # Convert it to a bundled .app |
---|
1090 | &Syscall([ @bundler, "$SCRIPTDIR/$target", |
---|
1091 | "$PREFIX/lib/", "$PREFIX/lib/mysql" ]) or die; |
---|
1092 | |
---|
1093 | # Remove copy of binary |
---|
1094 | unlink "$SCRIPTDIR/$target" or die; |
---|
1095 | |
---|
1096 | if ( $AVCfw ) |
---|
1097 | { &RecursiveCopy($AVCfw, "$finalTarget/Contents/Frameworks") } |
---|
1098 | |
---|
1099 | # Themes are required by all GUI apps. The filters and plugins are not |
---|
1100 | # used by mythtv-setup or mythwelcome, but for simplicity, do them all. |
---|
1101 | if ( $target eq "MythAVTest" or $target eq "MythFrontend" or |
---|
1102 | $target eq "MythWelcome" or $target =~ m/^MythTV-/ ) |
---|
1103 | { |
---|
1104 | my $res = "$finalTarget/Contents/Resources"; |
---|
1105 | my $libs = "$res/lib"; |
---|
1106 | my $plug = "$libs/mythtv/plugins"; |
---|
1107 | |
---|
1108 | # Install themes, filters, etc. |
---|
1109 | &Verbose("Installing resources into $target"); |
---|
1110 | mkdir $res; mkdir $libs; |
---|
1111 | &RecursiveCopy("$PREFIX/lib/mythtv", $libs); |
---|
1112 | mkdir "$res/share"; |
---|
1113 | &RecursiveCopy("$PREFIX/share/mythtv", "$res/share"); |
---|
1114 | |
---|
1115 | # Correct the library paths for the filters and plugins |
---|
1116 | foreach my $lib ( glob "$libs/mythtv/*/*" ) |
---|
1117 | { &Syscall([ @bundler, $lib, "$PREFIX/lib/" ]) or die } |
---|
1118 | |
---|
1119 | if ( -e $plug ) |
---|
1120 | { |
---|
1121 | # Allow Finder's 'Get Info' to manage plugin list: |
---|
1122 | &Syscall([ 'mv', $plug, "$finalTarget/Contents/Plugins" ]) or die; |
---|
1123 | &Syscall([ 'ln', '-s', "../../../Plugins", $plug ]) or die; |
---|
1124 | } |
---|
1125 | |
---|
1126 | # The icon |
---|
1127 | &Syscall([ 'cp', |
---|
1128 | "$MYTHSRCDIR/mythtv/programs/mythfrontend/mythfrontend.icns", |
---|
1129 | "$res/application.icns" ]) or die; |
---|
1130 | &Syscall([ '/Developer/Tools/SetFile', '-a', 'C', $finalTarget ]) |
---|
1131 | or die; |
---|
1132 | } |
---|
1133 | |
---|
1134 | if ( $target eq "MythFrontend" ) |
---|
1135 | { |
---|
1136 | foreach my $extra ( 'ignyte', 'mythpreviewgen', 'mtd' ) |
---|
1137 | { |
---|
1138 | if ( -e "$PREFIX/bin/$extra" ) |
---|
1139 | { |
---|
1140 | &Verbose("Installing $extra into $target"); |
---|
1141 | &Syscall([ 'cp', "$PREFIX/bin/$extra", |
---|
1142 | "$finalTarget/Contents/MacOS" ]) or die; |
---|
1143 | |
---|
1144 | &Verbose('Updating lib paths of', |
---|
1145 | "$finalTarget/Contents/MacOS/$extra"); |
---|
1146 | &Syscall([ @bundler, "$finalTarget/Contents/MacOS/$extra" ]) |
---|
1147 | or die; |
---|
1148 | &AddFakeBinDir($finalTarget); |
---|
1149 | } |
---|
1150 | } |
---|
1151 | |
---|
1152 | # Allow playback of region encoded DVDs |
---|
1153 | mkdir("$finalTarget/Contents/Plugins"); |
---|
1154 | &Syscall([ 'cp', "$PREFIX/lib/libdvdcss.2.dylib", |
---|
1155 | "$finalTarget/Contents/Plugins" ]) or die; |
---|
1156 | |
---|
1157 | # Allow opening of GIFs and JPEGs: |
---|
1158 | mkdir("$finalTarget/Contents/MacOS/imageformats"); |
---|
1159 | foreach my $plugin ( 'libqgif.dylib', 'libqjpeg.dylib' ) |
---|
1160 | { |
---|
1161 | my $pluginSrc = "$PREFIX/plugins/imageformats/$plugin"; |
---|
1162 | if ( -e $pluginSrc ) |
---|
1163 | { |
---|
1164 | &Syscall([ 'cp', $pluginSrc, |
---|
1165 | "$finalTarget/Contents/MacOS/imageformats" ]) |
---|
1166 | or die; |
---|
1167 | &Syscall([ @bundler, |
---|
1168 | "$finalTarget/Contents/MacOS/imageformats/$plugin" ]) |
---|
1169 | or die; |
---|
1170 | } |
---|
1171 | } |
---|
1172 | } |
---|
1173 | |
---|
1174 | if ( $target eq "MythWelcome" ) |
---|
1175 | { |
---|
1176 | &Verbose("Installing mythfrontend into $target"); |
---|
1177 | &Syscall([ 'cp', "$PREFIX/bin/mythfrontend", |
---|
1178 | "$finalTarget/Contents/MacOS" ]) or die; |
---|
1179 | &Syscall([ @bundler, "$finalTarget/Contents/MacOS/mythfrontend" ]) |
---|
1180 | or die; |
---|
1181 | &AddFakeBinDir($finalTarget); |
---|
1182 | |
---|
1183 | # For some unknown reason, mythfrontend looks here for support files: |
---|
1184 | &Syscall([ 'ln', '-s', "../Resources/share", # themes |
---|
1185 | "../Resources/lib", # filters/plugins |
---|
1186 | "$finalTarget/Contents/MacOS" ]) or die; |
---|
1187 | } |
---|
1188 | |
---|
1189 | # Run 'rebase' on all the frameworks: |
---|
1190 | my @libs = glob "$finalTarget/Contents/Frameworks/*"; |
---|
1191 | @libs = grep(s,(.*/)(\w+).framework$,$1$2.framework/Versions/A/$2, , @libs); # WCT mod |
---|
1192 | # @libs = grep(s,(.*/)(\w+).framework$,$1$2.framework/$2, , @libs); |
---|
1193 | # and all the filters/plugins: |
---|
1194 | push(@libs, glob "$finalTarget/Contents/Resources/lib/mythtv/*/*"); |
---|
1195 | if ( $OPT{'verbose'} ) |
---|
1196 | { &Syscall([ 'rebase', '-v', @libs ]) or die } |
---|
1197 | else |
---|
1198 | { &Syscall([ 'rebase', @libs ]) or die } |
---|
1199 | } |
---|
1200 | |
---|
1201 | if ( $backend && grep(m/MythBackend/, @targets) ) |
---|
1202 | { |
---|
1203 | my $BE = "$SCRIPTDIR/MythBackend.app"; |
---|
1204 | |
---|
1205 | # Copy XML files that UPnP requires: |
---|
1206 | my $share = "$BE/Contents/Resources/share/mythtv"; |
---|
1207 | &Syscall([ 'mkdir', '-p', $share ]) or die; |
---|
1208 | &Syscall([ 'cp', glob("$PREFIX/share/mythtv/*.xml"), $share ]) or die; |
---|
1209 | |
---|
1210 | # The backend gets all the useful binaries it might call: |
---|
1211 | foreach my $binary ( 'mythjobqueue', 'mythcommflag', |
---|
1212 | 'mythtranscode', 'mythfilldatabase' ) |
---|
1213 | { |
---|
1214 | my $SRC = "$PREFIX/bin/$binary"; |
---|
1215 | if ( -e $SRC ) |
---|
1216 | { |
---|
1217 | &Verbose("Installing $SRC into $BE"); |
---|
1218 | &Syscall([ '/bin/cp', $SRC, "$BE/Contents/MacOS" ]) or die; |
---|
1219 | |
---|
1220 | &Verbose("Updating lib paths of $BE/Contents/MacOS/$binary"); |
---|
1221 | &Syscall([ @bundler, "$BE/Contents/MacOS/$binary" ]) or die; |
---|
1222 | } |
---|
1223 | } |
---|
1224 | &AddFakeBinDir($BE); |
---|
1225 | } |
---|
1226 | |
---|
1227 | if ( $jobtools ) |
---|
1228 | { |
---|
1229 | # JobQueue also gets some binaries it might call: |
---|
1230 | my $JQ = "$SCRIPTDIR/MythJobQueue.app"; |
---|
1231 | my $DEST = "$JQ/Contents/MacOS"; |
---|
1232 | my $SRC = "$PREFIX/bin/mythcommflag"; |
---|
1233 | |
---|
1234 | &Syscall([ '/bin/cp', $SRC, $DEST ]) or die; |
---|
1235 | &AddFakeBinDir($JQ); |
---|
1236 | &Verbose("Updating lib paths of $DEST/mythcommflag"); |
---|
1237 | &Syscall([ @bundler, "$DEST/mythcommflag" ]) or die; |
---|
1238 | |
---|
1239 | $SRC = "$PREFIX/bin/mythtranscode.app/Contents/MacOS/mythtranscode"; |
---|
1240 | if ( -e $SRC ) |
---|
1241 | { |
---|
1242 | &Verbose("Installing $SRC into $JQ"); |
---|
1243 | &Syscall([ '/bin/cp', $SRC, $DEST ]) or die; |
---|
1244 | &Verbose("Updating lib paths of $DEST/mythtranscode"); |
---|
1245 | &Syscall([ @bundler, "$DEST/mythtranscode" ]) or die; |
---|
1246 | } |
---|
1247 | } |
---|
1248 | |
---|
1249 | # Clean tmp files. Most of these are leftovers from configure: |
---|
1250 | # |
---|
1251 | &Verbose('Cleaning build tmp directory'); |
---|
1252 | &Syscall([ 'rm', '-fr', $WORKDIR . '/tmp' ]) or die; |
---|
1253 | &Syscall([ 'mkdir', $WORKDIR . '/tmp' ]) or die; |
---|
1254 | |
---|
1255 | if ($OPT{usehdimage} && !$OPT{leavehdimage} ) |
---|
1256 | { |
---|
1257 | Verbose("Dismounting case-sensitive build device"); |
---|
1258 | UnmountHDImage(); |
---|
1259 | } |
---|
1260 | |
---|
1261 | &Verbose("Build complete. Self-contained package is at:\n\n $MFE\n"); |
---|
1262 | |
---|
1263 | ### end script |
---|
1264 | exit 0; |
---|
1265 | |
---|
1266 | |
---|
1267 | ###################################### |
---|
1268 | ## RecursiveCopy copies a directory tree, stripping out .svn |
---|
1269 | ## directories and properly managing static libraries. |
---|
1270 | ###################################### |
---|
1271 | |
---|
1272 | sub RecursiveCopy($$) |
---|
1273 | { |
---|
1274 | my ($src, $dst) = @_; |
---|
1275 | |
---|
1276 | # First copy absolutely everything |
---|
1277 | &Syscall([ '/bin/cp', '-pR', "$src", "$dst"]) or die; |
---|
1278 | |
---|
1279 | # Then strip out any .svn directories |
---|
1280 | my @files = map { chomp $_; $_ } `find $dst -name .svn`; |
---|
1281 | if ( scalar @files ) |
---|
1282 | { |
---|
1283 | &Syscall([ '/bin/rm', '-f', '-r', @files ]); |
---|
1284 | } |
---|
1285 | |
---|
1286 | # And make sure any static libraries are properly relocated. |
---|
1287 | my @libs = map { chomp $_; $_ } `find $dst -name "lib*.a"`; |
---|
1288 | if ( scalar @libs ) |
---|
1289 | { |
---|
1290 | &Syscall([ 'ranlib', '-s', @libs ]); |
---|
1291 | } |
---|
1292 | } |
---|
1293 | |
---|
1294 | ###################################### |
---|
1295 | ## CleanMakefiles removes every generated Makefile |
---|
1296 | ## from our MythTV build that contains PREFIX. |
---|
1297 | ## Necessary when we change the |
---|
1298 | ## PREFIX variable. |
---|
1299 | ###################################### |
---|
1300 | |
---|
1301 | sub CleanMakefiles |
---|
1302 | { |
---|
1303 | &Verbose("Cleaning MythTV makefiles containing PREFIX"); |
---|
1304 | &Syscall([ 'find', '.', '-name', 'Makefile', '-exec', |
---|
1305 | 'egrep', '-q', 'qmake.*PREFIX', '{}', ';', '-delete' ]) or die; |
---|
1306 | } # end CleanMakefiles |
---|
1307 | |
---|
1308 | |
---|
1309 | ###################################### |
---|
1310 | ## Syscall wrappers the Perl "system" |
---|
1311 | ## routine with verbosity and error |
---|
1312 | ## checking. |
---|
1313 | ###################################### |
---|
1314 | |
---|
1315 | sub Syscall($%) |
---|
1316 | { |
---|
1317 | my ($arglist, %opts) = @_; |
---|
1318 | |
---|
1319 | unless (ref $arglist) |
---|
1320 | { |
---|
1321 | $arglist = [ $arglist ]; |
---|
1322 | } |
---|
1323 | if ( $opts{'interpolate'} ) |
---|
1324 | { |
---|
1325 | my @args; |
---|
1326 | foreach my $arg (@$arglist) |
---|
1327 | { |
---|
1328 | $arg =~ s/\$PREFIX/$PREFIX/ge; |
---|
1329 | $arg =~ s/\$parallel_make_flags/$parallel_make_flags/ge; |
---|
1330 | push(@args, $arg); |
---|
1331 | } |
---|
1332 | $arglist = \@args; |
---|
1333 | } |
---|
1334 | if ( $opts{'munge'} ) |
---|
1335 | { |
---|
1336 | $arglist = [ join(' ', @$arglist) ]; |
---|
1337 | } |
---|
1338 | # clean out any null arguments |
---|
1339 | $arglist = [ map $_, @$arglist ]; |
---|
1340 | &Verbose(@$arglist); |
---|
1341 | my $ret = system(@$arglist); |
---|
1342 | if ( $ret ) |
---|
1343 | { |
---|
1344 | &Complain('Failed system call: "', @$arglist, |
---|
1345 | '" with error code', $ret >> 8); |
---|
1346 | } |
---|
1347 | return ($ret == 0); |
---|
1348 | } # end Syscall |
---|
1349 | |
---|
1350 | |
---|
1351 | ###################################### |
---|
1352 | ## Verbose prints messages in verbose |
---|
1353 | ## mode. |
---|
1354 | ###################################### |
---|
1355 | |
---|
1356 | sub Verbose |
---|
1357 | { |
---|
1358 | print STDERR '[osx-pkg] ' . join(' ', @_) . "\n" |
---|
1359 | if $OPT{'verbose'}; |
---|
1360 | } # end Verbose |
---|
1361 | |
---|
1362 | |
---|
1363 | ###################################### |
---|
1364 | ## Complain prints messages in any |
---|
1365 | ## verbosity mode. |
---|
1366 | ###################################### |
---|
1367 | |
---|
1368 | sub Complain |
---|
1369 | { |
---|
1370 | print STDERR '[osx-pkg] ' . join(' ', @_) . "\n"; |
---|
1371 | } # end Complain |
---|
1372 | |
---|
1373 | |
---|
1374 | ###################################### |
---|
1375 | ## Manage usehdimage disk image |
---|
1376 | ###################################### |
---|
1377 | |
---|
1378 | sub MountHDImage |
---|
1379 | { |
---|
1380 | if ( ! HDImageDevice() ) |
---|
1381 | { |
---|
1382 | if ( -e "$SCRIPTDIR/.osx-packager.dmg" ) |
---|
1383 | { |
---|
1384 | Verbose("Mounting existing UFS disk image for the build"); |
---|
1385 | } |
---|
1386 | else |
---|
1387 | { |
---|
1388 | Verbose("Creating a case-sensitive (UFS) disk image for the build"); |
---|
1389 | Syscall(['hdiutil', 'create', '-size', '2048m', |
---|
1390 | "$SCRIPTDIR/.osx-packager.dmg", '-volname', |
---|
1391 | 'MythTvPackagerHDImage', '-fs', 'UFS', '-quiet']) || die; |
---|
1392 | } |
---|
1393 | |
---|
1394 | &Syscall(['hdiutil', 'mount', |
---|
1395 | "$SCRIPTDIR/.osx-packager.dmg", |
---|
1396 | '-mountpoint', $WORKDIR, '-quiet']) || die; |
---|
1397 | } |
---|
1398 | |
---|
1399 | # configure defaults to /tmp and OSX barfs when mv crosses |
---|
1400 | # filesystems so tell configure to put temp files on the image |
---|
1401 | |
---|
1402 | $ENV{TMPDIR} = $WORKDIR . "/tmp"; |
---|
1403 | mkdir $ENV{TMPDIR}; |
---|
1404 | } |
---|
1405 | |
---|
1406 | sub UnmountHDImage |
---|
1407 | { |
---|
1408 | my $device = HDImageDevice(); |
---|
1409 | if ( $device ) |
---|
1410 | { |
---|
1411 | &Syscall(['hdiutil', 'detach', $device, '-force']); |
---|
1412 | } |
---|
1413 | } |
---|
1414 | |
---|
1415 | sub HDImageDevice |
---|
1416 | { |
---|
1417 | my @dev = split ' ', `/sbin/mount | grep $WORKDIR`; |
---|
1418 | $dev[0]; |
---|
1419 | } |
---|
1420 | |
---|
1421 | sub CaseSensitiveFilesystem |
---|
1422 | { |
---|
1423 | my $funky = $SCRIPTDIR . "/.osx-packager.FunkyStuff"; |
---|
1424 | my $unfunky = substr($funky, 0, -10) . "FUNKySTuFF"; |
---|
1425 | |
---|
1426 | unlink $funky if -e $funky; |
---|
1427 | `touch $funky`; |
---|
1428 | my $sensitivity = ! -e $unfunky; |
---|
1429 | unlink $funky; |
---|
1430 | |
---|
1431 | return $sensitivity; |
---|
1432 | } |
---|
1433 | |
---|
1434 | |
---|
1435 | ###################################### |
---|
1436 | ## Remove or add Nigel's speedup hacks |
---|
1437 | ###################################### |
---|
1438 | |
---|
1439 | sub DoSpeedupHacks($$) |
---|
1440 | { |
---|
1441 | my ($file, $subdirs) = @_; |
---|
1442 | |
---|
1443 | &Verbose("Removing Nigel's hacks from file $file"); |
---|
1444 | |
---|
1445 | open(IN, $file) or die; |
---|
1446 | open(OUT, ">$file.orig") or die; |
---|
1447 | while ( <IN> ) |
---|
1448 | { |
---|
1449 | if ( m/^# Nigel/ ) # Skip |
---|
1450 | { last } |
---|
1451 | print OUT; |
---|
1452 | } |
---|
1453 | if ( ! $backend && ! $jobtools ) |
---|
1454 | { |
---|
1455 | # Nigel's hack to speedup building |
---|
1456 | print OUT "# Nigel\'s speedup hack:\n"; |
---|
1457 | print OUT "SUBDIRS = $subdirs\n"; |
---|
1458 | } |
---|
1459 | close IN; close OUT; |
---|
1460 | rename("$file.orig", $file); |
---|
1461 | } |
---|
1462 | |
---|
1463 | ####################################################### |
---|
1464 | ## Parts of MythTV try to call helper apps like this: |
---|
1465 | ## gContext->GetInstallPrefix() + "/bin/mythtranscode"; |
---|
1466 | ## which means we need a bin directory. |
---|
1467 | ####################################################### |
---|
1468 | |
---|
1469 | sub AddFakeBinDir($) |
---|
1470 | { |
---|
1471 | my ($target) = @_; |
---|
1472 | |
---|
1473 | &Syscall("mkdir -p $target/Contents/Resources"); |
---|
1474 | &Syscall(['ln', '-sf', '../MacOS', "$target/Contents/Resources/bin"]); |
---|
1475 | } |
---|
1476 | |
---|
1477 | ### end file |
---|
1478 | 1; |
---|