Advertisement
Guest User

Untitled

a guest
Mar 5th, 2012
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 65.23 KB | None | 0 0
  1. diff --git a/OSX/build/osx-bundler.pl b/OSX/build/osx-bundler.pl
  2. index 73e5ae6..0b95324 100755
  3. --- a/OSX/build/osx-bundler.pl
  4. +++ b/OSX/build/osx-bundler.pl
  5. @@ -31,20 +31,17 @@ osx-bundler.pl target1.app/Contents/Resources/lib/extra.dylib [lib-dir...]
  6. # 2) copies them into the bundle's Framework directory
  7. # 3) uses install_name_tool to update the library load paths
  8. #
  9. -# = KNOWN BUGS
  10. -# Doesn't do anything about Universal Binaries yet
  11. -#
  12. # = TO DO
  13. # Add more arguments to allow the user to specify
  14. # .pinfo fields like CFBundleIdentifier, CFBundleSignature,
  15. # NSHumanReadableCopyright, CFBundleGetInfoString, et c.
  16. #
  17. # = REVISION
  18. -# $Id$
  19. +# 2.0
  20. #
  21. # = AUTHORS
  22. # Nigel Pearson. Based on osx-packager by Jeremiah Morris,
  23. -# with improvements by Geoffrey Kruse and David Abrahams
  24. +# with improvements by Geoffrey Kruse, David Abrahams and Jean-Yves Avenard
  25. # ============================================================================
  26.  
  27. use strict;
  28. @@ -67,7 +64,8 @@ if ( $#ARGV < 0 )
  29. # ============================================================================
  30.  
  31. my $verbose = 0;
  32. -my $Id = '$Id$'; # Version of this script. From version control system
  33. +our $arch = "";
  34. +my $Id = '2.0'; # Version of this script
  35. my $binary;
  36. my $binbase; # $binary without any directory path
  37. my $bundle;
  38. @@ -76,13 +74,15 @@ my $target; # Full path to the binary under $bundle
  39.  
  40. # Process arguments:
  41.  
  42. -Getopt::Long::GetOptions('verbose' => \$verbose) or usage(-1);
  43. +Getopt::Long::GetOptions('verbose' => \$verbose, 'arch=s' => \$arch) or usage(-1);
  44.  
  45. $binary = shift @ARGV;
  46. @libdirs = @ARGV;
  47.  
  48. # ============================================================================
  49.  
  50. +&Verbose("Processing $binary");
  51. +
  52. if ( $binary =~ m/(.*)\.app$/ )
  53. {
  54. $bundle = $binary;
  55. @@ -185,17 +185,37 @@ sub MakeFramework
  56. my ($dylib, $dest) = @_;
  57.  
  58. my ($base, $vers) = &BaseVers($dylib);
  59. + if ( ! defined $vers )
  60. + {
  61. + $vers = "1.0";
  62. + }
  63. my $fw_dir = $dest . '/' . $base . '.framework';
  64.  
  65. + &Verbose("MakeFramework: fw_fir = $fw_dir, dest = $dest, base = $base, dylib = $dylib");
  66. return '' if ( -e $fw_dir );
  67.  
  68. &Verbose("Building $base framework");
  69.  
  70. &Syscall([ '/bin/mkdir', '-p',
  71. "$fw_dir/Versions/A/Resources" ]) or die;
  72. - &Syscall([ '/bin/cp', $dylib,
  73. - "$fw_dir/Versions/A/$base" ]) or die;
  74. -
  75. + if ( $arch eq "" )
  76. + {
  77. + &Syscall([ '/bin/cp', $dylib,
  78. + "$fw_dir/Versions/A/$base" ]) or die;
  79. + }
  80. + else
  81. + {
  82. + &Verbose("Extracting $arch architecture from $dylib");
  83. + my @args = ( '/usr/bin/lipo', '-thin', $arch, $dylib, '-o', "$fw_dir/Versions/A/$base" );
  84. + &Verbose(@args);
  85. + # try to extract required architecture
  86. + system(@args);
  87. + if ( $? )
  88. + {
  89. + # if unsuccessful, just copy the lib
  90. + &Syscall([ '/bin/cp', $dylib, "$fw_dir/Versions/A/$base" ]) or die;
  91. + }
  92. + }
  93. &Syscall([ '/usr/bin/install_name_tool',
  94. '-id', $base, "$fw_dir/Versions/A/$base" ]) or die;
  95.  
  96. @@ -203,6 +223,19 @@ sub MakeFramework
  97. symlink('Versions/Current/Resources', "$fw_dir/Resources") or die;
  98. symlink("Versions/A/$base", "$fw_dir/$base") or die;
  99.  
  100. + if ( $dylib =~ m/\.framework/ )
  101. + {
  102. + my $resdir = dirname($dylib) . "/Resources";
  103. + if ( -d $resdir )
  104. + {
  105. + &Verbose("$resdir exists, copy over $fw_dir/Resources");
  106. + my @files = glob "$resdir/*";
  107. + foreach (@files)
  108. + {
  109. + &Syscall([ '/bin/cp', '-R', "$_", "$fw_dir/Resources" ]);
  110. + }
  111. + }
  112. + }
  113. &Verbose("Writing Info.plist for $base framework");
  114. my $plist;
  115. unless (open($plist, '>' . "$fw_dir/Versions/A/Resources/Info.plist"))
  116. @@ -345,7 +378,6 @@ sub ProcessDependencies(@)
  117. foreach my $dep (@deps)
  118. {
  119. chomp $dep;
  120. -
  121. # otool returns lines like:
  122. # libblah-7.dylib (compatibility version 7, current version 7)
  123. # but we only want the file part
  124. @@ -362,7 +394,7 @@ sub ProcessDependencies(@)
  125.  
  126. # Any dependency which is already package relative can be ignored
  127. next if $dep =~ m/\@executable_path/;
  128. -
  129. +
  130. # skip system library locations
  131. next if ($dep =~ m|^/System| ||
  132. $dep =~ m|^/usr/lib|);
  133. @@ -371,6 +403,7 @@ sub ProcessDependencies(@)
  134.  
  135. # Only add this dependency if needed. This assumes that
  136. # we aren't mixing versions of the same library name
  137. + &Verbose("Process Dep $base");
  138. if ( ! -e "$bundle/Contents/Frameworks/$base.framework/$base" )
  139. { $depfiles{$base} = $dep }
  140.  
  141. @@ -404,6 +437,11 @@ sub BaseVers
  142. {
  143. return ($1, undef);
  144. }
  145. + elsif ($filename =~ m|^.*?\.framework.*/(.*?)$|)
  146. + {
  147. + &Verbose("Framework : $1");
  148. + return ($1, undef);
  149. + }
  150.  
  151. &Verbose("Not a library file: $filename");
  152. return $filename;
  153. diff --git a/OSX/build/osx-packager-qtsdk.pl b/OSX/build/osx-packager-qtsdk.pl
  154. new file mode 100755
  155. index 0000000..8c0403e
  156. --- /dev/null
  157. +++ b/OSX/build/osx-packager-qtsdk.pl
  158. @@ -0,0 +1,1902 @@
  159. +#!/usr/bin/perl
  160. +
  161. +### = file
  162. +### osx-packager-qtsdk.pl
  163. +###
  164. +### = revision
  165. +### 1.0
  166. +###
  167. +### = location
  168. +### https://github.com/MythTV/packaging/raw/master/OSX/build/osx-packager-qtsdk.pl
  169. +###
  170. +### = description
  171. +### Tool for automating frontend builds on Mac OS X.
  172. +### Run "osx-packager.pl -man" for full documentation.
  173. +
  174. +use strict;
  175. +use Getopt::Long qw(:config auto_abbrev);
  176. +use Pod::Usage ();
  177. +use Cwd ();
  178. +use File::Temp qw/ tempfile tempdir /;
  179. +
  180. +### Configuration settings (stuff that might change more often)
  181. +
  182. +# We try to auto-locate the Git client binaries.
  183. +# If they are not in your path, we build them from source
  184. +#
  185. +our $git = `which git`; chomp $git;
  186. +
  187. +# This script used to always delete the installed include and lib dirs.
  188. +# That probably ensures a safe build, but when rebuilding adds minutes to
  189. +# the total build time, and prevents us skipping some parts of a full build
  190. +#
  191. +our $cleanLibs = 1;
  192. +
  193. +# By default, only the frontend is built (i.e. no backend or transcoding)
  194. +#
  195. +our $backend = 0;
  196. +our $jobtools = 0;
  197. +
  198. +# Start with a generic address and let sourceforge
  199. +# figure out which mirror is closest to us.
  200. +#
  201. +our $sourceforge = 'http://downloads.sourceforge.net';
  202. +
  203. +# At the moment, there is mythtv plus...
  204. +our @components = ( 'mythplugins' );
  205. +
  206. +# The OS X programs that we are likely to be interested in.
  207. +our @targets = ( 'MythFrontend', 'MythWelcome' );
  208. +our @targetsJT = ( 'MythCommFlag', 'MythJobQueue');
  209. +our @targetsBE = ( 'MythBackend', 'MythFillDatabase', 'MythTV-Setup');
  210. +
  211. +# Name of the PlugIns directory in the application bundle
  212. +our $BundlePlugins = "PlugIns";
  213. +our $OSTARGET = "10.5";
  214. +
  215. +# Patches for MythTV source
  216. +our %patches = ();
  217. +
  218. +our %build_profile = (
  219. + 'master'
  220. + => [
  221. + 'branch' => 'master',
  222. + 'mythtv'
  223. + => [
  224. + 'ccache',
  225. + 'pkgconfig',
  226. + 'dvdcss',
  227. + 'freetype',
  228. + 'lame',
  229. + 'mysqlclient',
  230. + #'dbus',
  231. + 'qt',
  232. + 'yasm',
  233. + 'liberation-sans',
  234. + 'firewiresdk',
  235. + ],
  236. + 'mythplugins'
  237. + => [
  238. + 'exif',
  239. +# MythMusic needs these:
  240. + 'libtool',
  241. + 'autoconf',
  242. + 'automake',
  243. + 'taglib',
  244. + 'libogg',
  245. + 'vorbis',
  246. + 'flac',
  247. + 'libcddb',
  248. + 'libcdio',
  249. + ],
  250. + ],
  251. + '0.24-fixes'
  252. + => [
  253. + 'branch' => 'fixes/0.24',
  254. + 'mythtv'
  255. + => [
  256. + 'ccache',
  257. + 'pkgconfig',
  258. + 'dvdcss',
  259. + 'freetype',
  260. + 'lame',
  261. + 'mysqlclient',
  262. + #'dbus',
  263. + 'qt',
  264. + 'yasm',
  265. + 'liberation-sans',
  266. + 'firewiresdk',
  267. + ],
  268. + 'mythplugins'
  269. + => [
  270. + 'exif',
  271. +# MythMusic needs these:
  272. + 'libtool',
  273. + 'autoconf',
  274. + 'automake',
  275. + 'taglib',
  276. + 'libogg',
  277. + 'vorbis',
  278. + 'flac',
  279. + ],
  280. + ],
  281. +);
  282. +
  283. +=head1 NAME
  284. +
  285. +osx-packager.pl - build OS X binary packages for MythTV
  286. +
  287. +=head1 SYNOPSIS
  288. +
  289. + osx-packager.pl [options]
  290. +
  291. + Options:
  292. + -help print the usage message
  293. + -man print full documentation
  294. + -verbose print informative messages during the process
  295. + -version <str> custom version suffix (defaults to "gitYYYYMMDD")
  296. + -noversion don't use any version suffix
  297. + (for building release versions)
  298. + -distclean throw away all myth installed and intermediates
  299. + files and exit
  300. + -qtsdk <path> path to Qt SDK Deskop
  301. + (e.g. -qtsdk ~/QtSDK/Desktop/Qt/4.8.0
  302. + -qtbin <path> path to Qt utilitities (qmake etc)
  303. + -qtplugins <path> path to Qt plugins
  304. + -m32 build for a 32-bit environment only
  305. + (default is to build for the host's architecture)
  306. + -universal build for both 32 and 64 bits architectures
  307. + (only works with 0.25 or later,
  308. + requires Qt libraries)
  309. + -gitrev <str> build a specified Git revision or tag
  310. +
  311. + You must provide either -qtsdk or -qtbin *and * -qtplugins
  312. +
  313. + Advanced Options:
  314. + -srcdir <path> build using provided root mythtv directory
  315. + -pkgsrcdir <path> build using provided packaging directory
  316. + -force use myth source directory as-is,
  317. + with no GIT validity check
  318. + -nodistclean do not perform a distclean prior to building myth
  319. + -thirdclean do a clean rebuild of third party packages
  320. + -thirdskip don't rebuild the third party packages
  321. + -mythtvskip don't rebuild/install mythtv, requires -nodistclean
  322. + -pluginskip don't rebuild/install mythplugins
  323. + -nohead don't update to HEAD revision of MythTV before
  324. + building
  325. + -clean clean myth module before rebuilding it (default)
  326. + -noclean use with -nohead, do not re-run configure nor clean
  327. + -usehdimage perform build inside of a case-sensitive disk image
  328. + -leavehdimage leave disk image mounted on exit
  329. + -enable-backend build the backend server as well as the frontend
  330. + -enable-jobtools build commflag/jobqueue as well as the frontend
  331. + -profile build with compile-type=profile
  332. + -debug build with compile-type=debug
  333. + -plugins <str> comma-separated list of plugins to include
  334. + -noparallel do not use parallel builds
  335. + -nobundle only recompile, do not create application bundle
  336. + -bootstrap exit after building all thirdparty components
  337. + -disable-sysroot compiling with sysroot only works with 0.25 or later
  338. + use -disable-sysroot if compiling earlier version of myth
  339. +
  340. +=head1 DESCRIPTION
  341. +
  342. +This script builds a MythTV frontend and all necessary dependencies, along
  343. +with plugins as specified, as a standalone binary package for Mac OS X.
  344. +
  345. +It is designed for building daily Git snapshots,
  346. +and can also be used to create release builds with the '-gitrev' option.
  347. +
  348. +All intermediate files go into an '.osx-packager' directory in the current
  349. +working directory. The finished application is named 'MythFrontend.app' and
  350. +placed in the current working directory.
  351. +
  352. +By default, the end application will only run on the architecture of the machine
  353. +used to compile (32 or 64 bits). Use -universal to compile an application for both
  354. +32 and 64 bits. For -universal to work, you must compile on a 64 bits intel host.
  355. +
  356. +=head1 REQUIREMENTS
  357. +
  358. +You need to have installed either Qt SDK (64 bits only) or
  359. +Qt libraries package (both 32 and 64 bits) from http://qt.nokia.com/downloads.
  360. +
  361. +When using the Qt SDK, use the -qtsdk flag to define the location of the Desktop Qt,
  362. +by default it is ~/QtSDK/Desktop/Qt/[VERSION]/gcc where version is 4.8.0 (SDK 1.2)
  363. +or 473 (SDK 1.1)
  364. +
  365. +When using the Qt libraries package, use the -qtbin and -qtplugins. Values for default
  366. +Qt installation are: -qtbin /usr/bin -qtplugins /Developer/Applications/Qt/plugins.
  367. +Qt Headers must be installed.
  368. +
  369. +=head1 EXAMPLES
  370. +
  371. +Building two snapshots, one with all plugins and one without:
  372. +
  373. + osx-packager.pl -qtbin /usr/bin -qtplugins /Developer/Applications/Qt/plugins
  374. + mv MythFrontend.app MythFrontend-plugins.app
  375. + osx-packager.pl -nohead -pluginskip -qtbin /usr/bin -qtplugins /Developer/Applications/Qt/plugins
  376. + mv MythFrontend.app MythFrontend-noplugins.app
  377. +
  378. +Building a "fixes" branch:
  379. +
  380. + osx-packager.pl -gitrev fixes/0.24 -qtbin /usr/bin -qtplugins /Developer/Applications/Qt/plugins
  381. +
  382. +Note that this script will not build old branches.
  383. +Please try the branched version instead. e.g.
  384. +http://svn.mythtv.org/svn/branches/release-0-21-fixes/mythtv/contrib/OSX/osx-packager.pl
  385. +
  386. +=head1 CREDITS
  387. +
  388. +Written by Jean-Yves Avenard <jyavenard@gmail.com>
  389. +Based on work by Jeremiah Morris <jm@whpress.com>
  390. +
  391. +Includes contributions from Nigel Pearson, Jan Ornstedt, Angel Li, and Andre Pang, Bas Hulsken (bhulsken@hotmail.com)
  392. +
  393. +=cut
  394. +
  395. +# Parse options
  396. +our (%OPT);
  397. +Getopt::Long::GetOptions(\%OPT,
  398. + 'help|?',
  399. + 'man',
  400. + 'verbose',
  401. + 'version=s',
  402. + 'noversion',
  403. + 'distclean',
  404. + 'thirdclean',
  405. + 'nodistclean',
  406. + 'noclean',
  407. + 'thirdskip',
  408. + 'mythtvskip',
  409. + 'pluginskip',
  410. + 'gitrev=s',
  411. + 'nohead',
  412. + 'usehdimage',
  413. + 'leavehdimage',
  414. + 'enable-backend',
  415. + 'enable-jobtools',
  416. + 'profile',
  417. + 'debug',
  418. + 'm32',
  419. + 'universal',
  420. + 'plugins=s',
  421. + 'srcdir=s',
  422. + 'pkgsrcdir=s',
  423. + 'force',
  424. + 'archives=s',
  425. + 'buildprofile=s',
  426. + 'bootstrap',
  427. + 'nohacks',
  428. + 'noparallel',
  429. + 'qtsdk=s',
  430. + 'qtbin=s',
  431. + 'qtplugins=s',
  432. + 'nobundle',
  433. + ) or Pod::Usage::pod2usage(2);
  434. +Pod::Usage::pod2usage(1) if $OPT{'help'};
  435. +Pod::Usage::pod2usage('-verbose' => 2) if $OPT{'man'};
  436. +
  437. +our $QTSDK = "";
  438. +our $QTBIN = "";
  439. +our $QTLIB = "";
  440. +our $QTPLUGINS = "";
  441. +our $QTVERSION = "";
  442. +if ( $OPT{'qtsdk'} )
  443. +{
  444. + $QTSDK = $OPT{'qtsdk'};
  445. +}
  446. +
  447. +if ( $OPT{'qtbin'} )
  448. +{
  449. + $QTBIN = "$OPT{'qtbin'}";
  450. +}
  451. +elsif ( $OPT{'qtsdk'} )
  452. +{
  453. + $QTBIN = "$OPT{'qtsdk'}/bin";
  454. +}
  455. +if ( $OPT{'qtplugins'} )
  456. +{
  457. + $QTPLUGINS = "$OPT{'qtplugins'}";
  458. +}
  459. +elsif ( $OPT{'qtsdk'} )
  460. +{
  461. + $QTPLUGINS = "$QTSDK/plugins";
  462. +}
  463. +
  464. +# Test if Qt conf is valid, all paths must exist
  465. +if ( ! ( (($QTBIN ne "") && ($QTPLUGINS ne "")) &&
  466. + ( -d $QTBIN && -d $QTPLUGINS )) )
  467. +{
  468. + &Complain("bin:$QTBIN lib:$QTLIB plugins:$QTPLUGINS You must define a valid Qt SDK path with -qtsdk <path> or -qtbin <path> *and* -qtplugins <path>");
  469. + exit;
  470. +}
  471. +
  472. +#Determine the version Qt SDK we are using, we need to retrieve the source code to build MySQL Qt plugin
  473. +if ( ! -e "$QTBIN/qmake" )
  474. +{
  475. + &Complain("$QTBIN isn't a valid Qt bin path (qmake not found)");
  476. + exit;
  477. +}
  478. +my @ret = `$QTBIN/qmake --version`;
  479. +my $regexp = qr/Qt version (\d+\.\d+\.\d+) in (.*)$/;
  480. +foreach my $line (@ret)
  481. +{
  482. + chomp $line;
  483. + next if ($line !~ m/$regexp/);
  484. + $QTVERSION = $1;
  485. + $QTLIB = $2;
  486. + &Verbose("Qt version is $QTVERSION");
  487. +}
  488. +
  489. +if ($QTVERSION eq "")
  490. +{
  491. + &Complain("Couldn't identify Qt version");
  492. + exit;
  493. +}
  494. +if ( ! -d $QTLIB )
  495. +{
  496. + &Complain("$QTLIB doesn't exist. Invalid Qt sdk");
  497. + exit;
  498. +}
  499. +
  500. +if ( $OPT{'enable-backend'} )
  501. +{ $backend = 1 }
  502. +
  503. +if ( $OPT{'noclean'} )
  504. +{ $cleanLibs = 0 }
  505. +
  506. +if ( $OPT{'enable-jobtools'} )
  507. +{ $jobtools = 1 }
  508. +
  509. +# Get version string sorted out
  510. +if ( $OPT{'gitrev'} && !$OPT{'version'} )
  511. +{
  512. + $OPT{'version'} = $OPT{'gitrev'};
  513. +}
  514. +$OPT{'version'} = '' if $OPT{'noversion'};
  515. +unless (defined $OPT{'version'})
  516. +{
  517. + my @lt = gmtime(time);
  518. + $OPT{'version'} = sprintf('git%04d%02d%02d',
  519. + $lt[5] + 1900, $lt[4] + 1, $lt[3]);
  520. +}
  521. +
  522. +if ( $OPT{'srcdir'} )
  523. +{
  524. + $OPT{'nohead'} = 1;
  525. + $OPT{'gitrev'} = '';
  526. +}
  527. +
  528. +# Build our temp directories
  529. +our $SCRIPTDIR = Cwd::abs_path(Cwd::getcwd());
  530. +if ( $SCRIPTDIR =~ /\s/ )
  531. +{
  532. + &Complain(<<END);
  533. +Working directory contains spaces
  534. +
  535. +Error: Your current working path:
  536. +
  537. + $SCRIPTDIR
  538. +
  539. +contains one or more spaces. This will break the compilation process,
  540. +so the script cannot continue. Please re-run this script from a different
  541. +directory (such as /tmp).
  542. +
  543. +The application produced will run from any directory, the no-spaces
  544. +rule is only for the build process itself.
  545. +
  546. +END
  547. + die;
  548. +}
  549. +
  550. +our $WORKDIR = "$SCRIPTDIR/.osx-packager";
  551. +mkdir $WORKDIR;
  552. +
  553. +if ( $OPT{'nohead'} && ! $OPT{'force'} && ! $OPT{'srcdir'} )
  554. +{
  555. + my $GITTOP="$WORKDIR/src/myth-git/.git";
  556. +
  557. + if ( ! -d $GITTOP )
  558. + { die "No source code to build?" }
  559. +
  560. + if ( ! `grep refs/heads/master $GITTOP/HEAD` )
  561. + { die "Source code does not match GIT master" }
  562. +}
  563. +elsif ( $OPT{'gitrev'} =~ m,^fixes/, && $OPT{'gitrev'} lt "fixes/0.23" )
  564. +{
  565. + &Complain(<<END);
  566. +This version of this script can not build old branches.
  567. +Please try the branched version instead. e.g.
  568. +http://svn.mythtv.org/svn/branches/release-0-23-fixes/packaging/OSX/build/osx-packager.pl
  569. +http://svn.mythtv.org/svn/branches/release-0-21-fixes/mythtv/contrib/OSX/osx-packager.pl
  570. +END
  571. + die;
  572. +}
  573. +
  574. +if ($OPT{usehdimage})
  575. +{ MountHDImage() }
  576. +
  577. +our $PREFIX = "$WORKDIR/build";
  578. +mkdir $PREFIX;
  579. +
  580. +our $SRCDIR = "$WORKDIR/src";
  581. +mkdir $SRCDIR;
  582. +
  583. +our $ARCHIVEDIR ='';
  584. +if ( $OPT{'archives'} )
  585. +{
  586. + $ARCHIVEDIR = "$SCRIPTDIR" . '/' . $OPT{'archives'};
  587. +} else {
  588. + $ARCHIVEDIR = "$SRCDIR";
  589. +}
  590. +
  591. +our %depend_order = '';
  592. +my $gitrevision = 'master'; # Default thingy to checkout
  593. +if ( $OPT{'buildprofile'} && $OPT{'buildprofile'} == '0.24-fixes' )
  594. +{
  595. + &Verbose('Building using 0.24-fixes profile');
  596. + %depend_order = @{ $build_profile{'0.24-fixes'} };
  597. + $gitrevision = 'fixes/0.24'
  598. +} else {
  599. + &Verbose('Building using master profile');
  600. + %depend_order = @{ $build_profile{'master'} };
  601. +}
  602. +
  603. +our $GITDIR = "$SRCDIR/myth-git";
  604. +
  605. +our @pluginConf;
  606. +if ( $OPT{plugins} )
  607. +{
  608. + @pluginConf = split /,/, $OPT{plugins};
  609. + @pluginConf = grep(s/^/--enable-/, @pluginConf);
  610. + unshift @pluginConf, '--disable-all';
  611. +}
  612. +else
  613. +{
  614. + @pluginConf = (
  615. + '--enable-opengl',
  616. + '--enable-mythgallery',
  617. + '--enable-exif',
  618. + '--enable-new-exif',
  619. + );
  620. +}
  621. +
  622. +# configure mythplugins, and mythtv, etc
  623. +our %conf = (
  624. + 'mythplugins'
  625. + => [
  626. + @pluginConf
  627. + ],
  628. + 'mythtv'
  629. + => [
  630. + "--runprefix=../Resources",
  631. + "--firewire-sdk=$PREFIX/lib",
  632. + "--enable-libmp3lame",
  633. +
  634. + # To "cross compile" something for a lesser Mac:
  635. + #'--tune=G3',
  636. + #'--disable-altivec',
  637. + ],
  638. +);
  639. +
  640. +# configure mythplugins, and mythtv, etc
  641. +our %makecleanopt = (
  642. + 'mythplugins'
  643. + => [
  644. + 'distclean',
  645. + ],
  646. +);
  647. +
  648. +use File::Basename;
  649. +our $gitpath = dirname $git;
  650. +
  651. +# Clean the environment
  652. +$ENV{'PATH'} = "$PREFIX/bin:/bin:/usr/bin:/usr/sbin:$gitpath";
  653. +$ENV{'PKG_CONFIG_PATH'} = "$PREFIX/lib/pkgconfig:";
  654. +delete $ENV{'CPP'};
  655. +delete $ENV{'CXX'};
  656. +
  657. +our $DEVROOT = `xcode-select -print-path`; chomp $DEVROOT;
  658. +our $SDKVER = `xcodebuild -showsdks | grep macosx10 | sort | head -n 1 | awk '{ print \$4 }' `; chomp $SDKVER;
  659. +our $SDKNAME = `xcodebuild -showsdks | grep macosx10 | sort | head -n 1 | awk '{ print \$6 }' `; chomp $SDKNAME;
  660. +our $SDKROOT = "$DEVROOT/SDKs/MacOSX$SDKVER.sdk";
  661. +
  662. +$ENV{'DEVROOT'} = $DEVROOT;
  663. +$ENV{'SDKVER'} = $SDKVER;
  664. +$ENV{'SDKROOT'} = $SDKROOT;
  665. +
  666. +# Determine appropriate gcc/g++ path for the selected SDKs
  667. +our $CCBIN = `xcodebuild -find gcc -sdk $SDKNAME`; chomp $CCBIN;
  668. +our $CXXBIN = `xcodebuild -find g++ -sdk $SDKNAME`; chomp $CXXBIN;
  669. +$ENV{'CC'} = $CCBIN;
  670. +$ENV{'CXX'} = $CXXBIN;
  671. +$ENV{'CPP'} = "$CCBIN -E";
  672. +$ENV{'CXXCPP'} = "$CXXBIN -E";
  673. +
  674. +if ( ! -e "$SDKROOT" && ! $OPT{'disable-sysroot'} )
  675. +{
  676. + #Handle special case for 10.4 where the SDK name is 10.4u.sdk
  677. + $SDKROOT = "$DEVROOT/SDKs/MacOSX${SDKVER}u.sdk";
  678. + if ( ! -e "$SDKROOT" )
  679. + {
  680. + # Handle XCode 4.3 new location
  681. + $SDKROOT = "$DEVROOT/Platforms/MacOSX.platform/Developer/SDKs/MacOSX$SDKVER.sdk";
  682. + if ( ! -e "$SDKROOT" )
  683. + {
  684. + &Complain("$SDKROOT doesn't exist");
  685. + &Complain("Did you set your xcode environmment path properly ? (xcode-select utility)");
  686. + exit;
  687. + }
  688. + }
  689. +}
  690. +
  691. +#Compilation was broken when using sysroots, mythtv code was fixed from 0.25 only. so this makes it configurable
  692. +our $SDKISYSROOT = "-isysroot $SDKROOT -mmacosx-version-min=$OSTARGET";
  693. +our $SDKLSYSROOT = "-Wl,-syslibroot,${SDKROOT} -mmacosx-version-min=$OSTARGET";
  694. +if ( $OPT{'disable-sysroot'} )
  695. +{
  696. + $SDKISYSROOT = "";
  697. + $SDKLSYSROOT = "";
  698. +}
  699. +
  700. +# set up Qt environment
  701. +$ENV{'QTDIR'} = "$QTSDK";
  702. +$ENV{'QMAKESPEC'} = 'macx-g++';
  703. +$ENV{'MACOSX_DEPLOYMENT_TARGET'} = $OSTARGET;
  704. +
  705. +$ENV{'CFLAGS'} = $ENV{'CXXFLAGS'} = $ENV{'ECXXFLAGS'} = "$SDKISYSROOT -I$PREFIX/include -I$PREFIX/mysql";
  706. +$ENV{'LDFLAGS'} = "$SDKLSYSROOT -L$PREFIX/lib -F$QTLIB";
  707. +$ENV{'PREFIX'} = $PREFIX;
  708. +$ENV{'SDKROOT'} = $SDKROOT;
  709. +
  710. +# compilation flags used for compiling dependency tools, do not use multi-architecture
  711. +our $CFLAGS = $ENV{'CFLAGS'};
  712. +our $CXXFLAGS = $ENV{'CXXFLAGS'};
  713. +our $ECXXFLAGS = $ENV{'ECXXFLAGS'};
  714. +our $LDFLAGS = $ENV{'LDFLAGS'};
  715. +our $ARCHARG = "";
  716. +our @ARCHS;
  717. +
  718. +# Check host computer architecture and create list of architecture to build
  719. +my $arch = `sysctl -n hw.machine`; chomp $arch;
  720. +if ( $OPT{'m32'} && ! $OPT{'universal'} )
  721. +{
  722. + &Verbose('Forcing 32 bits build...');
  723. + $ENV{'CFLAGS'} .= ' -m32';
  724. + $ENV{'CXXFLAGS'} .= ' -m32';
  725. + $ENV{'ECXXFLAGS'} .= ' -m32'; # MythTV configure
  726. + $ENV{'LDFLAGS'} .= ' -m32';
  727. + if ( $arch eq "x86_64" || $arch eq "i386" )
  728. + {
  729. + $ARCHARG = "-arch i386";
  730. + push @ARCHS, "i386";
  731. + }
  732. + else
  733. + {
  734. + # assume PPC, what else could it be?
  735. + $ARCHARG = "-arch ppc7400";
  736. + push @ARCHS, "ppc7400";
  737. + }
  738. +}
  739. +elsif ( $arch eq "x86_64" || $arch eq "ppc64" )
  740. +{
  741. + if ( $OPT{'universal'} )
  742. + {
  743. + # Requested universal, and 64 bits host
  744. + &Verbose('Building 32/64 bits universal app...');
  745. + if ( $arch eq "x86_64" )
  746. + {
  747. + $ENV{'CFLAGS'} .= ' -arch i386 -arch x86_64';
  748. + $ENV{'CXXFLAGS'} .= ' -arch i386 -arch x86_64';
  749. + $ENV{'ECXXFLAGS'} .= ' -arch i386 -arch x86_64'; # MythTV configure
  750. + $ENV{'LDFLAGS'} .= ' -arch i386 -arch x86_64';
  751. + $ARCHARG = "-arch i386 -arch x86_64";
  752. + push @ARCHS, "i386", "x86_64";
  753. + }
  754. + else
  755. + {
  756. + $ENV{'CFLAGS'} .= ' -arch ppc7400 -arch ppc64';
  757. + $ENV{'CXXFLAGS'} .= ' -arch ppc7400 -arch ppc64';
  758. + $ENV{'ECXXFLAGS'} .= ' -arch ppc7400 -arch ppc64'; # MythTV configure
  759. + $ENV{'LDFLAGS'} .= ' -arch ppc7400 -arch ppc64';
  760. + $ARCHARG = ' -arch ppc7400 -arch ppc64';
  761. + push @ARCHS, "ppc7400", "ppc64";
  762. + }
  763. + }
  764. + else
  765. + {
  766. + if ( $arch eq "x86_64" )
  767. + {
  768. + $ARCHARG = "-arch x86_64";
  769. + push @ARCHS, "x86_64";
  770. + }
  771. + else
  772. + {
  773. + $ARCHARG = "-arch ppc64";
  774. + push @ARCHS, "ppc64";
  775. + }
  776. + }
  777. +}
  778. +else
  779. +{
  780. + if ( $arch eq "i386" )
  781. + {
  782. + push @ARCHS, "i386";
  783. + }
  784. + else
  785. + {
  786. + push @ARCHS, "ppc7400";
  787. + }
  788. + $OPT{'universal'} = 0;
  789. +}
  790. +
  791. +# Test if Qt libraries support required architectures. We do so by generating a dummy project and trying to compile it
  792. +&Verbose("Testing Qt environment");
  793. +my $dir = tempdir( );#CLEANUP => 1 );
  794. +my $tmpe = "$dir/test";
  795. +my $tmpcpp = "$dir/test.cpp";
  796. +my $tmppro = "$dir/test.pro";
  797. +my $make = "$dir/Makefile";
  798. +open fdcpp, ">", $tmpcpp;
  799. +print fdcpp "#include <QString>\nint main(void) { QString(); }\n";
  800. +close fdcpp;
  801. +open fdpro, ">", $tmppro;
  802. +my $name = basename($tmpe);
  803. +print fdpro "SOURCES=$tmpcpp\nTARGET=$name\nDESTDIR=$dir\nCONFIG-=app_bundle";
  804. +close fdpro;
  805. +&Syscall("$QTBIN/qmake \"QMAKE_CC=$CCBIN\" \"QMAKE_CXX=$CXXBIN\" \"QMAKE_CXXFLAGS=$ENV{'ECXXFLAGS'}\" \"QMAKE_CFLAGS=$ENV{'CFLAGS'}\" \"QMAKE_LFLAGS+=$ENV{'LDFLAGS'}\" -o $make $tmppro");# 2> /dev/null > /dev/null");
  806. +&Syscall(['/bin/rm' , '-f', $tmpe]);
  807. +my $result = &Syscall("/usr/bin/make -C $dir -f $make $name");# 2>/dev/null >/dev/null");
  808. +
  809. +if ( $result ne "1" )
  810. +{
  811. + &Complain("Couldn't use Qt for the architectures @ARCHS. If using -universal or -m32, make sure the Qt frameworks is build for those architectures");
  812. + exit;
  813. +}
  814. +
  815. +# show summary of build parameters.
  816. +&Verbose("DEVROOT = $DEVROOT");
  817. +&Verbose("SDKVER = $SDKVER");
  818. +&Verbose("SDKROOT = $SDKROOT");
  819. +&Verbose("CCBIN = $ENV{'CC'}");
  820. +&Verbose("CXXBIN = $ENV{'CXX'}");
  821. +&Verbose("CFLAGS = $ENV{'CFLAGS'}");
  822. +&Verbose("LDFLAGS = $ENV{'LDFLAGS'}");
  823. +
  824. +# Test if LLVM, mythtv doesn't compile unless you build in debug mode
  825. +my $out = `$CCBIN --version`;
  826. +if ( $out =~ m/llvm/ )
  827. +{
  828. + $OPT{'debug'} = 1;
  829. + &Verbose('Using LLVM: Forcing debug compile...');
  830. +}
  831. +
  832. +our $standard_make = '/usr/bin/make';
  833. +our $parallel_make = $standard_make;
  834. +our $parallel_make_flags = '';
  835. +
  836. +my $cmd = "/usr/bin/hostinfo | grep 'processors\$'";
  837. +&Verbose($cmd);
  838. +my $cpus = `$cmd`; chomp $cpus;
  839. +$cpus =~ s/.*, (\d+) processors$/$1/;
  840. +if ( $cpus gt 1 )
  841. +{
  842. + &Verbose("Using", $cpus+1, "jobs on $cpus parallel CPUs");
  843. + ++$cpus;
  844. + $parallel_make_flags = "-j$cpus";
  845. +}
  846. +
  847. +if ($OPT{'noparallel'})
  848. +{
  849. + $parallel_make_flags = '';
  850. +}
  851. +$parallel_make .= " $parallel_make_flags";
  852. +
  853. +our %depend = (
  854. +
  855. + 'git' =>
  856. + {
  857. + 'url' => 'http://www.kernel.org/pub/software/scm/git/git-1.7.3.4.tar.bz2',
  858. + 'parallel-make' => 'yes'
  859. + },
  860. +
  861. + 'freetype' =>
  862. + {
  863. + 'url' => "$sourceforge/sourceforge/freetype/freetype-2.4.8.tar.gz",
  864. + },
  865. +
  866. + 'lame' =>
  867. + {
  868. + 'url' => "$sourceforge/sourceforge/lame/lame-3.99.5.tar.gz",
  869. + 'conf' => [
  870. + '--disable-frontend',
  871. + ],
  872. + },
  873. +
  874. + 'libmad' =>
  875. + {
  876. + 'url' => "$sourceforge/sourceforge/mad/libmad-0.15.0b.tar.gz",
  877. + 'parallel-make' => 'yes'
  878. + },
  879. +
  880. + # default generated taglib configure is bugger and won't compile universal file. So need to regenerate it
  881. + # new version of taglib 1.7 uses cmake which takes excessively long time to compile. So stick with 1.6.3
  882. + 'taglib' =>
  883. + {
  884. + 'url' => 'http://developer.kde.org/~wheeler/files/src/taglib-1.6.3.tar.gz',
  885. + 'pre-conf' => "cp $PREFIX/share/libtool/config/ltmain.sh admin/ ; " .
  886. + "cp $PREFIX/share/aclocal/libtool.m4 admin/libtool.m4.in ; " .
  887. + "$PREFIX/bin/autoreconf",
  888. + },
  889. +
  890. + 'libogg' =>
  891. + {
  892. + 'url' => 'http://downloads.xiph.org/releases/ogg/libogg-1.3.0.tar.gz',
  893. + },
  894. +
  895. + 'vorbis' =>
  896. + {
  897. + 'url' => 'http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.2.tar.gz',
  898. + },
  899. +
  900. + 'flac' =>
  901. + {
  902. + 'url' => "$sourceforge/sourceforge/flac/flac-1.2.1.tar.gz",
  903. + # Workaround Intel problem - Missing _FLAC__lpc_restore_signal_asm_ia32
  904. + 'conf' => [
  905. + '--disable-asm-optimizations',
  906. + ],
  907. + # patch to support universal compilation and fix incorrect sizeof
  908. + 'post-conf' => "echo \"/#define SIZEOF_VOIDP/c\n" .
  909. + "#ifdef __LP64__\n" .
  910. + "#define SIZEOF_VOIDP 8\n" .
  911. + "#else\n" .
  912. + "#define SIZEOF_VOIDP 4\n" .
  913. + "#endif\n" .
  914. + ".\n" .
  915. + "w\" | /bin/ed config.h ; sed -i -e 's/CC -dynamiclib/CC -dynamiclib $ARCHARG/g' libtool",
  916. + },
  917. +
  918. + # pkgconfig 0.26 and above do not include glib which is required to compile
  919. + # glib requires pkgconfig to compile, so it's a chicken and egg problem.
  920. + # Use nothing newer than 0.25 on OSX.
  921. + 'pkgconfig' =>
  922. + {
  923. + 'url' => "http://pkgconfig.freedesktop.org/releases/pkg-config-0.25.tar.gz",
  924. + 'conf-cmd' => "CFLAGS=\"\" LDFLAGS=\"\" ./configure",
  925. + 'conf' => [
  926. + "--prefix=$PREFIX",
  927. + "--disable-static",
  928. + "--enable-shared",
  929. + ],
  930. +
  931. + },
  932. +
  933. + 'dvdcss' =>
  934. + {
  935. + 'url' => 'http://download.videolan.org/pub/videolan/libdvdcss/1.2.11/libdvdcss-1.2.11.tar.bz2',
  936. + },
  937. +
  938. + 'mysqlclient' =>
  939. + {
  940. + 'url' => 'http://downloads.mysql.com/archives/mysql-5.1/mysql-5.1.56.tar.gz',
  941. + 'conf' => [
  942. + '--without-debug',
  943. + '--without-docs',
  944. + '--without-man',
  945. + '--without-bench',
  946. + '--without-server',
  947. + '--without-geometry',
  948. + '--without-extra-tools',
  949. + ],
  950. + },
  951. +
  952. + 'dbus' =>
  953. + {
  954. + 'url' => 'http://dbus.freedesktop.org/releases/dbus/dbus-1.0.3.tar.gz',
  955. + 'post-make' => 'mv $PREFIX/lib/dbus-1.0/include/dbus/dbus-arch-deps.h '.
  956. + ' $PREFIX/include/dbus-1.0/dbus ; '.
  957. + 'rm -fr $PREFIX/lib/dbus-1.0 ; '.
  958. + 'cd $PREFIX/bin ; '.
  959. + 'echo "#!/bin/sh
  960. + if [ \"\$2\" = dbus-1 ]; then
  961. + case \"\$1\" in
  962. + \"--version\") echo 1.0.3 ;;
  963. + \"--cflags\") echo -I$PREFIX/include/dbus-1.0 ;;
  964. + \"--libs\") echo \"-L$PREFIX/lib -ldbus-1\" ;;
  965. + esac
  966. + fi
  967. + exit 0" > pkg-config ; '.
  968. + 'chmod 755 pkg-config'
  969. + },
  970. +
  971. + 'qt'
  972. + =>
  973. + {
  974. + 'url' => "http://download.qt.nokia.com/qt/source/qt-everywhere-opensource-src-${QTVERSION}.tar.gz",
  975. + 'pre-conf'
  976. + => # Get around Qt bug QTBUG-24498 (4.8.0) && stupid thing can't compile in release mode on mac without framework active
  977. + #also hack for QTBUG-23258
  978. + "find . -name \"*.pro\" -exec sed -i -e \"s:/Developer/SDKs/:.*:g\" {} \\;",
  979. + 'conf-cmd'
  980. + => "cd src/plugins/sqldrivers/mysql && $QTBIN/qmake \"QMAKE_CC=$CCBIN\" \"QMAKE_CXX=$CXXBIN\" \"QMAKE_CXXFLAGS=$ENV{'ECXXFLAGS'}\" \"QMAKE_CFLAGS=$ENV{'CFLAGS'}\" \"QMAKE_LFLAGS+=$ENV{'LDFLAGS'}\" \"INCLUDEPATH+=$PREFIX/include/mysql\" \"LIBS+=-L$PREFIX/lib/mysql -lmysqlclient_r\" \"target.path=$PREFIX/qtplugins-$QTVERSION\" mysql.pro",
  981. + 'make-cmd' => 'cd src/plugins/sqldrivers/mysql',
  982. + 'make' => [ ],
  983. + 'post-make' => 'cd src/plugins/sqldrivers/mysql ; make install ; '.
  984. + 'make -f Makefile.Release install ; '.
  985. + 'cd $PREFIX/lib ; ln -s mysql lib; '.
  986. + 'rm -f $PREFIX/bin/pkg-config ; '.
  987. + '',
  988. + #WebKit in Qt keeps erroring half way on my quad-core when using -jX, use -noparallel
  989. + 'parallel-make' => 'yes'
  990. + },
  991. +
  992. + 'exif' =>
  993. + {
  994. + 'url' => "$sourceforge/sourceforge/libexif/libexif-0.6.20.tar.bz2",
  995. + 'conf' => [
  996. + '--disable-docs'
  997. + ]
  998. + },
  999. +
  1000. + 'yasm' =>
  1001. + {
  1002. + 'url' => 'http://www.tortall.net/projects/yasm/releases/yasm-1.2.0.tar.gz',
  1003. + },
  1004. +
  1005. + 'ccache' =>
  1006. + {
  1007. + 'url' => 'http://samba.org/ftp/ccache/ccache-3.1.4.tar.bz2',
  1008. + 'parallel-make' => 'yes'
  1009. + },
  1010. +
  1011. + 'libcddb' =>
  1012. + {
  1013. + 'url' => 'http://prdownloads.sourceforge.net/libcddb/libcddb-1.3.2.tar.bz2',
  1014. + },
  1015. +
  1016. + 'libcdio' =>
  1017. + {
  1018. + 'url' => 'http://ftp.gnu.org/pub/gnu/libcdio/libcdio-0.83.tar.bz2',
  1019. + },
  1020. +
  1021. + 'liberation-sans' =>
  1022. + {
  1023. + 'url' => 'https://fedorahosted.org/releases/l/i/liberation-fonts/liberation-fonts-ttf-1.07.1.tar.gz',
  1024. + 'conf-cmd' => 'echo "all:" > Makefile',
  1025. + 'make' => [ ], # override the default 'make all install' targets
  1026. + },
  1027. +
  1028. + 'firewiresdk' =>
  1029. + {
  1030. + 'url' => 'http://www.avenard.org/files/mac/AVCVideoServices.framework.tar.gz',
  1031. + 'conf-cmd' => 'cd',
  1032. + 'make-cmd' => "rm -rf $PREFIX/lib/AVCVideoServices.framework ; cp -R . $PREFIX/lib/AVCVideoServices.framework",
  1033. + 'make' => [ ],
  1034. + },
  1035. +
  1036. + 'cmake' =>
  1037. + {
  1038. + 'url' => 'http://www.cmake.org/files/v2.8/cmake-2.8.7.tar.gz',
  1039. + },
  1040. +
  1041. + 'libtool' =>
  1042. + {
  1043. + 'url' => 'http://ftpmirror.gnu.org/libtool/libtool-2.4.2.tar.gz',
  1044. + },
  1045. +
  1046. + 'autoconf' =>
  1047. + {
  1048. + 'url' => 'http://ftp.gnu.org/gnu/autoconf/autoconf-2.68.tar.gz',
  1049. + },
  1050. + 'automake' =>
  1051. + {
  1052. + 'url' => 'http://ftp.gnu.org/gnu/automake/automake-1.11.tar.gz',
  1053. + },
  1054. +
  1055. +);
  1056. +
  1057. +
  1058. +### Check for app present in target location
  1059. +our $MFE = "$SCRIPTDIR/MythFrontend.app";
  1060. +if ( -d $MFE && ! $OPT{'nobundle'} && ! $OPT{'distclean'} )
  1061. +{
  1062. + &Complain(<<END);
  1063. +$MFE already exists
  1064. +
  1065. +Error: a MythFrontend application exists where we were planning
  1066. +to build one. Please move this application away before running
  1067. +this script.
  1068. +
  1069. +END
  1070. + exit;
  1071. +}
  1072. +
  1073. +### Third party packages
  1074. +my ( @build_depends, %seen_depends );
  1075. +my @comps = ( 'mythtv', @components, 'packaging' );
  1076. +
  1077. +# Deal with user-supplied skip arguments
  1078. +if ( $OPT{'mythtvskip'} )
  1079. +{ @comps = grep(!m/mythtv/, @comps) }
  1080. +if ( $OPT{'pluginskip'} )
  1081. +{ @comps = grep(!m/mythplugins/, @comps) }
  1082. +
  1083. +if ( ! @comps )
  1084. +{
  1085. + &Complain("Nothing to build! Too many ...skip arguments?");
  1086. + exit;
  1087. +}
  1088. +
  1089. +&Verbose("Including components:", @comps);
  1090. +
  1091. +# If no Git in path, and we are checking something out, build Git:
  1092. +if ( ( ! $git || $git =~ m/no git in / ) && ! $OPT{'nohead'} )
  1093. +{
  1094. + $git = "$PREFIX/bin/git";
  1095. + @build_depends = ( 'git' );
  1096. +}
  1097. +
  1098. +foreach my $comp (@comps)
  1099. +{
  1100. + foreach my $dep (@{ $depend_order{$comp} })
  1101. + {
  1102. + unless (exists $seen_depends{$dep})
  1103. + {
  1104. + push(@build_depends, $dep);
  1105. + $seen_depends{$dep} = 1;
  1106. + }
  1107. + }
  1108. +}
  1109. +foreach my $sw ( @build_depends )
  1110. +{
  1111. + # Get info about this package
  1112. + my $pkg = $depend{$sw};
  1113. + my $url = $pkg->{'url'};
  1114. + my $filename = $url;
  1115. + $filename =~ s|^.+/([^/]+)$|$1|;
  1116. + my $dirname = $filename;
  1117. + $filename = $ARCHIVEDIR . '/' . $filename;
  1118. + $dirname =~ s|\.tar\.gz$||;
  1119. + $dirname =~ s|\.tar\.bz2$||;
  1120. +
  1121. + chdir($SRCDIR);
  1122. +
  1123. + # Download and decompress
  1124. + unless ( -e $filename )
  1125. + {
  1126. + &Verbose("Downloading $sw");
  1127. + unless (&Syscall([ '/usr/bin/curl', '-f', '-L', $url, '>', $filename ],
  1128. + 'munge' => 1))
  1129. + {
  1130. + &Syscall([ '/bin/rm', $filename ]) if (-e $filename);
  1131. + die;
  1132. + }
  1133. + }
  1134. + else
  1135. + { &Verbose("Using previously downloaded $sw") }
  1136. +
  1137. + if ( $pkg->{'skip'} )
  1138. + { next }
  1139. +
  1140. + if ( -d $dirname )
  1141. + {
  1142. + if ( $OPT{'thirdclean'} )
  1143. + {
  1144. + &Verbose("Removing previous build of $sw");
  1145. + &Syscall([ '/bin/rm', '-f', '-r', $dirname ]) or die;
  1146. + }
  1147. +
  1148. + if ( $OPT{'thirdskip'} )
  1149. + {
  1150. + &Verbose("Using previous build of $sw");
  1151. + next;
  1152. + }
  1153. +
  1154. + &Verbose("Using previously unpacked $sw");
  1155. + }
  1156. + else
  1157. + {
  1158. + &Verbose("Unpacking $sw");
  1159. + if ( substr($filename,-3) eq ".gz" )
  1160. + { &Syscall([ '/usr/bin/tar', '-xzf', $filename ]) or die }
  1161. + elsif ( substr($filename,-4) eq ".bz2" )
  1162. + { &Syscall([ '/usr/bin/tar', '-xjf', $filename ]) or die }
  1163. + else
  1164. + {
  1165. + &Complain("Cannot unpack file $filename");
  1166. + exit;
  1167. + }
  1168. + }
  1169. +
  1170. + # Configure
  1171. + chdir($dirname);
  1172. + unless (-e '.osx-config')
  1173. + {
  1174. + &Verbose("Configuring $sw");
  1175. + if ( $pkg->{'pre-conf'} )
  1176. + { &Syscall([ $pkg->{'pre-conf'} ], 'munge' => 1) or die }
  1177. +
  1178. + my (@configure, $munge);
  1179. +
  1180. + if ( $pkg->{'conf-cmd'} )
  1181. + {
  1182. + my $tmp = $pkg->{'conf-cmd'};
  1183. + push(@configure, $tmp);
  1184. + $munge = 1;
  1185. + }
  1186. + else
  1187. + {
  1188. + push(@configure, "./configure",
  1189. + "--prefix=$PREFIX",
  1190. + "--disable-static",
  1191. + "--enable-shared");
  1192. + if ( $OPT{'universal'} )
  1193. + {
  1194. + push(@configure, "--disable-dependency-tracking");
  1195. + }
  1196. + }
  1197. + if ( $pkg->{'conf'} )
  1198. + {
  1199. + push(@configure, @{ $pkg->{'conf'} });
  1200. + }
  1201. + &Syscall(\@configure, 'interpolate' => 1, 'munge' => $munge) or die;
  1202. + if ( $pkg->{'post-conf'} )
  1203. + {
  1204. + &Syscall([ $pkg->{'post-conf'} ], 'munge' => 1) or die;
  1205. + }
  1206. + &Syscall([ '/usr/bin/touch', '.osx-config' ]) or die;
  1207. + }
  1208. + else
  1209. + { &Verbose("Using previously configured $sw") }
  1210. +
  1211. + # Build and install
  1212. + unless (-e '.osx-built')
  1213. + {
  1214. + &Verbose("Making $sw");
  1215. + my (@make);
  1216. +
  1217. + if ( $pkg->{'make-cmd' } )
  1218. + {
  1219. + push(@make, $pkg->{'make-cmd' });
  1220. + }
  1221. + else
  1222. + {
  1223. + push(@make, $standard_make);
  1224. + if ( $pkg->{'parallel-make'} && $parallel_make_flags )
  1225. + { push(@make, $parallel_make_flags) }
  1226. + }
  1227. + if ( $pkg->{'make'} )
  1228. + { push(@make, @{ $pkg->{'make'} }) }
  1229. + else
  1230. + { push(@make, 'all', 'install') }
  1231. +
  1232. + &Syscall(\@make) or die;
  1233. + if ( $pkg->{'post-make'} )
  1234. + {
  1235. + &Syscall([ $pkg->{'post-make'} ], 'munge' => 1) or die;
  1236. + }
  1237. + &Syscall([ '/usr/bin/touch', '.osx-built' ]) or die;
  1238. + }
  1239. + else
  1240. + {
  1241. + &Verbose("Using previously built $sw");
  1242. + }
  1243. +}
  1244. +
  1245. +if ( $OPT{'bootstrap'} )
  1246. +{
  1247. + exit;
  1248. +}
  1249. +
  1250. +#
  1251. +# Work out Git branches, revisions and tags.
  1252. +# Note these vars are unused if nohead or srcdir set!
  1253. +#
  1254. +my $gitrepository = 'git://github.com/MythTV/mythtv.git';
  1255. +my $gitpackaging = 'git://github.com/MythTV/packaging.git';
  1256. +
  1257. +my $gitfetch = 0; # Synchronise cloned database copy before checkout?
  1258. +my $gitpull = 1; # Cause a fast-forward
  1259. +my $gitrevSHA = 0;
  1260. +my $gitrevert = 0; # Undo any local changes?
  1261. +
  1262. +if ( $OPT{'gitrev'} )
  1263. +{
  1264. + # This arg. could be '64d9d7c5...' (up to 40 hex digits),
  1265. + # a branch like 'mythtv-rec', 'nigelfixes' or 'master',
  1266. + # or a tag name like 'fixes/0.24'.
  1267. +
  1268. + $gitrevision = $OPT{'gitrev'};
  1269. +
  1270. + # If it is a hex revision, we checkout and don't pull mythtv src
  1271. + if ( $gitrevision =~ /^[0-9a-f]{7,40}$/ )
  1272. + {
  1273. + $gitrevSHA = 1;
  1274. + $gitfetch = 1; # Rev. might be newer than local cache
  1275. + $gitpull = 0; # Checkout creates "detached HEAD", git pull will fail
  1276. + }
  1277. +}
  1278. +
  1279. +# Retrieve source
  1280. +if ( $OPT{'srcdir'} )
  1281. +{
  1282. + chdir($SCRIPTDIR);
  1283. + &Syscall(['rm', '-fr', $GITDIR]);
  1284. + &Syscall(['mkdir', '-p', $GITDIR]);
  1285. + foreach my $dir ( @comps )
  1286. + {
  1287. + if ($dir eq 'packaging' && $OPT{'pkgsrcdir'})
  1288. + {
  1289. + &Syscall(['cp', '-pR', "$OPT{'pkgsrcdir'}", "$GITDIR/$dir"]);
  1290. + }
  1291. + else
  1292. + {
  1293. + &Syscall(['cp', '-pR', "$OPT{'srcdir'}/$dir", "$GITDIR/$dir"]);
  1294. + }
  1295. + }
  1296. + &Syscall("mkdir -p $GITDIR/mythtv/config")
  1297. +}
  1298. +elsif ( ! $OPT{'nohead'} )
  1299. +{
  1300. + # Only do 'git clone' if mythtv directory does not exist.
  1301. + # Always do 'git checkout' to make sure we have the right branch,
  1302. + # then 'git pull' to get up to date.
  1303. + if ( ! -e $GITDIR )
  1304. + {
  1305. + Verbose("Checking out source code");
  1306. + &Syscall([ $git, 'clone', $gitrepository, $GITDIR ]) or die;
  1307. + }
  1308. + if ( ! -e "$GITDIR/packaging" )
  1309. + {
  1310. + Verbose("Checking out packaging code");
  1311. + &Syscall([ $git, 'clone',
  1312. + $gitpackaging, $GITDIR . '/packaging' ]) or die;
  1313. + }
  1314. +
  1315. + my @gitcheckoutflags;
  1316. +
  1317. + if ( $gitrevert )
  1318. + { @gitcheckoutflags = ( 'checkout', '--force', $gitrevision ) }
  1319. + else
  1320. + { @gitcheckoutflags = ( 'checkout', '--merge', $gitrevision ) }
  1321. +
  1322. +
  1323. + chdir $GITDIR;
  1324. + if ( $gitfetch ) # Update Git DB
  1325. + { &Syscall([ $git, 'fetch' ]) or die }
  1326. + &Syscall([ $git, @gitcheckoutflags ]) or die;
  1327. + if ( $gitpull ) # Fast-forward
  1328. + { &Syscall([ $git, 'pull' ]) or die }
  1329. +
  1330. + chdir "$GITDIR/packaging";
  1331. + if ( $gitfetch ) # Update Git DB
  1332. + { &Syscall([ $git, 'fetch' ]) or die }
  1333. + if ( $gitrevSHA )
  1334. + {
  1335. + &Syscall([ $git, 'checkout', 'master' ]) or die;
  1336. + &Syscall([ $git, 'merge', 'master' ]) or die;
  1337. + }
  1338. + else
  1339. + {
  1340. + &Syscall([ $git, @gitcheckoutflags ]) or die;
  1341. + if ( $gitpull ) # Fast-forward
  1342. + { &Syscall([ $git, 'pull' ]) or die }
  1343. + }
  1344. +}
  1345. +
  1346. +# Make a convenience (non-hidden) directory for editing src code:
  1347. +system("ln -sf $GITDIR $SCRIPTDIR/src");
  1348. +
  1349. +if ( $OPT{'universal'} && ($OPT{'nodistclean'} || $OPT{'noclean'}) )
  1350. +{
  1351. + &Complain("Cannot use noclean options when building universal packages");
  1352. + exit;
  1353. +}
  1354. +
  1355. +if ( ! $OPT{'nodistclean'} )
  1356. +{
  1357. + if ( $OPT{'mythtvskip'} )
  1358. + {
  1359. + &Complain("Cannot skip building mythtv src if also cleaning, use -nodistclean");
  1360. + exit;
  1361. + }
  1362. + &Distclean(""); # Clean myth system installed libraries
  1363. +}
  1364. +
  1365. +foreach my $arch (@ARCHS)
  1366. +{
  1367. + ### build MythTV
  1368. + &Verbose("Compiling for $arch architecture");
  1369. +
  1370. + # Clean any previously installed libraries
  1371. + if ( ! $OPT{'nodistclean'} )
  1372. + {
  1373. + &Verbose("Cleaning previous installs of MythTV for arch: $arch");
  1374. + &Distclean($arch);
  1375. + }
  1376. +
  1377. + $ENV{'CFLAGS'} = "-arch $arch $CFLAGS";
  1378. + $ENV{'CXXFLAGS'} = "-arch $arch $CXXFLAGS";
  1379. + $ENV{'LDFLAGS'} = "-arch $arch $LDFLAGS";
  1380. + $ENV{'ECXXFLAGS'} = "-arch $arch $ECXXFLAGS";
  1381. +
  1382. + # show summary of build parameters.
  1383. + &Verbose("CFLAGS = $ENV{'CFLAGS'}");
  1384. + &Verbose("LDFLAGS = $ENV{'LDFLAGS'}");
  1385. +
  1386. + # Build MythTV and any plugins
  1387. + foreach my $comp (@comps)
  1388. + {
  1389. + my $compdir = "$GITDIR/$comp/" ;
  1390. +
  1391. + chdir $compdir || die "No source directory $compdir";
  1392. +
  1393. + if ( ! -e "$comp.pro" and ! -e 'Makefile' and ! -e 'configure' )
  1394. + {
  1395. + &Complain("Nothing to configure/make in $compdir for $arch");
  1396. + next;
  1397. + }
  1398. +
  1399. + if ( ($OPT{'distclean'} || ! $OPT{'noclean'}) && -e 'Makefile' )
  1400. + {
  1401. + &Verbose("Cleaning $comp for $arch");
  1402. + &Syscall([ $standard_make, 'distclean' ]);
  1403. + }
  1404. + next if $OPT{'distclean'};
  1405. +
  1406. + # Apply any nasty mac-specific patches
  1407. + if ( $patches{$comp} )
  1408. + {
  1409. + &Syscall([ "echo '$patches{$comp}' | patch -p0 --forward" ]);
  1410. + }
  1411. +
  1412. + # configure and make
  1413. + if ( $makecleanopt{$comp} && -e 'Makefile' && ! $OPT{'noclean'} )
  1414. + {
  1415. + my @makecleancom = $standard_make;
  1416. + push(@makecleancom, @{ $makecleanopt{$comp} }) if $makecleanopt{$comp};
  1417. + &Syscall([ @makecleancom ]) or die;
  1418. + }
  1419. + if ( -e 'configure' && ! $OPT{'noclean'} )
  1420. + {
  1421. + &Verbose("Configuring $comp for $arch");
  1422. + my @config = './configure';
  1423. + push(@config, @{ $conf{$comp} }) if $conf{$comp};
  1424. + push @config, "--prefix=$PREFIX/$arch";
  1425. + push @config, "--cc=$CCBIN";
  1426. + push @config, "--cxx=$CXXBIN";
  1427. + push @config, "--qmake=$QTBIN/qmake";
  1428. + push @config, "--extra-libs=-F$QTLIB";
  1429. +
  1430. + if ( $OPT{'profile'} )
  1431. + {
  1432. + push @config, '--compile-type=profile'
  1433. + }
  1434. + if ( $OPT{'debug'} )
  1435. + {
  1436. + push @config, '--compile-type=debug'
  1437. + }
  1438. + &Syscall([ @config ]) or die;
  1439. + }
  1440. + if ( (! -e 'configure') && -e "$comp.pro" && ! $OPT{'noclean'} )
  1441. + {
  1442. + &Verbose("Running qmake for $comp for $arch");
  1443. + my @qmake_opts = (
  1444. + "\"QMAKE_CC=$CCBIN\" \"QMAKE_CXX=$CXXBIN\" \"QMAKE_CXXFLAGS=$ENV{'CXXFLAGS'}\" \"QMAKE_CFLAGS=$ENV{'CFLAGS'}\" \"QMAKE_LFLAGS+=$ENV{'LDFLAGS'}\"",
  1445. + "INCLUDEPATH+=\"$PREFIX/include\"",
  1446. + "LIBS+=\"-F$QTLIB -L\"$PREFIX/lib\"",
  1447. + );
  1448. + &Syscall([ "$QTBIN/qmake",
  1449. + 'PREFIX=../Resources',
  1450. + @qmake_opts,
  1451. + "$comp.pro" ]) or die;
  1452. + }
  1453. +
  1454. + &Verbose("Making $comp for $arch");
  1455. + &Syscall([ $parallel_make ]) or die;
  1456. +
  1457. + &Verbose("Installing $comp for $arch");
  1458. + &Syscall([ $standard_make, 'install' ]) or die;
  1459. +
  1460. + if ( $cleanLibs && $comp eq 'mythtv' )
  1461. + {
  1462. + # If we cleaned the libs, make install will have recopied them,
  1463. + # which means any dynamic libraries that the static libraries depend on
  1464. + # are newer than the table of contents. Hence we need to regenerate it:
  1465. + my @mythlibs = glob "$PREFIX/lib/libmyth*.a";
  1466. + if ( scalar @mythlibs )
  1467. + {
  1468. + &Verbose("Running ranlib on reinstalled static libraries");
  1469. + foreach my $lib (@mythlibs)
  1470. + { &Syscall("ranlib $lib") or die }
  1471. + }
  1472. + }
  1473. + }
  1474. +}
  1475. +
  1476. +if ( $OPT{'distclean'} )
  1477. +{
  1478. + &Complain("Distclean done ..");
  1479. + exit;
  1480. +}
  1481. +&Complain("Compilation done ..");
  1482. +
  1483. +### Create universal binaries
  1484. +### BIN files
  1485. +&MakeFilesUniversal("bin", glob "$PREFIX/$ARCHS[0]/bin/*");
  1486. +
  1487. +### Libs
  1488. +&MakeFilesUniversal("lib", glob "$PREFIX/$ARCHS[0]/lib/*");
  1489. +
  1490. +&RecursiveCopy("$PREFIX/$ARCHS[0]/share", "$PREFIX");
  1491. +&RecursiveCopy("$PREFIX/$ARCHS[0]/include", "$PREFIX");
  1492. +
  1493. +# stop here if no bundle is to be created
  1494. +if ( $OPT{'nobundle'} )
  1495. +{
  1496. + exit;
  1497. +}
  1498. +
  1499. +### Build version string
  1500. +our $VERS = `find $PREFIX/lib -name 'libmyth-[0-9].[0-9][0-9].[0-9].dylib'`;
  1501. +chomp $VERS;
  1502. +$VERS =~ s/^.*\-(.*)\.dylib$/$1/s;
  1503. +$VERS .= '.' . $OPT{'version'} if $OPT{'version'};
  1504. +
  1505. +### Program which creates bundles:
  1506. +our @bundler = "$GITDIR/packaging/OSX/build/osx-bundler.pl";
  1507. +if ( $OPT{'verbose'} )
  1508. +{ push @bundler, '--verbose' }
  1509. +
  1510. +# Strip unused architectures, this reduces the size quite significantly
  1511. +if ( (`sysctl -n hw.machine` eq "x86_64\n" && $OPT{'m32'}) || `sysctl -n hw.machine` eq "i386\n" )
  1512. +{
  1513. + push @bundler, "--arch", "i386";
  1514. +}
  1515. +elsif ( `sysctl -n hw.machine` eq "x86_64\n" && !$OPT{'universal'} )
  1516. +{
  1517. + #not universal bundle, on 64 bits host: only keep 64 bits binaries
  1518. + push @bundler, "--arch", "x86_64";
  1519. +}
  1520. +
  1521. +### Create each package.
  1522. +### Note that this is a bit of a waste of disk space,
  1523. +### because there are now multiple copies of each library.
  1524. +
  1525. +if ( $jobtools )
  1526. +{ push @targets, @targetsJT }
  1527. +
  1528. +if ( $backend )
  1529. +{ push @targets, @targetsBE }
  1530. +
  1531. +my @libs = ( "$PREFIX/lib/", "$PREFIX/lib/mysql", "$QTLIB" );
  1532. +foreach my $target ( @targets )
  1533. +{
  1534. + my $finalTarget = "$SCRIPTDIR/$target.app";
  1535. + my $builtTarget = lc $target;
  1536. +
  1537. + # Get a fresh copy of the binary
  1538. + &Verbose("Building self-contained $target");
  1539. + &Syscall([ 'rm', '-fr', $finalTarget ]) or die;
  1540. + &Syscall([ 'cp', "$PREFIX/bin/$builtTarget",
  1541. + "$SCRIPTDIR/$target" ]) or die;
  1542. +
  1543. + # Convert it to a bundled .app
  1544. + &Syscall([ @bundler, "$SCRIPTDIR/$target", @libs ]) or die;
  1545. +
  1546. + # Remove copy of binary
  1547. + unlink "$SCRIPTDIR/$target" or die;
  1548. +
  1549. + # Themes are required by all GUI apps. The filters and plugins are not
  1550. + # used by mythtv-setup or mythwelcome, but for simplicity, do them all.
  1551. + if ( $target eq "MythFrontend" or
  1552. + $target eq "MythWelcome" or $target =~ m/^MythTV-/ )
  1553. + {
  1554. + my $res = "$finalTarget/Contents/Resources";
  1555. + my $libs = "$res/lib";
  1556. + my $plug = "$libs/mythtv/plugins";
  1557. +
  1558. + # Install themes, filters, etc.
  1559. + &Verbose("Installing resources into $target");
  1560. + mkdir $res; mkdir $libs;
  1561. + &RecursiveCopy("$PREFIX/lib/mythtv", $libs);
  1562. + mkdir "$res/share";
  1563. + &RecursiveCopy("$PREFIX/share/mythtv", "$res/share");
  1564. +
  1565. + # Correct the library paths for the filters and plugins
  1566. + foreach my $lib ( glob "$libs/mythtv/*/*" )
  1567. + { &Syscall([ @bundler, $lib, @libs ]) or die }
  1568. +
  1569. + if ( -e $plug )
  1570. + {
  1571. + # Allow Finder's 'Get Info' to manage plugin list:
  1572. + &Syscall([ 'mv', $plug, "$finalTarget/Contents/$BundlePlugins" ]) or die;
  1573. + &Syscall([ 'ln', '-s', "../../../$BundlePlugins", $plug ]) or die;
  1574. + }
  1575. +
  1576. + # The icon
  1577. + &Syscall([ 'cp',
  1578. + "$GITDIR/mythtv/programs/mythfrontend/mythfrontend.icns",
  1579. + "$res/application.icns" ]) or die;
  1580. + &Syscall([ 'xcrun', '-sdk', "$SDKNAME", 'SetFile', '-a', 'C', $finalTarget ])
  1581. + or die;
  1582. +
  1583. + # Create PlugIns directory
  1584. + mkdir("$finalTarget/Contents/PlugIns");
  1585. +
  1586. + # Tell Qt to use the PlugIns directory (doesn't work due QTBUG-24541, but in case they fix it)
  1587. + open FH, ">$res/qt.conf";
  1588. + print FH "[Paths]\nPlugins = $BundlePlugins\n";
  1589. + close FH;
  1590. +
  1591. + # Copy the required Qt plugins
  1592. + foreach my $plugin ( "sqldrivers", "imageformats")
  1593. + {
  1594. + &Syscall([ 'mkdir', "$finalTarget/Contents/$BundlePlugins/$plugin" ]) or die;
  1595. + # Have to create links in application folder due to QTBUG-24541
  1596. + &Syscall([ 'ln', '-s', "../$BundlePlugins/$plugin", "$finalTarget/Contents/MacOs/$plugin" ]) or die;
  1597. + }
  1598. +
  1599. + # copy the MySQL sqldriver
  1600. + &Syscall([ 'cp', "$PREFIX/qtplugins-$QTVERSION/libqsqlmysql.dylib", "$finalTarget/Contents/$BundlePlugins/sqldrivers/" ])
  1601. + or die;
  1602. + &Syscall([ @bundler, "$finalTarget/Contents/$BundlePlugins/sqldrivers/libqsqlmysql.dylib", @libs ])
  1603. + or die;
  1604. +
  1605. + foreach my $plugin ( 'imageformats/libqgif.dylib', 'imageformats/libqjpeg.dylib' )
  1606. + {
  1607. + my $pluginSrc = "$QTPLUGINS/$plugin";
  1608. + if ( -e $pluginSrc )
  1609. + {
  1610. + &Syscall([ 'cp', "$QTPLUGINS/$plugin",
  1611. + "$finalTarget/Contents/$BundlePlugins/$plugin" ])
  1612. + or die;
  1613. + &Syscall([ @bundler,
  1614. + "$finalTarget/Contents/$BundlePlugins/$plugin", @libs ])
  1615. + or die;
  1616. + }
  1617. + }
  1618. +
  1619. + # A font the Terra theme uses:
  1620. + my $url = $depend{'liberation-sans'}->{'url'};
  1621. + my $dirname = $url;
  1622. + $dirname =~ s|^.+/([^/]+)$|$1|;
  1623. + $dirname =~ s|\.tar\.gz$||;
  1624. + $dirname =~ s|\.tar\.bz2$||;
  1625. +
  1626. + my $fonts = "$res/share/mythtv/fonts";
  1627. + mkdir $fonts;
  1628. + &RecursiveCopy("$SRCDIR/$dirname/LiberationSans-Regular.ttf", $fonts);
  1629. + &EditPList("$finalTarget/Contents/Info.plist",
  1630. + 'ATSApplicationFontsPath', 'share/mythtv/fonts');
  1631. + }
  1632. +
  1633. + if ( $target eq "MythFrontend" )
  1634. + {
  1635. + my $extralib;
  1636. +
  1637. + foreach my $extra ( 'mythavtest', 'ignyte', 'mythpreviewgen', 'mtd' )
  1638. + {
  1639. + if ( -e "$PREFIX/bin/$extra" )
  1640. + {
  1641. + &Verbose("Installing $extra into $target");
  1642. + &Syscall([ 'cp', "$PREFIX/bin/$extra",
  1643. + "$finalTarget/Contents/MacOS" ]) or die;
  1644. +
  1645. + &Verbose('Updating lib paths of',
  1646. + "$finalTarget/Contents/MacOS/$extra");
  1647. + &Syscall([ @bundler, "$finalTarget/Contents/MacOS/$extra", @libs ])
  1648. + or die;
  1649. + }
  1650. + }
  1651. + &AddFakeBinDir($finalTarget);
  1652. +
  1653. + # Allow playback of region encoded DVDs
  1654. + $extralib = "libdvdcss.2.dylib";
  1655. + &Syscall([ 'cp', "$PREFIX/lib/$extralib",
  1656. + "$finalTarget/Contents/Frameworks" ]) or die;
  1657. + &Syscall([ @bundler, "$finalTarget/Contents/Frameworks/$extralib", @libs ])
  1658. + or die;
  1659. + }
  1660. +
  1661. + if ( $target eq "MythWelcome" )
  1662. + {
  1663. + &Verbose("Installing mythfrontend into $target");
  1664. + &Syscall([ 'cp', "$PREFIX/bin/mythfrontend",
  1665. + "$finalTarget/Contents/MacOS" ]) or die;
  1666. + &Syscall([ @bundler, "$finalTarget/Contents/MacOS/mythfrontend", @libs ])
  1667. + or die;
  1668. + &AddFakeBinDir($finalTarget);
  1669. +
  1670. + # For some unknown reason, mythfrontend looks here for support files:
  1671. + &Syscall([ 'ln', '-s', "../Resources/share", # themes
  1672. + "../Resources/lib", # filters/plugins
  1673. + "$finalTarget/Contents/MacOS" ]) or die;
  1674. + }
  1675. +
  1676. + # rebase segfault on my mac, so disable it for the time being
  1677. + # Run 'rebase' on all the frameworks, for slightly faster loading.
  1678. + # Note that we process the real library, not symlinks to it,
  1679. + # to prevent rebase erroneously creating copies:
  1680. + #my @libs = glob "$finalTarget/Contents/Frameworks/*";
  1681. + #@libs = grep(s,(.*/)(\w+).framework$,$1$2.framework/Versions/A/$2, , @libs);
  1682. +
  1683. + # Also process all the filters/plugins:
  1684. + #push(@libs, glob "$finalTarget/Contents/Resources/lib/mythtv/*/*.dylib");
  1685. + #push(@libs, glob "$finalTarget/Contents/PlugIns/*/*.dylib");
  1686. +
  1687. + #if ( $OPT{'verbose'} )
  1688. + #{ &Syscall([ 'rebase', '-v', @libs ]) or die }
  1689. + #else
  1690. + #{ &Syscall([ 'rebase', @libs ]) or die }
  1691. +
  1692. +}
  1693. +
  1694. +if ( $backend && grep(m/MythBackend/, @targets) )
  1695. +{
  1696. + my $BE = "$SCRIPTDIR/MythBackend.app";
  1697. +
  1698. + # Copy XML files that UPnP requires:
  1699. + my $share = "$BE/Contents/Resources/share/mythtv";
  1700. + &Syscall([ 'mkdir', '-p', $share ]) or die;
  1701. + &Syscall([ 'cp', glob("$PREFIX/share/mythtv/*.xml"), $share ]) or die;
  1702. +
  1703. + # Same for default web server page:
  1704. + &Syscall([ 'cp', '-pR', "$PREFIX/share/mythtv/html", $share ]) or die;
  1705. +
  1706. + # The backend gets all the useful binaries it might call:
  1707. + foreach my $binary ( 'mythjobqueue', 'mythcommflag',
  1708. + 'mythpreviewgen', 'mythtranscode', 'mythfilldatabase' )
  1709. + {
  1710. + my $SRC = "$PREFIX/bin/$binary";
  1711. + if ( -e $SRC )
  1712. + {
  1713. + &Verbose("Installing $SRC into $BE");
  1714. + &Syscall([ '/bin/cp', $SRC, "$BE/Contents/MacOS" ]) or die;
  1715. +
  1716. + &Verbose("Updating lib paths of $BE/Contents/MacOS/$binary");
  1717. + &Syscall([ @bundler, "$BE/Contents/MacOS/$binary", @libs ]) or die;
  1718. + }
  1719. + }
  1720. + &AddFakeBinDir($BE);
  1721. +}
  1722. +
  1723. +if ( $backend && grep(m/MythTV-Setup/, @targets) )
  1724. +{
  1725. + my $SET = "$SCRIPTDIR/MythTV-Setup.app";
  1726. + my $SRC = "$PREFIX/bin/mythfilldatabase";
  1727. + if ( -e $SRC )
  1728. + {
  1729. + &Verbose("Installing $SRC into $SET");
  1730. + &Syscall([ '/bin/cp', $SRC, "$SET/Contents/MacOS" ]) or die;
  1731. +
  1732. + &Verbose("Updating lib paths of $SET/Contents/MacOS/mythfilldatabase");
  1733. + &Syscall([ @bundler, "$SET/Contents/MacOS/mythfilldatabase", @libs ]) or die;
  1734. + }
  1735. + &AddFakeBinDir($SET);
  1736. +}
  1737. +
  1738. +if ( $jobtools )
  1739. +{
  1740. + # JobQueue also gets some binaries it might call:
  1741. + my $JQ = "$SCRIPTDIR/MythJobQueue.app";
  1742. + my $DEST = "$JQ/Contents/MacOS";
  1743. + my $SRC = "$PREFIX/bin/mythcommflag";
  1744. +
  1745. + &Syscall([ '/bin/cp', $SRC, $DEST ]) or die;
  1746. + &AddFakeBinDir($JQ);
  1747. + &Verbose("Updating lib paths of $DEST/mythcommflag");
  1748. + &Syscall([ @bundler, "$DEST/mythcommflag", @libs ]) or die;
  1749. +
  1750. + $SRC = "$PREFIX/bin/mythtranscode.app/Contents/MacOS/mythtranscode";
  1751. + if ( -e $SRC )
  1752. + {
  1753. + &Verbose("Installing $SRC into $JQ");
  1754. + &Syscall([ '/bin/cp', $SRC, $DEST ]) or die;
  1755. + &Verbose("Updating lib paths of $DEST/mythtranscode");
  1756. + &Syscall([ @bundler, "$DEST/mythtranscode", @libs ]) or die;
  1757. + }
  1758. +}
  1759. +
  1760. +# Clean tmp files. Most of these are leftovers from configure:
  1761. +#
  1762. +&Verbose('Cleaning build tmp directory');
  1763. +&Syscall([ 'rm', '-fr', $WORKDIR . '/tmp' ]) or die;
  1764. +&Syscall([ 'mkdir', $WORKDIR . '/tmp' ]) or die;
  1765. +
  1766. +if ($OPT{usehdimage} && !$OPT{leavehdimage} )
  1767. +{
  1768. + Verbose("Dismounting case-sensitive build device");
  1769. + UnmountHDImage();
  1770. +}
  1771. +
  1772. +&Verbose("Build complete. Self-contained package is at:\n\n $MFE\n");
  1773. +
  1774. +### end script
  1775. +exit 0;
  1776. +
  1777. +
  1778. +######################################
  1779. +## RecursiveCopy copies a directory tree, stripping out .git
  1780. +## directories and properly managing static libraries.
  1781. +######################################
  1782. +
  1783. +sub RecursiveCopy($$)
  1784. +{
  1785. + my ($src, $dst) = @_;
  1786. +
  1787. + # First copy absolutely everything
  1788. + &Syscall([ '/bin/cp', '-pR', "$src", "$dst"]) or die;
  1789. +
  1790. + # Then strip out any .git directories
  1791. + my @files = map { chomp $_; $_ } `find $dst -name .git`;
  1792. + if ( scalar @files )
  1793. + {
  1794. + &Syscall([ '/bin/rm', '-f', '-r', @files ]);
  1795. + }
  1796. +
  1797. + # And make sure any static libraries are properly relocated.
  1798. + my @libs = map { chomp $_; $_ } `find $dst -name "lib*.a"`;
  1799. + if ( scalar @libs )
  1800. + {
  1801. + &Syscall([ 'ranlib', '-s', @libs ]);
  1802. + }
  1803. +}
  1804. +
  1805. +######################################
  1806. +## CleanMakefiles removes every generated Makefile
  1807. +## from our MythTV build that contains PREFIX.
  1808. +## Necessary when we change the
  1809. +## PREFIX variable.
  1810. +######################################
  1811. +
  1812. +sub CleanMakefiles
  1813. +{
  1814. + &Verbose("Cleaning MythTV makefiles containing PREFIX");
  1815. + &Syscall([ 'find', '.', '-name', 'Makefile', '-exec',
  1816. + 'egrep', '-q', 'qmake.*PREFIX', '{}', ';', '-delete' ]) or die;
  1817. +} # end CleanMakefiles
  1818. +
  1819. +
  1820. +######################################
  1821. +## Syscall wrappers the Perl "system"
  1822. +## routine with verbosity and error
  1823. +## checking.
  1824. +######################################
  1825. +
  1826. +sub Syscall($%)
  1827. +{
  1828. + my ($arglist, %opts) = @_;
  1829. +
  1830. + unless (ref $arglist)
  1831. + {
  1832. + $arglist = [ $arglist ];
  1833. + }
  1834. + if ( $opts{'interpolate'} )
  1835. + {
  1836. + my @args;
  1837. + foreach my $arg (@$arglist)
  1838. + {
  1839. + $arg =~ s/\$PREFIX/$PREFIX/ge;
  1840. + $arg =~ s/\$SDKROOT/$SDKROOT/ge;
  1841. + $arg =~ s/\$CFLAGS/$ENV{'CFLAGS'};/ge;
  1842. + $arg =~ s/\$LDFLAGS/$ENV{'LDFLAGS'};/ge;
  1843. + $arg =~ s/\$parallel_make_flags/$parallel_make_flags/ge;
  1844. + push(@args, $arg);
  1845. + }
  1846. + $arglist = \@args;
  1847. + }
  1848. + if ( $opts{'munge'} )
  1849. + {
  1850. + $arglist = [ join(' ', @$arglist) ];
  1851. + }
  1852. + # clean out any null arguments
  1853. + $arglist = [ map $_, @$arglist ];
  1854. + &Verbose(@$arglist);
  1855. + my $ret = system(@$arglist);
  1856. + if ( $ret )
  1857. + {
  1858. + &Complain('Failed system call: "', @$arglist,
  1859. + '" with error code', $ret >> 8);
  1860. + }
  1861. + return ($ret == 0);
  1862. +} # end Syscall
  1863. +
  1864. +
  1865. +######################################
  1866. +## Verbose prints messages in verbose
  1867. +## mode.
  1868. +######################################
  1869. +
  1870. +sub Verbose
  1871. +{
  1872. + print STDERR '[osx-pkg] ' . join(' ', @_) . "\n"
  1873. + if $OPT{'verbose'};
  1874. +} # end Verbose
  1875. +
  1876. +
  1877. +######################################
  1878. +## Complain prints messages in any
  1879. +## verbosity mode.
  1880. +######################################
  1881. +
  1882. +sub Complain
  1883. +{
  1884. + print STDERR '[osx-pkg] ' . join(' ', @_) . "\n";
  1885. +} # end Complain
  1886. +
  1887. +
  1888. +######################################
  1889. +## Manage usehdimage disk image
  1890. +######################################
  1891. +
  1892. +sub MountHDImage
  1893. +{
  1894. + if ( ! HDImageDevice() )
  1895. + {
  1896. + if ( -e "$SCRIPTDIR/.osx-packager.dmg" )
  1897. + {
  1898. + Verbose("Mounting existing UFS disk image for the build");
  1899. + }
  1900. + else
  1901. + {
  1902. + Verbose("Creating a case-sensitive (UFS) disk image for the build");
  1903. + Syscall(['hdiutil', 'create', '-size', '2048m',
  1904. + "$SCRIPTDIR/.osx-packager.dmg", '-volname',
  1905. + 'MythTvPackagerHDImage', '-fs', 'UFS', '-quiet']) || die;
  1906. + }
  1907. +
  1908. + &Syscall(['hdiutil', 'mount',
  1909. + "$SCRIPTDIR/.osx-packager.dmg",
  1910. + '-mountpoint', $WORKDIR, '-quiet']) || die;
  1911. + }
  1912. +
  1913. + # configure defaults to /tmp and OSX barfs when mv crosses
  1914. + # filesystems so tell configure to put temp files on the image
  1915. +
  1916. + $ENV{TMPDIR} = $WORKDIR . "/tmp";
  1917. + mkdir $ENV{TMPDIR};
  1918. +}
  1919. +
  1920. +sub UnmountHDImage
  1921. +{
  1922. + my $device = HDImageDevice();
  1923. + if ( $device )
  1924. + {
  1925. + &Syscall(['hdiutil', 'detach', $device, '-force']);
  1926. + }
  1927. +}
  1928. +
  1929. +sub HDImageDevice
  1930. +{
  1931. + my @dev = split ' ', `/sbin/mount | grep $WORKDIR`;
  1932. + $dev[0];
  1933. +}
  1934. +
  1935. +sub CaseSensitiveFilesystem
  1936. +{
  1937. + my $funky = $SCRIPTDIR . "/.osx-packager.FunkyStuff";
  1938. + my $unfunky = substr($funky, 0, -10) . "FUNKySTuFF";
  1939. +
  1940. + unlink $funky if -e $funky;
  1941. + `touch $funky`;
  1942. + my $sensitivity = ! -e $unfunky;
  1943. + unlink $funky;
  1944. +
  1945. + return $sensitivity;
  1946. +}
  1947. +
  1948. +
  1949. +#######################################################
  1950. +## Parts of MythTV try to call helper apps like this:
  1951. +## gContext->GetInstallPrefix() + "/bin/mythtranscode";
  1952. +## which means we need a bin directory.
  1953. +#######################################################
  1954. +
  1955. +sub AddFakeBinDir($)
  1956. +{
  1957. + my ($target) = @_;
  1958. +
  1959. + &Syscall("mkdir -p $target/Contents/Resources");
  1960. + &Syscall(['ln', '-sf', '../MacOS', "$target/Contents/Resources/bin"]);
  1961. +}
  1962. +
  1963. +###################################################################
  1964. +## Update or add <dict> properties in a (non-binary) .plist file ##
  1965. +###################################################################
  1966. +
  1967. +sub EditPList($$$)
  1968. +{
  1969. + my ($file, $key, $value) = @_;
  1970. +
  1971. + &Verbose("Looking for property $key in file $file");
  1972. +
  1973. + open(IN, $file) or die;
  1974. + open(OUT, ">$file.edit") or die;
  1975. + while ( <IN> )
  1976. + {
  1977. + if ( m,\s<key>$key</key>, )
  1978. + {
  1979. + <IN>;
  1980. + &Verbose("Value was $_"); # Does this work?
  1981. + print OUT "<key>$key</key>\n<string>$value</string>\n";
  1982. + next;
  1983. + }
  1984. + elsif ( m,^</dict>$, ) # Not there. Add at end
  1985. + {
  1986. + print OUT "<key>$key</key>\n<string>$value</string>\n";
  1987. + print OUT "</dict>\n</plist>\n";
  1988. + last;
  1989. + }
  1990. +
  1991. + print OUT;
  1992. + }
  1993. + close IN; close OUT;
  1994. + rename("$file.edit", $file);
  1995. +}
  1996. +
  1997. +sub Distclean
  1998. +{
  1999. + my $arch = $_[0];
  2000. + if ( $arch ne "" )
  2001. + {
  2002. + $arch .= "/";
  2003. + }
  2004. + &Syscall("/bin/rm -f $PREFIX/${arch}bin/myth*" );
  2005. + &Syscall("/bin/rm -fr $PREFIX/${arch}lib/libmyth*");
  2006. + &Syscall("/bin/rm -fr $PREFIX/${arch}lib/mythtv" );
  2007. + &Syscall("/bin/rm -fr $PREFIX/${arch}share/mythtv");
  2008. + &Syscall("/bin/rm -fr $PREFIX/${arch}share/mythtv");
  2009. + &Syscall([ 'find', "$GITDIR/", '-name', '*.o', '-delete' ]);
  2010. + &Syscall([ 'find', "$GITDIR/", '-name', '*.a', '-delete' ]);
  2011. + &Syscall([ 'find', "$GITDIR/", '-name', '*.dylib', '-delete' ]);
  2012. + &Syscall([ 'find', "$GITDIR/", '-name', '*.orig', '-delete' ]);
  2013. + &Syscall([ 'find', "$GITDIR/", '-name', '*.rej', '-delete' ]);
  2014. +}
  2015. +
  2016. +#########################################################################
  2017. +## Go through the list of files recursively and combine all architectures
  2018. +# together to form a "fat" universal file
  2019. +#########################################################################
  2020. +
  2021. +sub MakeFilesUniversal($@)
  2022. +{
  2023. + my ($base, @files) = @_;
  2024. + if ( ! -d "$PREFIX/$base" )
  2025. + {
  2026. + &Syscall([ '/bin/mkdir', "$PREFIX/$base" ]);
  2027. + }
  2028. + for my $bin (@files)
  2029. + {
  2030. + my @lipo = "/usr/bin/lipo";
  2031. + my $name = basename($bin);
  2032. + if ( -l $bin || -f $bin )
  2033. + {
  2034. + # destination file exists, remove it
  2035. + &Syscall([ '/bin/rm', "$PREFIX/$base/$name" ] );
  2036. + }
  2037. + if ( -l $bin )
  2038. + {
  2039. + # copy link as is
  2040. + &Syscall([ '/bin/cp', '-R',
  2041. + "$PREFIX/$arch/$base/$name",
  2042. + "$PREFIX/$base/$name" ]);
  2043. + }
  2044. + elsif ( -f $bin )
  2045. + {
  2046. + for my $arch (@ARCHS)
  2047. + {
  2048. + push @lipo, "$PREFIX/$arch/$base/$name";
  2049. + }
  2050. + push @lipo, "-create", "-output", "$PREFIX/$base/$name";
  2051. + &Syscall([ @lipo ]);
  2052. + }
  2053. + elsif ( -d $bin )
  2054. + {
  2055. + &MakeFilesUniversal("$base/$name", glob "$PREFIX/$arch/$base/$name/*")
  2056. + }
  2057. + }
  2058. +}
  2059. +### end file
  2060. +1;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement