Ticket #9400: osx-packager_WCT_git.pl

File osx-packager_WCT_git.pl, 41.8 KB (added by Craig Treleaven <ctreleaven@…>, 15 years ago)
Line 
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
18use strict;
19use Getopt::Long qw(:config auto_abbrev);
20use Pod::Usage ();
21use 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
29our $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#
36our $cleanLibs = 1;
37
38# By default, only the frontend is built (i.e. no backend or transcoding)
39#
40our $backend = 0;
41our $jobtools = 0;
42our $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#
52our $sourceforge = 'http://downloads.sourceforge.net';
53
54# At the moment, there is mythtv plus these two
55our @components = ( 'myththemes', 'mythplugins' );
56
57# The OS X programs that we are likely to be interested in.
58our @targets = ( 'MythFrontend' );
59our @targetTW = ( 'MythAVTest', 'MythWelcome'); # WCT-make Test & Welcome options
60our @targetsJT = ( 'MythCommFlag', 'MythJobQueue');
61our @targetsBE = ( 'MythBackend', 'MythFillDatabase', 'MythTV-Setup');
62
63
64# Patches for MythTV source
65our %patches = ();
66
67our %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
88our %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
162if [ \"\$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
168fi
169exit 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
248osx-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
288This script builds a MythTV frontend and all necessary dependencies, along
289with plugins as specified, as a standalone binary package for Mac OS X.
290
291It was designed for building daily snapshots,
292but can also be used to create release builds.
293
294All intermediate files go into an '.osx-packager' directory in the current
295working directory. The finished application is named 'MythFrontend.app' and
296placed in the current working directory.
297
298=head1 EXAMPLES
299
300Building 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
307Building a "fixes" branch:
308
309 osx-packager.pl -distclean
310 osx-packager.pl -svnbranch release-0-22-fixes
311
312Note that this script will not build old branches.
313Please try the branched version instead. e.g.
314http://svn.mythtv.org/svn/branches/release-0-23-fixes/mythtv/contrib/OSX/osx-packager.pl
315
316=head1 CREDITS
317
318Written by Jeremiah Morris (jm@whpress.com)
319
320Special thanks to Nigel Pearson, Jan Ornstedt, Angel Li, and Andre Pang
321for help, code, and advice.
322
323Small 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!
324Mods for move to github, Craig Treleaven December 2010.
325
326=cut
327
328# Parse options
329our (%OPT);
330Getopt::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);
360Pod::Usage::pod2usage(1) if $OPT{'help'};
361Pod::Usage::pod2usage('-verbose' => 2) if $OPT{'man'};
362
363if ( $OPT{'enable-backend'} )
364{ $backend = 1 }
365
366if ( $OPT{'clean'} )
367{ $cleanLibs = 1 }
368
369if ( $OPT{'enable-jobtools'} )
370{ $jobtools = 1 }
371
372if ( $OPT{'enable-feplus'} ) # add MythAVTest and MythWelcome
373{ $feplus = 1 }
374
375# Get version string sorted out
376if ( $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'};
383unless (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
390if ( $OPT{'srcdir'} )
391{
392 $OPT{'nohead'} = 1;
393 $OPT{'svnbranch'} = 0;
394}
395
396# Build our temp directories
397our $SCRIPTDIR = Cwd::abs_path(Cwd::getcwd());
398if ( $SCRIPTDIR =~ /\s/ )
399{
400 &Complain(<<END);
401Working directory contains spaces
402
403Error: Your current working path:
404
405 $SCRIPTDIR
406
407contains one or more spaces. This will break the compilation process,
408so the script cannot continue. Please re-run this script from a different
409directory (such as /tmp).
410
411The application produced will run from any directory, the no-spaces
412rule is only for the build process itself.
413
414END
415 die;
416}
417
418if ( $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
442if ( $OPT{'svnbranch'} && $OPT{'svnbranch'} lt "release-0-24-fixes" )
443{
444 &Complain(<<END);
445This version of this script can not build old branches.
446Please try the branched version instead. e.g.
447# XXX Fix Me XXX
448http://svn.mythtv.org/svn/branches/release-0-21-fixes/mythtv/contrib/OSX/osx-packager.pl
449END
450 die;
451}
452
453#
454# Same tests for fixes copy of this script:
455#
456if ( 0 )
457{
458if ( $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}
468elsif ( ! $OPT{'svnbranch'} && ! $OPT{'force'} )
469{
470 &Complain(<<END);
471This script can only build branch release-0-22-fixes.
472To build SVN HEAD, please try the latest version instead. e.g.
473http://svn.mythtv.org/svn/trunk/packaging/OSX/build/osx-packager.pl
474END
475 die;
476}
477}
478
479our $WORKDIR = "$SCRIPTDIR/.osx-packager";
480mkdir $WORKDIR;
481
482# Do we need to force a case-sensitive disk image?
483if (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
490if ($OPT{usehdimage})
491{ MountHDImage() }
492
493our $PREFIX = "$WORKDIR/build";
494mkdir $PREFIX;
495
496our $SRCDIR = "$WORKDIR/src";
497mkdir $SRCDIR;
498
499#our $SVNDIR = "$SRCDIR/myth-svn";
500our $MYTHSRCDIR = "$SRCDIR/mythtv";
501
502our @pluginConf;
503if ( $OPT{plugins} )
504{
505 @pluginConf = split /,/, $OPT{plugins};
506 @pluginConf = grep(s/^/--enable-/, @pluginConf);
507 unshift @pluginConf, '--disable-all';
508}
509else
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
521our %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
550our %makecleanopt = (
551 'mythplugins'
552 => [
553 'distclean',
554 ],
555);
556
557# Source code version.pro needs to call subversion binary
558#
559
560use File::Basename;
561
562our $gitpath = dirname $git;
563our $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:";
570delete $ENV{'CC'};
571delete $ENV{'CXX'};
572delete $ENV{'CPP'};
573delete $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
584our $standard_make = '/usr/bin/make';
585our $parallel_make = $standard_make;
586our $parallel_make_flags = '';
587
588if ( $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:
598my $cmd = "/usr/bin/hostinfo | grep 'processors\$'";
599&Verbose($cmd);
600my $cpus = `$cmd`; chomp $cpus;
601$cpus =~ s/.*, (\d+) processors$/$1/;
602if ( $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:
612if ( `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.
620if ( $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?
631if ( $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
646our $MFE = "$SCRIPTDIR/MythFrontend.app";
647if ( -d $MFE )
648{
649 &Complain(<<END);
650$MFE already exists
651
652Error: a MythFrontend application exists where we were planning
653to build one. Please move this application away before running
654this script.
655
656END
657 exit;
658}
659
660### Third party packages
661my ( @build_depends, %seen_depends );
662my @comps = ( 'mythtv', @components, 'packaging' );
663
664# Deal with user-supplied skip arguments
665if ( $OPT{'mythtvskip'} )
666{ @comps = grep(!m/mythtv/, @comps) }
667if ( $OPT{'pluginskip'} )
668{ @comps = grep(!m/mythplugins/, @comps) }
669if ( $OPT{'themeskip'} )
670{ @comps = grep(!m/myththemes/, @comps) }
671
672if ( ! @comps )
673{
674 &Complain("Nothing to build! Too many ...skip arguments?");
675 exit;
676}
677
678&Verbose("Including components:", @comps);
679
680foreach 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}
691foreach 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
819if ( $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#
847my $svnrepository = 'http://svn.mythtv.org/svn/';
848my @svnrevision = ();
849
850if ( $OPT{'svnbranch'} )
851{
852 $svnrepository .= 'branches/' . $OPT{'svnbranch'} . '/';
853}
854elsif ( $OPT{'svntag'} )
855{
856 $svnrepository .= 'tags/' . $OPT{'svntag'} . '/';
857}
858elsif ( $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
891if ( $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}
903elsif ( ! $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}
931else
932{ &Syscall("mkdir -p $MYTHSRCDIR/mythtv/config") }
933
934# Make a convenience (non-hidden) directory for editing src code:
935system("ln -sf $MYTHSRCDIR $SCRIPTDIR/src");
936
937# Build MythTV and any plugins
938foreach 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
1047our $VERS = `find $PREFIX/lib -name 'libmyth-[0-9].[0-9][0-9].[0-9].dylib'`;
1048chomp $VERS;
1049$VERS =~ s/^.*\-(.*)\.dylib$/$1/s;
1050$VERS .= '.' . $OPT{'version'} if $OPT{'version'};
1051
1052### Program which creates bundles:
1053our @bundler = "$MYTHSRCDIR/packaging/OSX/build/osx-bundler.pl";
1054if ( $OPT{'verbose'} )
1055{ push @bundler, '--verbose' }
1056
1057
1058### Framework that has a screwed up link dependency path
1059my $AVCfw = '/Developer/FireWireSDK*/Examples/' .
1060 'Framework/AVCVideoServices.framework';
1061my @AVCfw = split / /, `ls -d $AVCfw`;
1062$AVCfw = pop @AVCfw;
1063chop $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
1069if ( $jobtools )
1070{ push @targets, @targetsJT }
1071
1072if ( $feplus )
1073{ push @targets, @targetTW }
1074
1075if ( $backend )
1076{ push @targets, @targetsBE }
1077
1078foreach 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
1201if ( $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
1227if ( $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
1255if ($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
1264exit 0;
1265
1266
1267######################################
1268## RecursiveCopy copies a directory tree, stripping out .svn
1269## directories and properly managing static libraries.
1270######################################
1271
1272sub 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
1301sub 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
1315sub 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
1356sub 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
1368sub Complain
1369{
1370 print STDERR '[osx-pkg] ' . join(' ', @_) . "\n";
1371} # end Complain
1372
1373
1374######################################
1375## Manage usehdimage disk image
1376######################################
1377
1378sub 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
1406sub UnmountHDImage
1407{
1408 my $device = HDImageDevice();
1409 if ( $device )
1410 {
1411 &Syscall(['hdiutil', 'detach', $device, '-force']);
1412 }
1413}
1414
1415sub HDImageDevice
1416{
1417 my @dev = split ' ', `/sbin/mount | grep $WORKDIR`;
1418 $dev[0];
1419}
1420
1421sub 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
1439sub 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
1469sub 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
14781;