#!/usr/bin/perl -w use strict; use warnings; ## Load in certain modules for things we're going to do later... use Cwd; use File::Basename; use File::Copy; use File::Path; use File::Spec::Functions qw(:ALL); use Getopt::Long; use POSIX qw(strftime); ## Here we set some basic settings.. most of these dont need to change very often. my $squeezeCenterStartupScript = "server/slimserver.pl"; my $sourceDirsToExclude = ".svn tests slimp3 squeezebox /softsqueeze tools ext/source ext-all-debug.js"; my $revisionTextFile = "server/revision.txt"; my $revision; my $myVersion = "0.0.3"; my $defaultDestName = "squeezecenter"; my $defaultReleaseType = "nightly"; ## Windows Specific Stuff my $windowsPerlDir = "C:\\perl"; my $windowsPerlPath = "$windowsPerlDir\\bin\\perl.exe"; ## Directories to exclude when building certain packages... my $dirsToExcludeForLinuxTarball = "MSWin32-x86-multi-thread PreventStandby"; my $dirsToExcludeForLinuxNoCpanTarball = "MSWin32-x86-multi-thread darwin i386-linux-thread-multi powerpc-hardhat-linux arch PreventStandby"; my $dirsToExcludeForMacOSX = "i386-linux x86_64-linux MSWin32 powerpc-hardhat-linux PreventStandby"; my $dirsToExcludeForWin32 = "i386-linux x86_64-linux powerpc-hardhat-linux darwin OS/Debian.pm OS/Linux.pm OS/Unix.pm OS/OSX.pm OS/ReadyNAS.pm OS/RedHat.pm OS/Suse.pm OS/SlimService.pm"; my $dirsToExcludeForReadyNas = "x86_64 darwin-thread-multi MSWin32-x86 5.10 DBD PreventStandby"; ## Initialize some variables we'll use later my ($build, $destName, $destDir, $buildDir, $sourceDir, $version, $fakeRoot, $noCPAN, $releaseType, $release, $archType); ############################################################################################## ## Begin the main run of the build... based on input from the user, and dynamically ## ## picked up content like the version #, we'll build only the appropriate files requested ## ############################################################################################## sub main { ## Find out if the user gave us any data.. if not, post the help and quit checkCommandOptions(); ## Get our version #, based on data supplied by user $version = getVersion(); ## Right before we start actually building stuff, print out our config options... printOptions(); ## Set up the directories we need to do to our build setupDirectories(); ## Set the build tree up now... we do this for every distribution we build. setupBuildTree(); ## Ok, begin the IF statement... what are we building? doCommandOptions(); } ############################################################################################## ## Walk through the options passed in by the user, and see if they make sense. If they ## ## don't, we'll exit here and show them the usage guidelines. ## ############################################################################################## sub checkCommandOptions { ## First, lets make sure they sent the most basic option we need, a build target... GetOptions( 'build=s' => \$build, 'buildDir=s' => \$buildDir, 'sourceDir=s' => \$sourceDir, 'destName=s' => \$destName, 'destDir=s' => \$destDir, 'noCPAN' => \$noCPAN, 'releaseType=s' => \$releaseType, 'archType=s' => \$archType, 'fakeRoot' => \$fakeRoot); if (!$build) { showUsage(); exit(1); }; if ($build eq "tarball" || $build eq "readynas" || $build eq "debian" || $build eq "rpm" || $build eq "macosx" || $build eq "win32") { ## releaseType is an option, but if its not there, we need ## to default it to 'nightly' if (!$releaseType) { $releaseType = "$defaultReleaseType"; } elsif ( $releaseType ne "nightly" && $releaseType ne "release" ) { print "INFO: \$releaseType passed in is incorrect. Please use either \'nightly\' or \'release\'.\n"; } ## make sure that IF its a readynas package, they picked an architecture if ($build eq "readynas" && !$archType) { print "INFO: Required data missing.\n"; showUsage(); exit 1; } ## If they passed in all the options, lets go forward... if ($buildDir && $sourceDir && $destDir) { print "INFO: Required variables passed in. Moving forward.\n"; return $build; ## otherwise, fail and give them the usage guidelines again } else { print "INFO: Required data missing.\n"; showUsage(); exit 1; } ## Now, if they gave us a Build option, but it doesnt make sense... fail } else { print "INFO: Invalid 'build' option passed in... \n"; showUsage(); exit 1; } return $build; } ############################################################################################## ## Here we search through the SqueezeCenter startup script to dynamically grab the version ## ## number for the rest of our script. ## ############################################################################################## sub getVersion { ## We check the startup script for the version # info on this build. For now, we'll call this ## the source of truth for the version information. my @temparray; open(SLIMSERVERPL, "$sourceDir/$squeezeCenterStartupScript") or die "Couldn't open $sourceDir/$squeezeCenterStartupScript to get the version # of this release: $!\n"; while () { if (/our \$VERSION/) { my @temparray = split(/\'/, $_); $version = "$temparray[1]"; } } close(SLIMSERVERPL); if (!$version) { die "Couldn't find the version # in $sourceDir/$squeezeCenterStartupScript... aborting built.\n"; } return $version; } ############################################################################################## ## Begin the main run of the build... based on input from the user, and dynamically ## ## picked up content like the version #, we'll build only the appropriate files requested ## ############################################################################################## sub printOptions { print "INFO: \$buildDir -> $buildDir\n"; print "INFO: \$destDir -> $destDir\n"; print "INFO: \$sourceDir -> $sourceDir\n"; print "INFO: \$version -> $version\n"; print "INFO: \$squeezeCenterStartupScript -> $sourceDir/$squeezeCenterStartupScript\n"; print "INFO: \$releaseType -> $releaseType\n"; if ($archType) { print "INFO: \$archType -> $archType\n"; } } ############################################################################################## ## We need to set up the directories for the build... ## ## ## ############################################################################################## sub setupDirectories { ## First, check if the buildDir exists... we need a clean directory to build our code. if (-d $buildDir) { print "INFO: Source Directory ($buildDir) already existed, erasing it so we can start clean...\n"; rmtree($buildDir); } ## Now, create a new build directory mkpath($buildDir) or die "Problem: couldn't make $buildDir!\n"; print "INFO: Build Directory ($buildDir) was created...\n"; ## Finally, create the destination directory, if it doesnt exist. We don't care if ## it exists already, because someone might want to put this into a more generic ## directory that has other files in it. if (!-d $destDir) { mkpath($destDir) or die "Problem: couldn't make $destDir!\n"; print "INFO: Dest Directory ($destDir) was created...\n"; } else { print "INFO: Dest Directory ($destDir) already existed, not creating...\n"; } } ############################################################################################## ## No matter what we are building, we're going to move it away from the SVN source directory## ## and move it into a building directory. ## ############################################################################################## sub setupBuildTree { # Create a copy of the SVN source directory without additional # directorys or .svn turd files for the build. ## Set up directories to exclude when we start the build... my @sourceExcludeArray = split(/ /, $sourceDirsToExclude); my $sourceExclude = join(' --exclude ', @sourceExcludeArray); ## If this is created, we need to begin it with '--exclude'... but if it doesnt, do not set it.. if ($sourceExclude) { $sourceExclude = "--exclude $sourceExclude"; } print "INFO: Making copy of server source ($sourceDir -> $buildDir)\n"; ## Exclude the .svn directory, and anything else we configured in the beginning of the script. system("rsync -a --quiet $sourceExclude $sourceDir/ $buildDir"); ## Verify that things went OK during the transfer... if (!-d "$buildDir/server") { die "Problem: export of server files failed - $buildDir/server directory!"; } ## Force some permissions, just in case they weren't already set chmod 0755, "$buildDir/$squeezeCenterStartupScript"; chmod 0755, "$buildDir/server/scanner.pl"; # Write out the revision number if ($revision = getRevisionForRepo()) { my $date = `date`; print "INFO: Last Revision number is: $revision\n"; open(REV, ">$buildDir/$revisionTextFile") or die "Problem: Couldn't write out $buildDir/$revisionTextFile : $!\n"; print REV "$revision\n$date"; close(REV); } } ############################################################################################## ## Assuming everythings worked so far, we'll actually start building the packages. ## ############################################################################################## sub doCommandOptions { ## Check if there's a destName passed in ## $destName is used for Tarballs, Windows and Mac OSX packages. Linux packages ## have their own naming schemas. if (!$destName) { $destName = "$defaultDestName-$version-$revision"; } ## If we're building a tarball, do the tarball only... if ($build eq "tarball") { ## If we're building without CPAN libraries, make sure thats in the filename... if ($noCPAN) { ## Use the NO CPAN variables buildTarball($dirsToExcludeForLinuxNoCpanTarball, "$destDir/$destName-noCPAN"); } else { ## Use the CPAN variables buildTarball($dirsToExcludeForLinuxTarball, "$destDir/$destName"); } } elsif ($build eq "readynas") { ## Next, we'll build the debian package... buildReadyNas(); } elsif ($build eq "debian") { ## Build a Debian Package buildDebian(); } elsif ($build eq "rpm") { ## Run the RPM buildRPM(); } elsif ($build eq "macosx") { ## Build the Mac OSX package buildMacOSX("$destName"); } elsif ($build eq "win32") { ## Build the Windows 32bit Installer buildWin32("$destName"); } } ############################################################################################## ## We need to know the revision # of the code, so that we can put it into the source tree ## ############################################################################################## sub getRevisionForRepo { my $revision; open (SVN, "svn info $sourceDir |") or die "Problem: Couldn't run svn info $sourceDir : $!\n"; while () { if (/Last Changed Rev: (\d+)/) { $revision = $1; } } close(SVN); return $revision; } ############################################################################################## ## display the help ############################################################################################## sub showUsage { print "buildme.pl - version ($myVersion) - Help \n"; print "-------------------------------------------\n"; print "This script can build all of our versions \n"; print "of SqueezeCenter... but only one at a time.\n"; print "Each distribution has its own options, \n"; print "listed below... don't try to mix them up! :)\n"; print " \n"; print "--- Building a Linux Tarball\n"; print " --build tarball \n"; print " --buildDir - The directory to do temporary work in\n"; print " --sourceDir - The location of the source code repository\n"; print " that you've checked out from SVN\n"; print " --destDir - The destination you'd like your files \n"; print " --destName - The name of the tarball you would like to\n"; print " (optional) have made. Do not include the .tar.gz/tgz,\n"; print " it will be appended automatically.\n"; print " --noCPAN (optional) - Build a package with no CPAN modules included\n"; print "\n"; print "--- Building an RPM package\n"; print " --build rpm \n"; print " --buildDir - The directory to do temporary work in\n"; print " --sourceDir - The location of the source code repository\n"; print " that you've checked out from SVN\n"; print " --destDir - The destination you'd like your files \n"; print " --releaseType - Whether you're building a 'release' package, \n"; print " (optional) or you're building a nightly-style package\n"; print "\n"; print "--- Building a Debian Package\n"; print " --build debian \n"; print " --buildDir - The directory to do temporary work in\n"; print " --sourceDir - The location of the source code repository\n"; print " that you've checked out from SVN\n"; print " --destDir - The destination you'd like your files \n"; print " --releaseType - Whether you're building a 'release' package, \n"; print " (optional) or you're building a nightly-style package\n"; print "\n"; print "--- Building a ReadyNas Deb. Package\n"; print " --build readynas \n"; print " --buildDir - The directory to do temporary work in\n"; print " --sourceDir - The location of the source code repository\n"; print " that you've checked out from SVN\n"; print " --destDir - The destination you'd like your files \n"; print " --releaseType - Whether you're building a 'release' package, \n"; print " (optional) or you're building a nightly-style package\n"; print " --archType - Pick the right architecture because \n"; print " ONLY the libraries for that ARCH will be included\n"; print "\n"; print "--- Building a Mac OSX Package\n"; print " --build macosx \n"; print " --buildDir - The directory to do temporary work in\n"; print " --sourceDir - The location of the source code repository\n"; print " that you've checked out from SVN\n"; print " --destDir - The destination you'd like your files \n"; print " --destName - The name of the OSX Package Name, do not \n"; print " (optional) include the .dmg\n"; print "\n"; print "--- Building a Windows Package\n"; print " --build win32 \n"; print " --buildDir - The directory to do temporary work in\n"; print " --sourceDir - The location of the source code repository\n"; print " that you've checked out from SVN\n"; print " --destDir - The destination you'd like your files \n"; } ############################################################################################## ## Here we can build a no-cpan tarball, if we either need one, or the user calls for one ## ############################################################################################## sub buildTarball { ## Grab the variables passed to us... if ( ($_[0] && $_[1]) || die("Problem: Not all of the variables were passed to the BuildTarball function...") ) { my $dirsToExclude = $_[0]; my $tarballName = $_[1]; ## We want a pretty name as the output dir, so we rename the server directory real quick ## (the old script would do an rsync here, but an rsync takes too long and is an unnecessary waste of space, even temorarily) my ($name, $path, $suffix); ($name,$path,$suffix) = fileparse($tarballName); system("mv $buildDir/server $buildDir/$name"); ## Set up the exclude path my @excludedDirArray = split(/ /, $dirsToExclude); my $sourceExclude = join(' --exclude ', @excludedDirArray); ## If this is created, we need to begin it with '--exclude'... but if it doesnt, do not set it.. if ($sourceExclude) { $sourceExclude = "--exclude $sourceExclude"; } ## Make the tarball... print "INFO: Building $tarballName.tgz with source from $buildDir/$name ($buildDir/server), excluding [$dirsToExclude]...\n"; system("cd $buildDir; tar $sourceExclude -zcf $tarballName.tgz $name"); ## Remove the link system("mv $buildDir/$name $buildDir/server"); } } ############################################################################################## ## Build an RPM package ## ############################################################################################## sub buildRPM { require File::Which; print "INFO: Building YUM-ified RPM for RHEL/RedHat/Fedora/etc... \n"; # this must be a unix system # make the RPM if appropriate if (!File::Which::which('rpmbuild')) { print "rpmbuild not detected on this system. Not making an RPM"; return; } print "INFO: Building xxx RPM in $buildDir... final file will be in $destDir. \n"; ## We need to setup an RPM build directory to put all of our files in... for my $path (qw(SPECS SOURCES BUILD RPMS SRPMS)) { print "INFO: Making directory for RPM build... ($buildDir/rpm/$path)\n"; mkpath("$buildDir/rpm/$path") || die "PROBLEM: I couldn't create $buildDir/rpm/$path...\n"; } ## Now we need to build a tarball ... print "INFO: Building $buildDir/squeezecenter.tgz for the RPM...\n"; buildTarball($dirsToExcludeForLinuxTarball, "$buildDir/squeezecenter"); ## We already built a tarball, so now lets use it... print "INFO: Moving $buildDir/squeezecenter.tgz to $buildDir/rpm/SOURCES...\n"; system("mv $buildDir/squeezecenter.tgz $buildDir/rpm/SOURCES"); ## Copy the various SPEC< Config, etc files into the right dirs... copy("$buildDir/platforms/redhat/squeezecenter.config", "$buildDir/rpm/SOURCES"); copy("$buildDir/platforms/redhat/squeezecenter.init", "$buildDir/rpm/SOURCES"); copy("$buildDir/platforms/redhat/squeezecenter.logrotate", "$buildDir/rpm/SOURCES"); copy("$buildDir/platforms/redhat/squeezecenter.spec", "$buildDir/rpm/SPECS"); ## Just check, if this is a 'nightly' build, pass on 'trunk' to the rpmbuild command if ($releaseType eq "nightly") { $releaseType = "trunk"; } # Do it my $date = strftime('%Y-%m-%d', localtime()); print `rpmbuild -bb --with $releaseType --define="src_basename squeezecenter" --define="_version $version" --define="_src_date $date" --define="_revision $revision" --define='_topdir $buildDir/rpm' $buildDir/rpm/SPECS/squeezecenter.spec`; ## Just move the file out of the building directory, and put it into the destDir print "INFO: Moving $buildDir/rpm/RPMS/noarch/*.rpm to $destDir\n"; system("mv $buildDir/rpm/RPMS/noarch/*.rpm $destDir"); rmtree("$buildDir/rpm"); } ############################################################################################## ## Build a Debian package ## ############################################################################################## sub buildDebian { print "INFO: Building package for Debian Release... \n"; ## Lets setup the right version/build #... open (READ, "$sourceDir/platforms/debian/changelog") || die "Can't open changelog file to read: $!\n"; open (WRITE, ">$buildDir/platforms/debian/changelog") || die "Can't open changelog file to write: $!\n"; ## Unlike the RPM, with a Debian package there's no simple way to go from a ## 'release' to a 'nightly.' We need to make that choice here, and update ## the changelog file accordingly. if ($releaseType eq "nightly") { $release = "$version~$revision"; } elsif ($releaseType eq "release") { $release = "$version"; } while () { s/_VERSION_/$release/; print WRITE $_; } close WRITE; close READ; ## Ok, we've set everything up... lets run the dpkg-buildpkg command... if ($fakeRoot) { print `cd $buildDir/platforms; fakeroot dpkg-buildpackage -b -d ;`; } else { print `cd $buildDir/platforms; dpkg-buildpackage -b -d ;`; } ## Now that the package is built, lets put it into the destDir system("mv -f $buildDir/*.deb $destDir"); } ############################################################################################## ## Build the ReadyNas Debian Package... this package is very simple. ## ############################################################################################## sub buildReadyNas { print "INFO: Building package for ReadyNas Debian Release... \n"; ## We need to make sure the ARCHTYPE is correct for our build... open (READ, "$sourceDir/platforms/readynas/control") || die "Can't open control file to read: $!\n"; open (WRITE, ">$buildDir/platforms/readynas/control") || die "Can't open control file to write: $!\n"; while () { s/_ARCHTYPE_/$archType/; print WRITE $_; } close WRITE; ## Lets setup the right version/build #... open (READ, "$sourceDir/platforms/readynas/changelog") || die "Can't open changelog file to read: $!\n"; open (WRITE, ">$buildDir/platforms/readynas/changelog") || die "Can't open changelog file to write: $!\n"; ## Unlike the RPM, with a Debian package there's no simple way to go from a ## 'release' to a 'nightly.' We need to make that choice here, and update ## the changelog file accordingly. if ($releaseType eq "nightly") { $release = "$version~$revision"; } elsif ($releaseType eq "release") { $release = "$version"; } while () { s/_VERSION_/$release/; print WRITE $_; } close WRITE; ## dpkg-buildpackage on the ReadyNas units isn't completely up to date, so ## we have to do some funny things to get things right. First, we'll ## get rid of the real 'debian' platforms directory, and move the readynas control ## directory into the 'debian' place. system("mv $buildDir/platforms/debian $buildDir/platforms/debian.orig"); system("ln -s $buildDir/platforms/readynas $buildDir/platforms/debian"); ## Check if a specific architecture was selected ... if ($archType eq "i386") { ## Since i386 was selected, lets make sure to remove sparc libs print "INFO: \$archType was provided as [$archType], removing sparc-linux files...\n"; $dirsToExcludeForReadyNas ="sparc-linux $dirsToExcludeForReadyNas"; } elsif ($archType =~ /sparc/) { ## In this case, we remove all the i386 libs print "INFO: \$archType was provided as [$archType], removing i386 files...\n"; $dirsToExcludeForReadyNas = "i386 $dirsToExcludeForReadyNas";; ## use sparc specific custom-convert.conf to disable transcoding to flac copy("$sourceDir/platforms/readynas/custom-convert.sparc", "$buildDir/platforms/readynas/custom-convert.conf"); } else { ## Fail if no architecture was specified... die("No valid archType was specified. I got [$archType] submitted, but did not recognize it."); } ## First, lets make sure we get rid of the files we don't need for this install my @dirsToExclude = split(/ /, $dirsToExcludeForReadyNas); my $n = 0; while ($dirsToExclude[$n]) { print "INFO: Removing $dirsToExclude[$n] files from buildDir...\n"; system("find $buildDir | grep -i $dirsToExclude[$n] | xargs rm -rf "); $n++; } ## Ok, we've set everything up... lets run the dpkg-buildpkg command... if ($fakeRoot) { print `cd $buildDir/platforms; fakeroot dpkg-buildpackage -b -a$archType -d ;`; } else { print `cd $buildDir/platforms; dpkg-buildpackage -b -a$archType -d ;`; } ## Now that the package is built, lets put it into the addon dir for final packaging print "INFO: Putting .deb file into the appropriate squeezecenter_addon dir for final packaging...\n"; system("mv $buildDir/*.deb $buildDir/platforms/readynas/squeezecenter_addon_$archType/SqueezeCenter/files/"); ## Update the addon package version info ## Lets setup the right version/build #... open (READ, "$buildDir/platforms/readynas/squeezecenter_addon_$archType/SqueezeCenter/addons.tmpl") || die "Can't open addons.tmpl file to read: $!\n"; open (WRITE, ">$buildDir/platforms/readynas/squeezecenter_addon_$archType/SqueezeCenter/addons.conf") || die "Can't open addons.conf file to write: $!\n"; while () { s/VERSION/$release-$archType-readynas/; print WRITE $_; } close WRITE; ## Build the addon now print "INFO: Executing build_addon.sh...\n"; system("cd $buildDir/platforms/readynas/squeezecenter_addon_$archType/; ./build_addon.sh"); ## Move the final addon into place print "INFO: Moving the final addon into [$destDir]\n"; system("mv $buildDir/platforms/readynas/squeezecenter_addon_$archType/*.bin $destDir/"); } ############################################################################################## ## Build the Mac OSX Installer Package ############################################################################################## sub buildMacOSX { ## Grab the variables passed to us... if ( ($_[0] ) || die("Problem: Not all of the variables were passed to the BuildTarball function...") ) { ## Take the filename passed to us and make sure that we build the DMG with ## that name, and that the 'pretty mounted name' also matches my $diskImageFileName = "$_[0].dmg"; my $diskImageName = $_[0]; $diskImageName =~ s/-/ /g; ## If the name squeezecenter is in here, capitalize it... $diskImageFileName =~ s/squeezecenter/SqueezeCenter/; $diskImageName =~ s/squeezecenter/SqueezeCenter/; print "INFO: Building package for Mac OSX (Universal)... \n"; ## First, lets make sure we get rid of the files we don't need for this install my @dirsToExclude = split(/ /, $dirsToExcludeForMacOSX); my $n = 0; while ($dirsToExclude[$n]) { print "INFO: Removing $dirsToExclude[$n] files from buildDir...\n"; system("find $buildDir | grep -i $dirsToExclude[$n] | xargs rm -rf "); $n++; } ## Next, lets build the openUp helper app print "INFO: Building the openUP helper app...\n"; system("cc $buildDir/platforms/osx/openUp.c -o $buildDir/openUp"); ## Now, lets make the Install Files directory print "INFO: Making $buildDir/$diskImageName/Install Files...\n"; mkpath("$buildDir/$diskImageName/Install Files"); ## Copy in the documentation and license files.. print "INFO: Copying documentation & licenses...\n"; copy("$buildDir/server/license.txt", "$buildDir/$diskImageName/License.txt"); copy("$buildDir/platforms/osx/Getting Started.html", "$buildDir/$diskImageName/Getting Started.html"); copy("$buildDir/platforms/osx/Getting Started.fr.html", "$buildDir/$diskImageName/Mise en route.html"); copy("$buildDir/platforms/osx/Getting Started.es.html", "$buildDir/$diskImageName/Guía rápida.html"); copy("$buildDir/platforms/osx/Getting Started.it.html", "$buildDir/$diskImageName/Per iniziare.html"); copy("$buildDir/platforms/osx/Getting Started.nl.html", "$buildDir/$diskImageName/Beginnen.html"); copy("$buildDir/platforms/osx/Getting Started.de.html", "$buildDir/$diskImageName/Erste Schritte.html"); copy("$buildDir/platforms/osx/Getting Started.he.html", "$buildDir/$diskImageName/תחילת השימוש.html"); ## Set some xcodebuild paths... my $xcodeBuildDir = "$buildDir/platforms/osx/Preference Pane/build/Deployment"; my $contentsDir = "$buildDir/$diskImageName/Install Files/SqueezeCenter.prefPane/Contents"; ## Lets build the pref pane and installer... print "INFO: Beginning PreferencePane and Installer build...\n"; system("cd \"$buildDir/platforms/osx/Preference Pane\"; xcodebuild -project \"SqueezeCenter.xcodeproj\" -target \"SqueezeCenter\" -configuration Deployment"); print "INFO: Copying Preference Pane...\n"; system("ditto \"$xcodeBuildDir/SqueezeCenter.prefPane\" \"$buildDir/$diskImageName/Install Files/SqueezeCenter.prefPane\""); print "INFO: Copying MacOSX Installer...\n"; system("ditto \"$xcodeBuildDir/SqueezeCenter Installer.app\" \"$buildDir/$diskImageName/SqueezeCenter Installer.app\" "); # .svn directories have already been removed. system("mv \"$buildDir/server\" \"$contentsDir/\" "); print "INFO: Copying MacOSX Launcher App...\n"; system("ditto \"$xcodeBuildDir/Launcher.app\" \"$contentsDir/server/SqueezeCenter.app\""); ## Lets make sure we don't have any DMG's mounted... if (-d "/Volumes/$diskImageName") { print "INFO: Unmounting previously mounted DMG volume\n"; system("hdiutil detach \"/Volumes/$diskImageName\" "); } ## Lets make sure we don't have any DMG's mounted... if (-d "/Volumes/SqueezeCenter") { print "INFO: Unmounting previously mounted DMG volume\n"; system("hdiutil detach \"/Volumes/SqueezeCenter\" "); } print "INFO: Building MacOSX DMG Image...\n"; system("hdiutil create -fs HFS+ -layout SPUD -volname \"$diskImageName\" -size 100m \"$buildDir/temp-$diskImageFileName\" "); print "INFO: Mounting MacOSX DMG Image...\n"; system("hdiutil mount \"$buildDir/temp-$diskImageFileName\" "); print "INFO: Opening MacOSX DMG Image (template - sc-template-ro.dmg)...\n"; system("hdiutil mount \"$buildDir/platforms/osx/sc-template-ro.dmg\" "); print "INFO: Copying over template image files to new DMG...\n"; system("ditto -rsrc /Volumes/SqueezeCenter/ \"/Volumes/$diskImageName\" "); print "INFO: Opening MacOSX DMG Image (template - sc-template-ro.dmg)...\n"; system("hdiutil unmount \"/Volumes/SqueezeCenter\" "); print "INFO: Copying over MacOSX Files...\n"; system("ditto -rsrc \"$buildDir/$diskImageName\" \"/Volumes/$diskImageName\" "); print "INFO: Making auto open\n"; system("$buildDir/openUp \"/Volumes/$diskImageName\" "); print "INFO: Unmounting MacOSX DMG Image...\n"; system("hdiutil detach \"/Volumes/$diskImageName\" "); print "INFO: Converting MacOSX DMG Image...\n"; system("hdiutil convert -ov -format UDZO \"$buildDir/temp-$diskImageFileName\" -o \"$destDir/$diskImageFileName\" "); print "INFO: Removing temporary DMG file...\n"; unlink("$destDir/temp-$diskImageFileName"); } } ############################################################################################## ## Build the Windows32 Installer ############################################################################################## sub buildWin32 { ## Grab the variables passed to us... if ( ($_[0] ) || die("Problem: Not all of the variables were passed to the BuildTarball function...") ) { ## Take the filename passed to us and make sure that we build the DMG with ## that name, and that the 'pretty mounted name' also matches my $destFileName = $_[0]; my $destPrettyDirName = $_[0]; $destPrettyDirName =~ s/-/ /g; ## If the name squeezecenter is in here, capitalize it... $destPrettyDirName =~ s/squeezecenter/SqueezeCenter/; $destFileName =~ s/squeezecenter/SqueezeCenter/; print "INFO: Building Win32 Installer Package...\n"; ## First, lets make sure we get rid of the files we don't need for this install my @dirsToExclude = split(/ /, $dirsToExcludeForWin32); my $n = 0; while ($dirsToExclude[$n]) { print "INFO: Removing $dirsToExclude[$n] files from buildDir...\n"; system("find $buildDir | grep -i $dirsToExclude[$n] | xargs rm -rf "); $n++; } print "INFO: Creating $buildDir/build for the final packaging...\n"; mkpath("$buildDir/build"); print "INFO: Copying server directory to $buildDir/build...\n"; system("cp -R $buildDir/server \"$buildDir/build/server\" "); print "INFO: Copying various documents to $buildDir/build...\n"; copy("$buildDir/platforms/win32/Getting Started.html", "$buildDir/build"); copy("$buildDir/server/CHANGELOG.html", "$buildDir/build/Release Notes.html"); copy("$buildDir/server/license.txt", "$buildDir/build/License.txt"); copy("$buildDir/platforms/win32/Getting Started.html", "$buildDir/build"); copy("$buildDir/platforms/win32/Getting Started.de.html", "$buildDir/build"); copy("$buildDir/platforms/win32/Getting Started.es.html", "$buildDir/build"); copy("$buildDir/platforms/win32/Getting Started.fr.html", "$buildDir/build"); copy("$buildDir/platforms/win32/Getting Started.he.html", "$buildDir/build"); copy("$buildDir/platforms/win32/Getting Started.it.html", "$buildDir/build"); copy("$buildDir/platforms/win32/Getting Started.nl.html", "$buildDir/build"); copy("$buildDir/docs/squeezebox3/Squeezebox-v3-Owners-Guide.pdf", "$buildDir/build/Squeezebox-Owners-Guide.pdf"); copy("$buildDir/server/License.txt", "$buildDir/build"); copy("$buildDir/server/License.de.txt", "$buildDir/build"); copy("$buildDir/server/License.es.txt", "$buildDir/build"); copy("$buildDir/server/License.fr.txt", "$buildDir/build"); copy("$buildDir/server/License.he.txt", "$buildDir/build"); copy("$buildDir/server/License.it.txt", "$buildDir/build"); copy("$buildDir/server/License.nl.txt", "$buildDir/build"); my $rev = $revision || getRevisionForRepo() || $version; my @versionInfo = ( "CompanyName=SlimDevices - A Logitech Company", "FileVersion=$rev", "LegalCopyright=Copyright 2001-2008 Logitech", "ProductVersion=$version", "ProductName=SqueezeCenter", ); my $programInfo = join(';', @versionInfo, ( "FileDescription=SqueezeCenter Tray Icon", "OriginalFilename=SqueezeTray", "InternalName=SqueezeTray", )); print "INFO: Building perltray executable...\n"; my $libpaths = join(';', qw( . ../../server/CPAN ../../server/CPAN/arch/5.8/MSWin32-x86-multi-thread ../../server/CPAN/arch/5.8/MSWin32-x86-multi-thread/auto ), "$windowsPerlDir/lib"); system("cd $buildDir/platforms/win32; perltray --perl \"$windowsPerlPath\" --force --clean --singleton --lib \"$libpaths\" --info \"$programInfo\" --icon \"res/SqueezeCenter.ico;res/SqueezeCenterOff.ico\" SqueezeTray.pl"); move("$buildDir/platforms/win32/SqueezeTray.exe", "$buildDir/build/SqueezeTray.exe"); copy("$buildDir/platforms/win32/strings.txt", "$buildDir/build/strings.txt"); $programInfo = join(';', @versionInfo, ( "FileDescription=SqueezeCenter Service", "OriginalFilename=SqueezeCenter", "InternalName=SqueezeCenter", )); print "INFO: creating list of perl modules available in our repository...\n"; print "INFO: Building perlsvc executable for server...\n"; $libpaths = join(';', qw( . CPAN CPAN/arch/5.8/MSWin32-x86-multi-thread CPAN/arch/5.8/MSWin32-x86-multi-thread/auto lib ), "$windowsPerlDir/lib"); system("cd $buildDir/server; perlsvc \@../squeezecenter.inc --perl \"$windowsPerlPath\" --clean --lib \"$libpaths\" --info \"$programInfo\" --add IPC::Open2 --force slimserver.pl"); move("$buildDir/server/slimserver.exe", "$buildDir/build/server/squeezecenter.exe"); $programInfo = join(';', @versionInfo, ( "FileDescription=SqueezeCenter Scanner", "OriginalFilename=Scanner", "InternalName=Scanner", )); print "Making scanner executable...\n"; system("cd $buildDir/server; perlapp \@../scanner.inc --perl \"$windowsPerlPath\" --clean --lib \"$libpaths\" --info \"$programInfo\" --force scanner.pl "); move("$buildDir/server/scanner.exe", "$buildDir/build/server/scanner.exe"); $programInfo = join(';', @versionInfo, ( "FileDescription=SqueezeCenter Cleanup", "OriginalFilename=Cleanup", "InternalName=Cleanup", )); print "Making cleanup executable...\n"; system("cd $buildDir/server; perlapp --gui --perl \"$windowsPerlPath\" --lib \"$libpaths\" --info \"$programInfo\" --force cleanup.pl"); move("$buildDir/server/cleanup.exe", "$buildDir/build/server/cleanup.exe"); print "INFO: Making ServiceEnabler...\n"; copy("$buildDir/platforms/win32/installer/ServiceManager.iss", "$buildDir/build"); copy("$buildDir/platforms/win32/installer/StartupModeWizardPage.iss", "$buildDir/build"); copy("$buildDir/platforms/win32/installer/ServiceEnabler.iss", "$buildDir/build") || die ($!); copy("$buildDir/platforms/win32/installer/SocketTest.iss", "$buildDir/build") || die ($!); copy("$buildDir/platforms/win32/installer/strings.iss", "$buildDir/build"); copy("$buildDir/platforms/win32/installer/psvince.dll", "$buildDir/build"); copy("$buildDir/platforms/win32/installer/sockettest.dll", "$buildDir/build"); copy("$buildDir/platforms/win32/installer/ApplicationData.xml", "$buildDir/build"); copy("$buildDir/platforms/win32/InnoSetup/Languages/Danish.isl", "$buildDir/build"); copy("$buildDir/platforms/win32/InnoSetup/Languages/Dutch.isl", "$buildDir/build"); copy("$buildDir/platforms/win32/InnoSetup/Default.isl", "$buildDir/build"); copy("$buildDir/platforms/win32/InnoSetup/Languages/Finnish.isl", "$buildDir/build"); copy("$buildDir/platforms/win32/InnoSetup/Languages/French.isl", "$buildDir/build"); copy("$buildDir/platforms/win32/InnoSetup/Languages/German.isl", "$buildDir/build"); copy("$buildDir/platforms/win32/InnoSetup/Languages/Hebrew.isl", "$buildDir/build"); copy("$buildDir/platforms/win32/InnoSetup/Languages/Italian.isl", "$buildDir/build"); copy("$buildDir/platforms/win32/InnoSetup/Languages/Norwegian.isl", "$buildDir/build"); copy("$buildDir/platforms/win32/InnoSetup/Languages/Spanish.isl", "$buildDir/build"); # Swedish is 3rd party - we keep it in our installer folder copy("$buildDir/platforms/win32/installer/Swedish.isl", "$buildDir/build"); copy("$buildDir/platforms/win32/installer/logitech.bmp", "$buildDir/build"); copy("$buildDir/platforms/win32/installer/squeezebox.bmp", "$buildDir/build"); system("cd $buildDir/build; \"$buildDir/platforms/win32/InnoSetup/ISCC.exe\" \/Q ServiceEnabler.iss "); move("$buildDir/build/Output/ServiceEnabler.exe", "$buildDir/build/"); print "INFO: Removing files we don't want to have in the binary distribution...\n"; rmtree("$buildDir/build/server/CPAN"); rmtree("$buildDir/build/server/lib"); foreach (qw(Buttons Control Display Formats Hardware Menu Music Networking Player Schema Utils Web)) { rmtree("$buildDir/build/server/Slim/$_"); } unlink("$buildDir/build/server/Slim/Plugin/Base.pm"); unlink("$buildDir/build/server/Slim/Plugin/OPMLBased.pm"); unlink("$buildDir/build/server/Slim/bootstrap.pm"); unlink("$buildDir/build/server/Slim/Formats.pm"); unlink("$buildDir/build/server/Slim/Schema.pm"); unlink("$buildDir/build/server/cleanup.pl"); unlink("$buildDir/build/server/slimserver.pl"); unlink("$buildDir/build/server/slimservice.pl"); unlink("$buildDir/build/server/scanner.pl"); print "INFO: Making installer...\n"; # replacing build number in installer script system("sed -e \"s/VersionInfoVersion=0.0.0.0/VersionInfoVersion=$revision/\" \"$buildDir/platforms/win32/installer/SqueezeCenter.iss\" > \"$buildDir/build/SqueezeCenter.iss\""); system("cd $buildDir/build; \"$buildDir/platforms/win32/InnoSetup/ISCC.exe\" \/Q SqueezeCenter.iss "); unlink("$buildDir/build/SqueezeCenter.iss"); unlink("$buildDir/build/ServiceManager.iss"); unlink("$buildDir/build/SocketTest.iss"); unlink("$buildDir/build/StartupModeWizardPage.iss"); unlink("$buildDir/build/ServiceEnabler.iss"); unlink("$buildDir/build/psvince.dll"); unlink("$buildDir/build/sockettest.dll"); unlink("$buildDir/build/ApplicationData.xml"); unlink("$buildDir/build/slim.bmp"); unlink("$buildDir/build/strings.iss"); unlink("$buildDir/build/Danish.isl"); unlink("$buildDir/build/Default.isl"); unlink("$buildDir/build/Dutch.isl"); unlink("$buildDir/build/English.isl"); unlink("$buildDir/build/Finnish.isl"); unlink("$buildDir/build/French.isl"); unlink("$buildDir/build/German.isl"); unlink("$buildDir/build/Hebrew.isl"); unlink("$buildDir/build/Norwegian.isl"); unlink("$buildDir/build/Italian.isl"); unlink("$buildDir/build/Spanish.isl"); unlink("$buildDir/build/Swedish.isl"); # print "INFO: Making Windows Home Server installer... $version.$revision \n"; # replacing build number in installer script # system("sed -e \"s/!!revision!!/$revision/\" \"$buildDir/platforms/win32/installer/SqueezeCenter.wxs\" > \"$buildDir/build/Output/SqueezeCenter.wxs\""); # system("cd $buildDir/build/Output; \"$buildDir/platforms/win32/WiX/candle.exe\" SqueezeCenter.wxs"); # system("cd $buildDir/build/Output; \"$buildDir/platforms/win32/WiX/light.exe\" -sw2024 -sw1076 SqueezeCenter.wixobj"); # # unlink("$buildDir/build/Output/SqueezeCenter.wixobj"); # unlink("$buildDir/build/Output/SqueezeCenter.wixpdb"); # unlink("$buildDir/build/Output/SqueezeCenter.wxs"); print "INFO: Everything is finally ready, renaming directories and building the .exe and zip files...\n"; print "INFO: Moving [$buildDir/build] to [$buildDir/$destPrettyDirName] for packaging\n"; move("$buildDir/build", "$buildDir/$destPrettyDirName"); print "INFO: Moving [$buildDir/$destPrettyDirName/Output/SqueezeSetup.exe] to [$destDir/$destFileName.exe]\n"; move("$buildDir/$destPrettyDirName/Output/SqueezeSetup.exe", "$destDir/$destFileName.exe"); # # rename the Windows Home Server installer # print "INFO: Moving [$buildDir/$destPrettyDirName/Output/SqueezeCenter.msi] to [$destDir/$destFileName-whs.msi]\n"; # move("$buildDir/$destPrettyDirName/Output/SqueezeCenter.msi", "$destDir/$destFileName-whs.msi"); rmtree("$buildDir/$destPrettyDirName/Output"); print "INFO: Building zip [$destDir/$destFileName.ZIP] of [$buildDir/$destPrettyDirName]\n"; unlink("$destDir/$destFileName.ZIP"); system("cd $buildDir; zip -qr $destDir/$destFileName.ZIP \"$destPrettyDirName\" "); } } ##i############################################################################################ ## Ok, start the main() function and begin everything... ## ############################################################################################## main();