Home | History | Annotate | Download | only in Scripts
      1 # Copyright (C) 2005, 2006, 2007, 2010 Apple Inc. All rights reserved.
      2 # Copyright (C) 2009 Google Inc. All rights reserved.
      3 # Copyright (C) 2011 Research In Motion Limited. All rights reserved.
      4 #
      5 # Redistribution and use in source and binary forms, with or without
      6 # modification, are permitted provided that the following conditions
      7 # are met:
      8 #
      9 # 1.  Redistributions of source code must retain the above copyright
     10 #     notice, this list of conditions and the following disclaimer. 
     11 # 2.  Redistributions in binary form must reproduce the above copyright
     12 #     notice, this list of conditions and the following disclaimer in the
     13 #     documentation and/or other materials provided with the distribution. 
     14 # 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     15 #     its contributors may be used to endorse or promote products derived
     16 #     from this software without specific prior written permission. 
     17 #
     18 # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     19 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     20 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     21 # DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     22 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     23 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     24 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     25 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 
     29 # Module to share code to get to WebKit directories.
     30 
     31 use strict;
     32 use warnings;
     33 use Config;
     34 use FindBin;
     35 use File::Basename;
     36 use File::Path;
     37 use File::Spec;
     38 use POSIX;
     39 use VCSUtils;
     40 
     41 BEGIN {
     42    use Exporter   ();
     43    our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
     44    $VERSION     = 1.00;
     45    @ISA         = qw(Exporter);
     46    @EXPORT      = qw(&chdirWebKit &baseProductDir &productDir &XcodeOptions &XcodeOptionString &XcodeOptionStringNoConfig &passedConfiguration &setConfiguration &safariPath &checkFrameworks &currentSVNRevision);
     47    %EXPORT_TAGS = ( );
     48    @EXPORT_OK   = ();
     49 }
     50 
     51 our @EXPORT_OK;
     52 
     53 my $architecture;
     54 my $numberOfCPUs;
     55 my $baseProductDir;
     56 my @baseProductDirOption;
     57 my $configuration;
     58 my $configurationForVisualStudio;
     59 my $configurationProductDir;
     60 my $sourceDir;
     61 my $currentSVNRevision;
     62 my $osXVersion;
     63 my $generateDsym;
     64 my $isQt;
     65 my $qmakebin = "qmake"; # Allow override of the qmake binary from $PATH
     66 my $isSymbian;
     67 my %qtFeatureDefaults;
     68 my $isGtk;
     69 my $isWinCE;
     70 my $isWinCairo;
     71 my $isWx;
     72 my $isEfl;
     73 my @wxArgs;
     74 my $isChromium;
     75 my $isInspectorFrontend;
     76 my $isWK2;
     77 
     78 # Variables for Win32 support
     79 my $vcBuildPath;
     80 my $windowsSourceDir;
     81 my $winVersion;
     82 my $willUseVCExpressWhenBuilding = 0;
     83 
     84 # Defined in VCSUtils.
     85 sub exitStatus($);
     86 
     87 sub determineSourceDir
     88 {
     89     return if $sourceDir;
     90     $sourceDir = $FindBin::Bin;
     91     $sourceDir =~ s|/+$||; # Remove trailing '/' as we would die later
     92 
     93     # walks up path checking each directory to see if it is the main WebKit project dir, 
     94     # defined by containing Sources, WebCore, and WebKit
     95     until ((-d "$sourceDir/Source" && -d "$sourceDir/Source/WebCore" && -d "$sourceDir/Source/WebKit") || (-d "$sourceDir/Internal" && -d "$sourceDir/OpenSource"))
     96     {
     97         if ($sourceDir !~ s|/[^/]+$||) {
     98             die "Could not find top level webkit directory above source directory using FindBin.\n";
     99         }
    100     }
    101 
    102     $sourceDir = "$sourceDir/OpenSource" if -d "$sourceDir/OpenSource";
    103 }
    104 
    105 sub currentPerlPath()
    106 {
    107     my $thisPerl = $^X;
    108     if ($^O ne 'VMS') {
    109         $thisPerl .= $Config{_exe} unless $thisPerl =~ m/$Config{_exe}$/i;
    110     }
    111     return $thisPerl;
    112 }
    113 
    114 sub setQmakeBinaryPath($)
    115 {
    116     ($qmakebin) = @_;
    117 }
    118 
    119 # used for scripts which are stored in a non-standard location
    120 sub setSourceDir($)
    121 {
    122     ($sourceDir) = @_;
    123 }
    124 
    125 sub determineBaseProductDir
    126 {
    127     return if defined $baseProductDir;
    128     determineSourceDir();
    129 
    130     $baseProductDir = $ENV{"WEBKITOUTPUTDIR"};
    131 
    132     if (!defined($baseProductDir) and isAppleMacWebKit()) {
    133         # Silently remove ~/Library/Preferences/xcodebuild.plist which can
    134         # cause build failure. The presence of
    135         # ~/Library/Preferences/xcodebuild.plist can prevent xcodebuild from
    136         # respecting global settings such as a custom build products directory
    137         # (<rdar://problem/5585899>).
    138         my $personalPlistFile = $ENV{HOME} . "/Library/Preferences/xcodebuild.plist";
    139         if (-e $personalPlistFile) {
    140             unlink($personalPlistFile) || die "Could not delete $personalPlistFile: $!";
    141         }
    142 
    143         open PRODUCT, "defaults read com.apple.Xcode PBXApplicationwideBuildSettings 2> " . File::Spec->devnull() . " |" or die;
    144         $baseProductDir = join '', <PRODUCT>;
    145         close PRODUCT;
    146 
    147         $baseProductDir = $1 if $baseProductDir =~ /SYMROOT\s*=\s*\"(.*?)\";/s;
    148         undef $baseProductDir unless $baseProductDir =~ /^\//;
    149 
    150         if (!defined($baseProductDir)) {
    151             open PRODUCT, "defaults read com.apple.Xcode PBXProductDirectory 2> " . File::Spec->devnull() . " |" or die;
    152             $baseProductDir = <PRODUCT>;
    153             close PRODUCT;
    154             if ($baseProductDir) {
    155                 chomp $baseProductDir;
    156                 undef $baseProductDir unless $baseProductDir =~ /^\//;
    157             }
    158         }
    159     } elsif (isSymbian()) {
    160         # Shadow builds are not supported on Symbian
    161         $baseProductDir = $sourceDir;
    162     }
    163 
    164     if (!defined($baseProductDir)) { # Port-spesific checks failed, use default
    165         $baseProductDir = "$sourceDir/WebKitBuild";
    166     }
    167 
    168     if (isGit() && isGitBranchBuild()) {
    169         my $branch = gitBranch();
    170         $baseProductDir = "$baseProductDir/$branch";
    171     }
    172 
    173     if (isAppleMacWebKit()) {
    174         $baseProductDir =~ s|^\Q$(SRCROOT)/..\E$|$sourceDir|;
    175         $baseProductDir =~ s|^\Q$(SRCROOT)/../|$sourceDir/|;
    176         $baseProductDir =~ s|^~/|$ENV{HOME}/|;
    177         die "Can't handle Xcode product directory with a ~ in it.\n" if $baseProductDir =~ /~/;
    178         die "Can't handle Xcode product directory with a variable in it.\n" if $baseProductDir =~ /\$/;
    179         @baseProductDirOption = ("SYMROOT=$baseProductDir", "OBJROOT=$baseProductDir");
    180     }
    181 
    182     if (isCygwin()) {
    183         my $dosBuildPath = `cygpath --windows \"$baseProductDir\"`;
    184         chomp $dosBuildPath;
    185         $ENV{"WEBKITOUTPUTDIR"} = $dosBuildPath;
    186         my $unixBuildPath = `cygpath --unix \"$baseProductDir\"`;
    187         chomp $unixBuildPath;
    188         $baseProductDir = $unixBuildPath;
    189     }
    190 }
    191 
    192 sub setBaseProductDir($)
    193 {
    194     ($baseProductDir) = @_;
    195 }
    196 
    197 sub determineConfiguration
    198 {
    199     return if defined $configuration;
    200     determineBaseProductDir();
    201     if (open CONFIGURATION, "$baseProductDir/Configuration") {
    202         $configuration = <CONFIGURATION>;
    203         close CONFIGURATION;
    204     }
    205     if ($configuration) {
    206         chomp $configuration;
    207         # compatibility for people who have old Configuration files
    208         $configuration = "Release" if $configuration eq "Deployment";
    209         $configuration = "Debug" if $configuration eq "Development";
    210     } else {
    211         $configuration = "Release";
    212     }
    213 }
    214 
    215 sub determineArchitecture
    216 {
    217     return if defined $architecture;
    218     # make sure $architecture is defined for non-apple-mac builds
    219     $architecture = "";
    220     return unless isAppleMacWebKit();
    221 
    222     determineBaseProductDir();
    223     if (open ARCHITECTURE, "$baseProductDir/Architecture") {
    224         $architecture = <ARCHITECTURE>;
    225         close ARCHITECTURE;
    226     }
    227     if ($architecture) {
    228         chomp $architecture;
    229     } else {
    230         if (isTiger() or isLeopard()) {
    231             $architecture = `arch`;
    232         } else {
    233             my $supports64Bit = `sysctl -n hw.optional.x86_64`;
    234             chomp $supports64Bit;
    235             $architecture = $supports64Bit ? 'x86_64' : `arch`;
    236         }
    237         chomp $architecture;
    238     }
    239 }
    240 
    241 sub determineNumberOfCPUs
    242 {
    243     return if defined $numberOfCPUs;
    244     if (isLinux()) {
    245         # First try the nproc utility, if it exists. If we get no
    246         # results fall back to just interpretting /proc directly.
    247         chomp($numberOfCPUs = `nproc 2> /dev/null`);
    248         if ($numberOfCPUs eq "") {
    249             $numberOfCPUs = (grep /processor/, `cat /proc/cpuinfo`);
    250         }
    251     } elsif (isWindows() || isCygwin()) {
    252         if (defined($ENV{NUMBER_OF_PROCESSORS})) {
    253             $numberOfCPUs = $ENV{NUMBER_OF_PROCESSORS};
    254         } else {
    255             # Assumes cygwin
    256             $numberOfCPUs = `ls /proc/registry/HKEY_LOCAL_MACHINE/HARDWARE/DESCRIPTION/System/CentralProcessor | wc -w`;
    257         }
    258     } elsif (isDarwin()) {
    259         $numberOfCPUs = `sysctl -n hw.ncpu`;
    260     }
    261 }
    262 
    263 sub jscPath($)
    264 {
    265     my ($productDir) = @_;
    266     my $jscName = "jsc";
    267     $jscName .= "_debug"  if configurationForVisualStudio() eq "Debug_All";
    268     $jscName .= ".exe" if (isWindows() || isCygwin());
    269     return "$productDir/$jscName" if -e "$productDir/$jscName";
    270     return "$productDir/JavaScriptCore.framework/Resources/$jscName";
    271 }
    272 
    273 sub argumentsForConfiguration()
    274 {
    275     determineConfiguration();
    276     determineArchitecture();
    277 
    278     my @args = ();
    279     push(@args, '--debug') if $configuration eq "Debug";
    280     push(@args, '--release') if $configuration eq "Release";
    281     push(@args, '--32-bit') if $architecture ne "x86_64";
    282     push(@args, '--qt') if isQt();
    283     push(@args, '--symbian') if isSymbian();
    284     push(@args, '--gtk') if isGtk();
    285     push(@args, '--efl') if isEfl();
    286     push(@args, '--wince') if isWinCE();
    287     push(@args, '--wx') if isWx();
    288     push(@args, '--chromium') if isChromium();
    289     push(@args, '--inspector-frontend') if isInspectorFrontend();
    290     return @args;
    291 }
    292 
    293 sub determineConfigurationForVisualStudio
    294 {
    295     return if defined $configurationForVisualStudio;
    296     determineConfiguration();
    297     # FIXME: We should detect when Debug_All or Production has been chosen.
    298     $configurationForVisualStudio = $configuration;
    299 }
    300 
    301 sub usesPerConfigurationBuildDirectory
    302 {
    303     # [Gtk][Efl] We don't have Release/Debug configurations in straight
    304     # autotool builds (non build-webkit). In this case and if
    305     # WEBKITOUTPUTDIR exist, use that as our configuration dir. This will
    306     # allows us to run run-webkit-tests without using build-webkit.
    307     #
    308     # Symbian builds do not have Release/Debug configurations either.
    309     return ($ENV{"WEBKITOUTPUTDIR"} && (isGtk() || isEfl())) || isSymbian() || isAppleWinWebKit();
    310 }
    311 
    312 sub determineConfigurationProductDir
    313 {
    314     return if defined $configurationProductDir;
    315     determineBaseProductDir();
    316     determineConfiguration();
    317     if (isAppleWinWebKit() && !isWx()) {
    318         $configurationProductDir = File::Spec->catdir($baseProductDir, configurationForVisualStudio(), "bin");
    319     } else {
    320         if (usesPerConfigurationBuildDirectory()) {
    321             $configurationProductDir = "$baseProductDir";
    322         } else {
    323             $configurationProductDir = "$baseProductDir/$configuration";
    324         }
    325     }
    326 }
    327 
    328 sub setConfigurationProductDir($)
    329 {
    330     ($configurationProductDir) = @_;
    331 }
    332 
    333 sub determineCurrentSVNRevision
    334 {
    335     return if defined $currentSVNRevision;
    336     determineSourceDir();
    337     $currentSVNRevision = svnRevisionForDirectory($sourceDir);
    338     return $currentSVNRevision;
    339 }
    340 
    341 
    342 sub chdirWebKit
    343 {
    344     determineSourceDir();
    345     chdir $sourceDir or die;
    346 }
    347 
    348 sub baseProductDir
    349 {
    350     determineBaseProductDir();
    351     return $baseProductDir;
    352 }
    353 
    354 sub sourceDir
    355 {
    356     determineSourceDir();
    357     return $sourceDir;
    358 }
    359 
    360 sub productDir
    361 {
    362     determineConfigurationProductDir();
    363     return $configurationProductDir;
    364 }
    365 
    366 sub jscProductDir
    367 {
    368     my $productDir = productDir();
    369     $productDir .= "/JavaScriptCore" if isQt();
    370     $productDir .= "/$configuration" if (isQt() && isWindows());
    371     $productDir .= "/Programs" if (isGtk() || isEfl());
    372 
    373     return $productDir;
    374 }
    375 
    376 sub configuration()
    377 {
    378     determineConfiguration();
    379     return $configuration;
    380 }
    381 
    382 sub configurationForVisualStudio()
    383 {
    384     determineConfigurationForVisualStudio();
    385     return $configurationForVisualStudio;
    386 }
    387 
    388 sub currentSVNRevision
    389 {
    390     determineCurrentSVNRevision();
    391     return $currentSVNRevision;
    392 }
    393 
    394 sub generateDsym()
    395 {
    396     determineGenerateDsym();
    397     return $generateDsym;
    398 }
    399 
    400 sub determineGenerateDsym()
    401 {
    402     return if defined($generateDsym);
    403     $generateDsym = checkForArgumentAndRemoveFromARGV("--dsym");
    404 }
    405 
    406 sub argumentsForXcode()
    407 {
    408     my @args = ();
    409     push @args, "DEBUG_INFORMATION_FORMAT=dwarf-with-dsym" if generateDsym();
    410     return @args;
    411 }
    412 
    413 sub XcodeOptions
    414 {
    415     determineBaseProductDir();
    416     determineConfiguration();
    417     determineArchitecture();
    418     return (@baseProductDirOption, "-configuration", $configuration, "ARCHS=$architecture", argumentsForXcode());
    419 }
    420 
    421 sub XcodeOptionString
    422 {
    423     return join " ", XcodeOptions();
    424 }
    425 
    426 sub XcodeOptionStringNoConfig
    427 {
    428     return join " ", @baseProductDirOption;
    429 }
    430 
    431 sub XcodeCoverageSupportOptions()
    432 {
    433     my @coverageSupportOptions = ();
    434     push @coverageSupportOptions, "GCC_GENERATE_TEST_COVERAGE_FILES=YES";
    435     push @coverageSupportOptions, "GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES";
    436     push @coverageSupportOptions, "EXTRA_LINK= \$(EXTRA_LINK) -ftest-coverage -fprofile-arcs";
    437     push @coverageSupportOptions, "OTHER_CFLAGS= \$(OTHER_CFLAGS) -DCOVERAGE -MD";
    438     push @coverageSupportOptions, "OTHER_LDFLAGS=\$(OTHER_LDFLAGS) -ftest-coverage -fprofile-arcs -lgcov";
    439     return @coverageSupportOptions;
    440 }
    441 
    442 my $passedConfiguration;
    443 my $searchedForPassedConfiguration;
    444 sub determinePassedConfiguration
    445 {
    446     return if $searchedForPassedConfiguration;
    447     $searchedForPassedConfiguration = 1;
    448 
    449     for my $i (0 .. $#ARGV) {
    450         my $opt = $ARGV[$i];
    451         if ($opt =~ /^--debug$/i || $opt =~ /^--devel/i) {
    452             splice(@ARGV, $i, 1);
    453             $passedConfiguration = "Debug";
    454             $passedConfiguration .= "_Cairo_CFLite" if (isWinCairo() && isCygwin());
    455             return;
    456         }
    457         if ($opt =~ /^--release$/i || $opt =~ /^--deploy/i) {
    458             splice(@ARGV, $i, 1);
    459             $passedConfiguration = "Release";
    460             $passedConfiguration .= "_Cairo_CFLite" if (isWinCairo() && isCygwin());
    461             return;
    462         }
    463         if ($opt =~ /^--profil(e|ing)$/i) {
    464             splice(@ARGV, $i, 1);
    465             $passedConfiguration = "Profiling";
    466             $passedConfiguration .= "_Cairo_CFLite" if (isWinCairo() && isCygwin());
    467             return;
    468         }
    469     }
    470     $passedConfiguration = undef;
    471 }
    472 
    473 sub passedConfiguration
    474 {
    475     determinePassedConfiguration();
    476     return $passedConfiguration;
    477 }
    478 
    479 sub setConfiguration
    480 {
    481     setArchitecture();
    482 
    483     if (my $config = shift @_) {
    484         $configuration = $config;
    485         return;
    486     }
    487 
    488     determinePassedConfiguration();
    489     $configuration = $passedConfiguration if $passedConfiguration;
    490 }
    491 
    492 
    493 my $passedArchitecture;
    494 my $searchedForPassedArchitecture;
    495 sub determinePassedArchitecture
    496 {
    497     return if $searchedForPassedArchitecture;
    498     $searchedForPassedArchitecture = 1;
    499 
    500     for my $i (0 .. $#ARGV) {
    501         my $opt = $ARGV[$i];
    502         if ($opt =~ /^--32-bit$/i) {
    503             splice(@ARGV, $i, 1);
    504             if (isAppleMacWebKit()) {
    505                 $passedArchitecture = `arch`;
    506                 chomp $passedArchitecture;
    507             }
    508             return;
    509         }
    510     }
    511     $passedArchitecture = undef;
    512 }
    513 
    514 sub passedArchitecture
    515 {
    516     determinePassedArchitecture();
    517     return $passedArchitecture;
    518 }
    519 
    520 sub architecture()
    521 {
    522     determineArchitecture();
    523     return $architecture;
    524 }
    525 
    526 sub numberOfCPUs()
    527 {
    528     determineNumberOfCPUs();
    529     return $numberOfCPUs;
    530 }
    531 
    532 sub setArchitecture
    533 {
    534     if (my $arch = shift @_) {
    535         $architecture = $arch;
    536         return;
    537     }
    538 
    539     determinePassedArchitecture();
    540     $architecture = $passedArchitecture if $passedArchitecture;
    541 }
    542 
    543 
    544 sub safariPathFromSafariBundle
    545 {
    546     my ($safariBundle) = @_;
    547 
    548     return "$safariBundle/Contents/MacOS/Safari" if isAppleMacWebKit();
    549     return $safariBundle if isAppleWinWebKit();
    550 }
    551 
    552 sub installedSafariPath
    553 {
    554     my $safariBundle;
    555 
    556     if (isAppleMacWebKit()) {
    557         $safariBundle = "/Applications/Safari.app";
    558     } elsif (isAppleWinWebKit()) {
    559         $safariBundle = `"$configurationProductDir/FindSafari.exe"`;
    560         $safariBundle =~ s/[\r\n]+$//;
    561         $safariBundle = `cygpath -u '$safariBundle'` if isCygwin();
    562         $safariBundle =~ s/[\r\n]+$//;
    563         $safariBundle .= "Safari.exe";
    564     }
    565 
    566     return safariPathFromSafariBundle($safariBundle);
    567 }
    568 
    569 # Locate Safari.
    570 sub safariPath
    571 {
    572     # Use WEBKIT_SAFARI environment variable if present.
    573     my $safariBundle = $ENV{WEBKIT_SAFARI};
    574     if (!$safariBundle) {
    575         determineConfigurationProductDir();
    576         # Use Safari.app in product directory if present (good for Safari development team).
    577         if (isAppleMacWebKit() && -d "$configurationProductDir/Safari.app") {
    578             $safariBundle = "$configurationProductDir/Safari.app";
    579         } elsif (isAppleWinWebKit()) {
    580             my $path = "$configurationProductDir/Safari.exe";
    581             my $debugPath = "$configurationProductDir/Safari_debug.exe";
    582 
    583             if (configurationForVisualStudio() eq "Debug_All" && -x $debugPath) {
    584                 $safariBundle = $debugPath;
    585             } elsif (-x $path) {
    586                 $safariBundle = $path;
    587             }
    588         }
    589         if (!$safariBundle) {
    590             return installedSafariPath();
    591         }
    592     }
    593     my $safariPath = safariPathFromSafariBundle($safariBundle);
    594     die "Can't find executable at $safariPath.\n" if isAppleMacWebKit() && !-x $safariPath;
    595     return $safariPath;
    596 }
    597 
    598 sub builtDylibPathForName
    599 {
    600     my $libraryName = shift;
    601     determineConfigurationProductDir();
    602     if (isChromium()) {
    603         return "$configurationProductDir/$libraryName";
    604     }
    605     if (isQt()) {
    606         $libraryName = "QtWebKit";
    607         if (isDarwin() and -d "$configurationProductDir/lib/$libraryName.framework") {
    608             return "$configurationProductDir/lib/$libraryName.framework/$libraryName";
    609         } elsif (isDarwin() and -d "$configurationProductDir/lib") {
    610             return "$configurationProductDir/lib/lib$libraryName.dylib";
    611         } elsif (isWindows()) {
    612             if (configuration() eq "Debug") {
    613                 # On Windows, there is a "d" suffix to the library name. See <http://trac.webkit.org/changeset/53924/>.
    614                 $libraryName .= "d";
    615             }
    616 
    617             my $mkspec = `$qmakebin -query QMAKE_MKSPECS`;
    618             $mkspec =~ s/[\n|\r]$//g;
    619             my $qtMajorVersion = retrieveQMakespecVar("$mkspec/qconfig.pri", "QT_MAJOR_VERSION");
    620             if (not $qtMajorVersion) {
    621                 $qtMajorVersion = "";
    622             }
    623             return "$configurationProductDir/lib/$libraryName$qtMajorVersion.dll";
    624         } else {
    625             return "$configurationProductDir/lib/lib$libraryName.so";
    626         }
    627     }
    628     if (isWx()) {
    629         return "$configurationProductDir/libwxwebkit.dylib";
    630     }
    631     if (isGtk()) {
    632         my $libraryDir = "$configurationProductDir/.libs/";
    633         my $extension = isDarwin() ? "dylib" : "so";
    634         if (-e $libraryDir . "libwebkitgtk-3.0.$extension") {
    635             return $libraryDir . "libwebkitgtk-3.0.$extension";
    636         }
    637         return $libraryDir . "libwebkitgtk-1.0.$extension";
    638     }
    639     if (isEfl()) {
    640         return "$configurationProductDir/$libraryName/../WebKit/libewebkit.so";
    641     }
    642     if (isWinCE()) {
    643         return "$configurationProductDir/$libraryName";
    644     }
    645     if (isAppleMacWebKit()) {
    646         return "$configurationProductDir/$libraryName.framework/Versions/A/$libraryName";
    647     }
    648     if (isAppleWinWebKit()) {
    649         if ($libraryName eq "JavaScriptCore") {
    650             return "$baseProductDir/lib/$libraryName.lib";
    651         } else {
    652             return "$baseProductDir/$libraryName.intermediate/$configuration/$libraryName.intermediate/$libraryName.lib";
    653         }
    654     }
    655 
    656     die "Unsupported platform, can't determine built library locations.\nTry `build-webkit --help` for more information.\n";
    657 }
    658 
    659 # Check to see that all the frameworks are built.
    660 sub checkFrameworks # FIXME: This is a poor name since only the Mac calls built WebCore a Framework.
    661 {
    662     return if isCygwin() || isWindows();
    663     my @frameworks = ("JavaScriptCore", "WebCore");
    664     push(@frameworks, "WebKit") if isAppleMacWebKit(); # FIXME: This seems wrong, all ports should have a WebKit these days.
    665     for my $framework (@frameworks) {
    666         my $path = builtDylibPathForName($framework);
    667         die "Can't find built framework at \"$path\".\n" unless -e $path;
    668     }
    669 }
    670 
    671 sub isInspectorFrontend()
    672 {
    673     determineIsInspectorFrontend();
    674     return $isInspectorFrontend;
    675 }
    676 
    677 sub determineIsInspectorFrontend()
    678 {
    679     return if defined($isInspectorFrontend);
    680     $isInspectorFrontend = checkForArgumentAndRemoveFromARGV("--inspector-frontend");
    681 }
    682 
    683 sub isQt()
    684 {
    685     determineIsQt();
    686     return $isQt;
    687 }
    688 
    689 sub isSymbian()
    690 {
    691     determineIsSymbian();
    692     return $isSymbian;
    693 }
    694 
    695 sub qtFeatureDefaults()
    696 {
    697     determineQtFeatureDefaults();
    698     return %qtFeatureDefaults;
    699 }
    700 
    701 sub commandExists($)
    702 {
    703     my $command = shift;
    704     my $devnull = File::Spec->devnull();
    705     return `$command --version 2> $devnull`;
    706 }
    707 
    708 sub determineQtFeatureDefaults()
    709 {
    710     return if %qtFeatureDefaults;
    711     die "ERROR: qmake missing but required to build WebKit.\n" if not commandExists($qmakebin);
    712     my $originalCwd = getcwd();
    713     chdir File::Spec->catfile(sourceDir(), "Source", "WebCore");
    714     my $defaults = `$qmakebin CONFIG+=compute_defaults 2>&1`;
    715     chdir $originalCwd;
    716 
    717     while ($defaults =~ m/(\S+?)=(\S+?)/gi) {
    718         $qtFeatureDefaults{$1}=$2;
    719     }
    720 }
    721 
    722 sub checkForArgumentAndRemoveFromARGV
    723 {
    724     my $argToCheck = shift;
    725     return checkForArgumentAndRemoveFromArrayRef($argToCheck, \@ARGV);
    726 }
    727 
    728 sub checkForArgumentAndRemoveFromArrayRef
    729 {
    730     my ($argToCheck, $arrayRef) = @_;
    731     my @indicesToRemove;
    732     foreach my $index (0 .. $#$arrayRef) {
    733         my $opt = $$arrayRef[$index];
    734         if ($opt =~ /^$argToCheck$/i ) {
    735             push(@indicesToRemove, $index);
    736         }
    737     }
    738     foreach my $index (@indicesToRemove) {
    739         splice(@$arrayRef, $index, 1);
    740     }
    741     return $#indicesToRemove > -1;
    742 }
    743 
    744 sub isWK2()
    745 {
    746     if (defined($isWK2)) {
    747         return $isWK2;
    748     }
    749     if (checkForArgumentAndRemoveFromARGV("-2")) {
    750         $isWK2 = 1;
    751     } else {
    752         $isWK2 = 0;
    753     }
    754     return $isWK2;
    755 }
    756 
    757 sub determineIsQt()
    758 {
    759     return if defined($isQt);
    760 
    761     # Allow override in case QTDIR is not set.
    762     if (checkForArgumentAndRemoveFromARGV("--qt")) {
    763         $isQt = 1;
    764         return;
    765     }
    766 
    767     # The presence of QTDIR only means Qt if --gtk or --wx or --efl are not on the command-line
    768     if (isGtk() || isWx() || isEfl()) {
    769         $isQt = 0;
    770         return;
    771     }
    772     
    773     $isQt = defined($ENV{'QTDIR'});
    774 }
    775 
    776 sub determineIsSymbian()
    777 {
    778     return if defined($isSymbian);
    779 
    780     if (checkForArgumentAndRemoveFromARGV("--symbian")) {
    781         $isSymbian = 1;
    782         return;
    783     }
    784 }
    785 
    786 sub determineIsEfl()
    787 {
    788     return if defined($isEfl);
    789     $isEfl = checkForArgumentAndRemoveFromARGV("--efl");
    790 }
    791 
    792 sub isEfl()
    793 {
    794     determineIsEfl();
    795     return $isEfl;
    796 }
    797 
    798 sub isGtk()
    799 {
    800     determineIsGtk();
    801     return $isGtk;
    802 }
    803 
    804 sub determineIsGtk()
    805 {
    806     return if defined($isGtk);
    807     $isGtk = checkForArgumentAndRemoveFromARGV("--gtk");
    808 }
    809 
    810 sub isWinCE()
    811 {
    812     determineIsWinCE();
    813     return $isWinCE;
    814 }
    815 
    816 sub determineIsWinCE()
    817 {
    818     return if defined($isWinCE);
    819     $isWinCE = checkForArgumentAndRemoveFromARGV("--wince");
    820 }
    821 
    822 sub isWx()
    823 {
    824     determineIsWx();
    825     return $isWx;
    826 }
    827 
    828 sub determineIsWx()
    829 {
    830     return if defined($isWx);
    831     $isWx = checkForArgumentAndRemoveFromARGV("--wx");
    832 }
    833 
    834 sub getWxArgs()
    835 {
    836     if (!@wxArgs) {
    837         @wxArgs = ("");
    838         my $rawWxArgs = "";
    839         foreach my $opt (@ARGV) {
    840             if ($opt =~ /^--wx-args/i ) {
    841                 @ARGV = grep(!/^--wx-args/i, @ARGV);
    842                 $rawWxArgs = $opt;
    843                 $rawWxArgs =~ s/--wx-args=//i;
    844             }
    845         }
    846         @wxArgs = split(/,/, $rawWxArgs);
    847     }
    848     return @wxArgs;
    849 }
    850 
    851 # Determine if this is debian, ubuntu, linspire, or something similar.
    852 sub isDebianBased()
    853 {
    854     return -e "/etc/debian_version";
    855 }
    856 
    857 sub isFedoraBased()
    858 {
    859     return -e "/etc/fedora-release";
    860 }
    861 
    862 sub isChromium()
    863 {
    864     determineIsChromium();
    865     return $isChromium;
    866 }
    867 
    868 sub determineIsChromium()
    869 {
    870     return if defined($isChromium);
    871     $isChromium = checkForArgumentAndRemoveFromARGV("--chromium");
    872 }
    873 
    874 sub isWinCairo()
    875 {
    876     determineIsWinCairo();
    877     return $isWinCairo;
    878 }
    879 
    880 sub determineIsWinCairo()
    881 {
    882     return if defined($isWinCairo);
    883     $isWinCairo = checkForArgumentAndRemoveFromARGV("--wincairo");
    884 }
    885 
    886 sub isCygwin()
    887 {
    888     return ($^O eq "cygwin") || 0;
    889 }
    890 
    891 sub determineWinVersion()
    892 {
    893     return if $winVersion;
    894 
    895     if (!isCygwin()) {
    896         $winVersion = -1;
    897         return;
    898     }
    899 
    900     my $versionString = `uname -s`;
    901     $versionString =~ /(\d\.\d)/;
    902     $winVersion = $1;
    903 }
    904 
    905 sub winVersion()
    906 {
    907     determineWinVersion();
    908     return $winVersion;
    909 }
    910 
    911 sub isWindows7()
    912 {
    913     return winVersion() eq "6.1";
    914 }
    915 
    916 sub isWindowsVista()
    917 {
    918     return winVersion() eq "6.0";
    919 }
    920 
    921 sub isWindowsXP()
    922 {
    923     return winVersion() eq "5.1";
    924 }
    925 
    926 sub isDarwin()
    927 {
    928     return ($^O eq "darwin") || 0;
    929 }
    930 
    931 sub isWindows()
    932 {
    933     return ($^O eq "MSWin32") || 0;
    934 }
    935 
    936 sub isMsys()
    937 {
    938     return ($^O eq "msys") || 0;
    939 }
    940 
    941 sub isLinux()
    942 {
    943     return ($^O eq "linux") || 0;
    944 }
    945 
    946 sub isAppleWebKit()
    947 {
    948     return !(isQt() or isGtk() or isWx() or isChromium() or isEfl() or isWinCE());
    949 }
    950 
    951 sub isAppleMacWebKit()
    952 {
    953     return isAppleWebKit() && isDarwin();
    954 }
    955 
    956 sub isAppleWinWebKit()
    957 {
    958     return isAppleWebKit() && (isCygwin() || isWindows());
    959 }
    960 
    961 sub isPerianInstalled()
    962 {
    963     if (!isAppleWebKit()) {
    964         return 0;
    965     }
    966 
    967     if (-d "/Library/QuickTime/Perian.component") {
    968         return 1;
    969     }
    970 
    971     if (-d "$ENV{HOME}/Library/QuickTime/Perian.component") {
    972         return 1;
    973     }
    974 
    975     return 0;
    976 }
    977 
    978 sub determineOSXVersion()
    979 {
    980     return if $osXVersion;
    981 
    982     if (!isDarwin()) {
    983         $osXVersion = -1;
    984         return;
    985     }
    986 
    987     my $version = `sw_vers -productVersion`;
    988     my @splitVersion = split(/\./, $version);
    989     @splitVersion >= 2 or die "Invalid version $version";
    990     $osXVersion = {
    991             "major" => $splitVersion[0],
    992             "minor" => $splitVersion[1],
    993             "subminor" => (defined($splitVersion[2]) ? $splitVersion[2] : 0),
    994     };
    995 }
    996 
    997 sub osXVersion()
    998 {
    999     determineOSXVersion();
   1000     return $osXVersion;
   1001 }
   1002 
   1003 sub isTiger()
   1004 {
   1005     return isDarwin() && osXVersion()->{"minor"} == 4;
   1006 }
   1007 
   1008 sub isLeopard()
   1009 {
   1010     return isDarwin() && osXVersion()->{"minor"} == 5;
   1011 }
   1012 
   1013 sub isSnowLeopard()
   1014 {
   1015     return isDarwin() && osXVersion()->{"minor"} == 6;
   1016 }
   1017 
   1018 sub isWindowsNT()
   1019 {
   1020     return $ENV{'OS'} eq 'Windows_NT';
   1021 }
   1022 
   1023 sub relativeScriptsDir()
   1024 {
   1025     my $scriptDir = File::Spec->catpath("", File::Spec->abs2rel($FindBin::Bin, getcwd()), "");
   1026     if ($scriptDir eq "") {
   1027         $scriptDir = ".";
   1028     }
   1029     return $scriptDir;
   1030 }
   1031 
   1032 sub launcherPath()
   1033 {
   1034     my $relativeScriptsPath = relativeScriptsDir();
   1035     if (isGtk() || isQt() || isWx() || isEfl() || isWinCE()) {
   1036         return "$relativeScriptsPath/run-launcher";
   1037     } elsif (isAppleWebKit()) {
   1038         return "$relativeScriptsPath/run-safari";
   1039     }
   1040 }
   1041 
   1042 sub launcherName()
   1043 {
   1044     if (isGtk()) {
   1045         return "GtkLauncher";
   1046     } elsif (isQt()) {
   1047         return "QtTestBrowser";
   1048     } elsif (isWx()) {
   1049         return "wxBrowser";
   1050     } elsif (isAppleWebKit()) {
   1051         return "Safari";
   1052     } elsif (isEfl()) {
   1053         return "EWebLauncher";
   1054     } elsif (isWinCE()) {
   1055         return "WinCELauncher";
   1056     }
   1057 }
   1058 
   1059 sub checkRequiredSystemConfig
   1060 {
   1061     if (isDarwin()) {
   1062         chomp(my $productVersion = `sw_vers -productVersion`);
   1063         if (eval "v$productVersion" lt v10.4) {
   1064             print "*************************************************************\n";
   1065             print "Mac OS X Version 10.4.0 or later is required to build WebKit.\n";
   1066             print "You have " . $productVersion . ", thus the build will most likely fail.\n";
   1067             print "*************************************************************\n";
   1068         }
   1069         my $xcodebuildVersionOutput = `xcodebuild -version`;
   1070         my $devToolsCoreVersion = ($xcodebuildVersionOutput =~ /DevToolsCore-(\d+)/) ? $1 : undef;
   1071         my $xcodeVersion = ($xcodebuildVersionOutput =~ /Xcode ([0-9](\.[0-9]+)*)/) ? $1 : undef;
   1072         if (!$devToolsCoreVersion && !$xcodeVersion
   1073             || $devToolsCoreVersion && $devToolsCoreVersion < 747
   1074             || $xcodeVersion && eval "v$xcodeVersion" lt v2.3) {
   1075             print "*************************************************************\n";
   1076             print "Xcode Version 2.3 or later is required to build WebKit.\n";
   1077             print "You have an earlier version of Xcode, thus the build will\n";
   1078             print "most likely fail.  The latest Xcode is available from the web:\n";
   1079             print "http://developer.apple.com/tools/xcode\n";
   1080             print "*************************************************************\n";
   1081         }
   1082     } elsif (isGtk() or isQt() or isWx() or isEfl()) {
   1083         my @cmds = qw(flex bison gperf);
   1084         my @missing = ();
   1085         foreach my $cmd (@cmds) {
   1086             push @missing, $cmd if not commandExists($cmd);
   1087         }
   1088 
   1089         if (@missing) {
   1090             my $list = join ", ", @missing;
   1091             die "ERROR: $list missing but required to build WebKit.\n";
   1092         }
   1093     }
   1094     # Win32 and other platforms may want to check for minimum config
   1095 }
   1096 
   1097 sub determineWindowsSourceDir()
   1098 {
   1099     return if $windowsSourceDir;
   1100     $windowsSourceDir = sourceDir();
   1101     chomp($windowsSourceDir = `cygpath -w '$windowsSourceDir'`) if isCygwin();
   1102 }
   1103 
   1104 sub windowsSourceDir()
   1105 {
   1106     determineWindowsSourceDir();
   1107     return $windowsSourceDir;
   1108 }
   1109 
   1110 sub windowsLibrariesDir()
   1111 {
   1112     return windowsSourceDir() . "\\WebKitLibraries\\win";
   1113 }
   1114 
   1115 sub windowsOutputDir()
   1116 {
   1117     return windowsSourceDir() . "\\WebKitBuild";
   1118 }
   1119 
   1120 sub setupAppleWinEnv()
   1121 {
   1122     return unless isAppleWinWebKit();
   1123 
   1124     if (isWindowsNT()) {
   1125         my $restartNeeded = 0;
   1126         my %variablesToSet = ();
   1127 
   1128         # Setting the environment variable 'CYGWIN' to 'tty' makes cygwin enable extra support (i.e., termios)
   1129         # for UNIX-like ttys in the Windows console
   1130         $variablesToSet{CYGWIN} = "tty" unless $ENV{CYGWIN};
   1131         
   1132         # Those environment variables must be set to be able to build inside Visual Studio.
   1133         $variablesToSet{WEBKITLIBRARIESDIR} = windowsLibrariesDir() unless $ENV{WEBKITLIBRARIESDIR};
   1134         $variablesToSet{WEBKITOUTPUTDIR} = windowsOutputDir() unless $ENV{WEBKITOUTPUTDIR};
   1135 
   1136         foreach my $variable (keys %variablesToSet) {
   1137             print "Setting the Environment Variable '" . $variable . "' to '" . $variablesToSet{$variable} . "'\n\n";
   1138             system qw(regtool -s set), '\\HKEY_CURRENT_USER\\Environment\\' . $variable, $variablesToSet{$variable};
   1139             $restartNeeded ||= $variable eq "WEBKITLIBRARIESDIR" || $variable eq "WEBKITOUTPUTDIR";
   1140         }
   1141 
   1142         if ($restartNeeded) {
   1143             print "Please restart your computer before attempting to build inside Visual Studio.\n\n";
   1144         }
   1145     } else {
   1146         if (!$ENV{'WEBKITLIBRARIESDIR'}) {
   1147             print "Warning: You must set the 'WebKitLibrariesDir' environment variable\n";
   1148             print "         to be able build WebKit from within Visual Studio.\n";
   1149             print "         Make sure that 'WebKitLibrariesDir' points to the\n";
   1150             print "         'WebKitLibraries/win' directory, not the 'WebKitLibraries/' directory.\n\n";
   1151         }
   1152         if (!$ENV{'WEBKITOUTPUTDIR'}) {
   1153             print "Warning: You must set the 'WebKitOutputDir' environment variable\n";
   1154             print "         to be able build WebKit from within Visual Studio.\n\n";
   1155         }
   1156     }
   1157 }
   1158 
   1159 sub setupCygwinEnv()
   1160 {
   1161     return if !isCygwin() && !isWindows();
   1162     return if $vcBuildPath;
   1163 
   1164     my $vsInstallDir;
   1165     my $programFilesPath = $ENV{'PROGRAMFILES(X86)'} || $ENV{'PROGRAMFILES'} || "C:\\Program Files";
   1166     if ($ENV{'VSINSTALLDIR'}) {
   1167         $vsInstallDir = $ENV{'VSINSTALLDIR'};
   1168     } else {
   1169         $vsInstallDir = File::Spec->catdir($programFilesPath, "Microsoft Visual Studio 8");
   1170     }
   1171     chomp($vsInstallDir = `cygpath "$vsInstallDir"`) if isCygwin();
   1172     $vcBuildPath = File::Spec->catfile($vsInstallDir, qw(Common7 IDE devenv.com));
   1173     if (-e $vcBuildPath) {
   1174         # Visual Studio is installed; we can use pdevenv to build.
   1175         # FIXME: Make pdevenv work with non-Cygwin Perl.
   1176         $vcBuildPath = File::Spec->catfile(sourceDir(), qw(Tools Scripts pdevenv)) if isCygwin();
   1177     } else {
   1178         # Visual Studio not found, try VC++ Express
   1179         $vcBuildPath = File::Spec->catfile($vsInstallDir, qw(Common7 IDE VCExpress.exe));
   1180         if (! -e $vcBuildPath) {
   1181             print "*************************************************************\n";
   1182             print "Cannot find '$vcBuildPath'\n";
   1183             print "Please execute the file 'vcvars32.bat' from\n";
   1184             print "'$programFilesPath\\Microsoft Visual Studio 8\\VC\\bin\\'\n";
   1185             print "to setup the necessary environment variables.\n";
   1186             print "*************************************************************\n";
   1187             die;
   1188         }
   1189         $willUseVCExpressWhenBuilding = 1;
   1190     }
   1191 
   1192     my $qtSDKPath = File::Spec->catdir($programFilesPath, "QuickTime SDK");
   1193     if (0 && ! -e $qtSDKPath) {
   1194         print "*************************************************************\n";
   1195         print "Cannot find '$qtSDKPath'\n";
   1196         print "Please download the QuickTime SDK for Windows from\n";
   1197         print "http://developer.apple.com/quicktime/download/\n";
   1198         print "*************************************************************\n";
   1199         die;
   1200     }
   1201     
   1202     unless ($ENV{WEBKITLIBRARIESDIR}) {
   1203         $ENV{'WEBKITLIBRARIESDIR'} = File::Spec->catdir($sourceDir, "WebKitLibraries", "win");
   1204         chomp($ENV{WEBKITLIBRARIESDIR} = `cygpath -wa $ENV{WEBKITLIBRARIESDIR}`) if isCygwin();
   1205     }
   1206 
   1207     print "Building results into: ", baseProductDir(), "\n";
   1208     print "WEBKITOUTPUTDIR is set to: ", $ENV{"WEBKITOUTPUTDIR"}, "\n";
   1209     print "WEBKITLIBRARIESDIR is set to: ", $ENV{"WEBKITLIBRARIESDIR"}, "\n";
   1210 }
   1211 
   1212 sub dieIfWindowsPlatformSDKNotInstalled
   1213 {
   1214     my $registry32Path = "/proc/registry/";
   1215     my $registry64Path = "/proc/registry64/";
   1216     my $windowsPlatformSDKRegistryEntry = "HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/MicrosoftSDK/InstalledSDKs/D2FF9F89-8AA2-4373-8A31-C838BF4DBBE1";
   1217 
   1218     # FIXME: It would be better to detect whether we are using 32- or 64-bit Windows
   1219     # and only check the appropriate entry. But for now we just blindly check both.
   1220     return if (-e $registry32Path . $windowsPlatformSDKRegistryEntry) || (-e $registry64Path . $windowsPlatformSDKRegistryEntry);
   1221 
   1222     print "*************************************************************\n";
   1223     print "Cannot find registry entry '$windowsPlatformSDKRegistryEntry'.\n";
   1224     print "Please download and install the Microsoft Windows Server 2003 R2\n";
   1225     print "Platform SDK from <http://www.microsoft.com/downloads/details.aspx?\n";
   1226     print "familyid=0baf2b35-c656-4969-ace8-e4c0c0716adb&displaylang=en>.\n\n";
   1227     print "Then follow step 2 in the Windows section of the \"Installing Developer\n";
   1228     print "Tools\" instructions at <http://www.webkit.org/building/tools.html>.\n";
   1229     print "*************************************************************\n";
   1230     die;
   1231 }
   1232 
   1233 sub copyInspectorFrontendFiles
   1234 {
   1235     my $productDir = productDir();
   1236     my $sourceInspectorPath = sourceDir() . "/Source/WebCore/inspector/front-end/";
   1237     my $inspectorResourcesDirPath = $ENV{"WEBKITINSPECTORRESOURCESDIR"};
   1238 
   1239     if (!defined($inspectorResourcesDirPath)) {
   1240         $inspectorResourcesDirPath = "";
   1241     }
   1242 
   1243     if (isAppleMacWebKit()) {
   1244         $inspectorResourcesDirPath = $productDir . "/WebCore.framework/Resources/inspector";
   1245     } elsif (isAppleWinWebKit()) {
   1246         $inspectorResourcesDirPath = $productDir . "/WebKit.resources/inspector";
   1247     } elsif (isQt() || isGtk()) {
   1248         my $prefix = $ENV{"WebKitInstallationPrefix"};
   1249         $inspectorResourcesDirPath = (defined($prefix) ? $prefix : "/usr/share") . "/webkit-1.0/webinspector";
   1250     } elsif (isEfl()) {
   1251         my $prefix = $ENV{"WebKitInstallationPrefix"};
   1252         $inspectorResourcesDirPath = (defined($prefix) ? $prefix : "/usr/share") . "/ewebkit/webinspector";
   1253     }
   1254 
   1255     if (! -d $inspectorResourcesDirPath) {
   1256         print "*************************************************************\n";
   1257         print "Cannot find '$inspectorResourcesDirPath'.\n" if (defined($inspectorResourcesDirPath));
   1258         print "Make sure that you have built WebKit first.\n" if (! -d $productDir || defined($inspectorResourcesDirPath));
   1259         print "Optionally, set the environment variable 'WebKitInspectorResourcesDir'\n";
   1260         print "to point to the directory that contains the WebKit Inspector front-end\n";
   1261         print "files for the built WebCore framework.\n";
   1262         print "*************************************************************\n";
   1263         die;
   1264     }
   1265     return system "rsync", "-aut", "--exclude=/.DS_Store", "--exclude=*.re2js", "--exclude=.svn/", !isQt() ? "--exclude=/WebKit.qrc" : "", $sourceInspectorPath, $inspectorResourcesDirPath;
   1266 }
   1267 
   1268 sub buildXCodeProject($$@)
   1269 {
   1270     my ($project, $clean, @extraOptions) = @_;
   1271 
   1272     if ($clean) {
   1273         push(@extraOptions, "-alltargets");
   1274         push(@extraOptions, "clean");
   1275     }
   1276 
   1277     return system "xcodebuild", "-project", "$project.xcodeproj", @extraOptions;
   1278 }
   1279 
   1280 sub usingVisualStudioExpress()
   1281 {
   1282     setupCygwinEnv();
   1283     return $willUseVCExpressWhenBuilding;
   1284 }
   1285 
   1286 sub buildVisualStudioProject
   1287 {
   1288     my ($project, $clean) = @_;
   1289     setupCygwinEnv();
   1290 
   1291     my $config = configurationForVisualStudio();
   1292 
   1293     dieIfWindowsPlatformSDKNotInstalled() if $willUseVCExpressWhenBuilding;
   1294 
   1295     chomp($project = `cygpath -w "$project"`) if isCygwin();
   1296     
   1297     my $action = "/build";
   1298     if ($clean) {
   1299         $action = "/clean";
   1300     }
   1301 
   1302     my @command = ($vcBuildPath, $project, $action, $config);
   1303 
   1304     print join(" ", @command), "\n";
   1305     return system @command;
   1306 }
   1307 
   1308 sub downloadWafIfNeeded
   1309 {
   1310     # get / update waf if needed
   1311     my $waf = "$sourceDir/Tools/wx/waf";
   1312     my $wafURL = 'http://wxwebkit.wxcommunity.com/downloads/deps/waf';
   1313     if (!-f $waf) {
   1314         my $result = system "curl -o $waf $wafURL";
   1315         chmod 0755, $waf;
   1316     }
   1317 }
   1318 
   1319 sub buildWafProject
   1320 {
   1321     my ($project, $shouldClean, @options) = @_;
   1322     
   1323     # set the PYTHONPATH for waf
   1324     my $pythonPath = $ENV{'PYTHONPATH'};
   1325     if (!defined($pythonPath)) {
   1326         $pythonPath = '';
   1327     }
   1328     my $sourceDir = sourceDir();
   1329     my $newPythonPath = "$sourceDir/Tools/wx/build:$pythonPath";
   1330     if (isCygwin()) {
   1331         $newPythonPath = `cygpath --mixed --path $newPythonPath`;
   1332     }
   1333     $ENV{'PYTHONPATH'} = $newPythonPath;
   1334     
   1335     print "Building $project\n";
   1336 
   1337     my $wafCommand = "$sourceDir/Tools/wx/waf";
   1338     if ($ENV{'WXWEBKIT_WAF'}) {
   1339         $wafCommand = $ENV{'WXWEBKIT_WAF'};
   1340     }
   1341     if (isCygwin()) {
   1342         $wafCommand = `cygpath --windows "$wafCommand"`;
   1343         chomp($wafCommand);
   1344     }
   1345     if ($shouldClean) {
   1346         return system $wafCommand, "uninstall", "clean", "distclean";
   1347     }
   1348     
   1349     return system $wafCommand, 'configure', 'build', 'install', @options;
   1350 }
   1351 
   1352 sub retrieveQMakespecVar
   1353 {
   1354     my $mkspec = $_[0];
   1355     my $varname = $_[1];
   1356 
   1357     my $varvalue = undef;
   1358     #print "retrieveMakespecVar " . $mkspec . ", " . $varname . "\n";
   1359 
   1360     local *SPEC;
   1361     open SPEC, "<$mkspec" or return $varvalue;
   1362     while (<SPEC>) {
   1363         if ($_ =~ /\s*include\((.+)\)/) {
   1364             # open the included mkspec
   1365             my $oldcwd = getcwd();
   1366             (my $volume, my $directories, my $file) = File::Spec->splitpath($mkspec);
   1367             my $newcwd = "$volume$directories";
   1368             chdir $newcwd if $newcwd;
   1369             $varvalue = retrieveQMakespecVar($1, $varname);
   1370             chdir $oldcwd;
   1371         } elsif ($_ =~ /$varname\s*=\s*([^\s]+)/) {
   1372             $varvalue = $1;
   1373             last;
   1374         }
   1375     }
   1376     close SPEC;
   1377     return $varvalue;
   1378 }
   1379 
   1380 sub qtMakeCommand($)
   1381 {
   1382     my ($qmakebin) = @_;
   1383     chomp(my $mkspec = `$qmakebin -query QMAKE_MKSPECS`);
   1384     $mkspec .= "/default";
   1385     my $compiler = retrieveQMakespecVar("$mkspec/qmake.conf", "QMAKE_CC");
   1386 
   1387     #print "default spec: " . $mkspec . "\n";
   1388     #print "compiler found: " . $compiler . "\n";
   1389 
   1390     if ($compiler && $compiler eq "cl") {
   1391         return "nmake";
   1392     }
   1393 
   1394     return "make";
   1395 }
   1396 
   1397 sub autotoolsFlag($$)
   1398 {
   1399     my ($flag, $feature) = @_;
   1400     my $prefix = $flag ? "--enable" : "--disable";
   1401 
   1402     return $prefix . '-' . $feature;
   1403 }
   1404 
   1405 sub autogenArgumentsHaveChanged($@)
   1406 {
   1407     my ($filename, @currentArguments) = @_;
   1408 
   1409     if (! -e $filename) {
   1410         return 1;
   1411     }
   1412 
   1413     open(AUTOTOOLS_ARGUMENTS, $filename);
   1414     chomp(my $previousArguments = <AUTOTOOLS_ARGUMENTS>);
   1415     close(AUTOTOOLS_ARGUMENTS);
   1416 
   1417     return $previousArguments ne join(" ", @currentArguments);
   1418 }
   1419 
   1420 sub buildAutotoolsProject($@)
   1421 {
   1422     my ($project, $clean, @buildParams) = @_;
   1423 
   1424     my $make = 'make';
   1425     my $dir = productDir();
   1426     my $config = passedConfiguration() || configuration();
   1427     my $prefix;
   1428 
   1429     my @buildArgs = ();
   1430     my $makeArgs = $ENV{"WebKitMakeArguments"} || "";
   1431     for my $i (0 .. $#buildParams) {
   1432         my $opt = $buildParams[$i];
   1433         if ($opt =~ /^--makeargs=(.*)/i ) {
   1434             $makeArgs = $makeArgs . " " . $1;
   1435         } elsif ($opt =~ /^--prefix=(.*)/i ) {
   1436             $prefix = $1;
   1437         } else {
   1438             push @buildArgs, $opt;
   1439         }
   1440     }
   1441 
   1442     # Automatically determine the number of CPUs for make only
   1443     # if make arguments haven't already been specified.
   1444     if ($makeArgs eq "") {
   1445         $makeArgs = "-j" . numberOfCPUs();
   1446     }
   1447 
   1448     # WebKit is the default target, so we don't need to specify anything.
   1449     if ($project eq "JavaScriptCore") {
   1450         $makeArgs .= " jsc";
   1451     }
   1452 
   1453     $prefix = $ENV{"WebKitInstallationPrefix"} if !defined($prefix);
   1454     push @buildArgs, "--prefix=" . $prefix if defined($prefix);
   1455 
   1456     # check if configuration is Debug
   1457     if ($config =~ m/debug/i) {
   1458         push @buildArgs, "--enable-debug";
   1459     } else {
   1460         push @buildArgs, "--disable-debug";
   1461     }
   1462 
   1463     # Use rm to clean the build directory since distclean may miss files
   1464     if ($clean && -d $dir) {
   1465         system "rm", "-rf", "$dir";
   1466     }
   1467 
   1468     if (! -d $dir) {
   1469         File::Path::mkpath($dir) or die "Failed to create build directory " . $dir
   1470     }
   1471     chdir $dir or die "Failed to cd into " . $dir . "\n";
   1472 
   1473     if ($clean) {
   1474         return 0;
   1475     }
   1476 
   1477     # If GNUmakefile exists, don't run autogen.sh. The makefile should be
   1478     # smart enough to track autotools dependencies and re-run autogen.sh
   1479     # when build files change.
   1480     my $autogenArgumentsFile = "previous-autogen-arguments.txt";
   1481     my $result;
   1482     if (!(-e "GNUmakefile") or autogenArgumentsHaveChanged($autogenArgumentsFile, @buildArgs)) {
   1483 
   1484         # Write autogen.sh arguments to a file so that we can detect
   1485         # when they change and automatically re-run it.
   1486         open(AUTOTOOLS_ARGUMENTS, ">$autogenArgumentsFile");
   1487         print AUTOTOOLS_ARGUMENTS  join(" ", @buildArgs);
   1488         close(AUTOTOOLS_ARGUMENTS);
   1489 
   1490         print "Calling configure in " . $dir . "\n\n";
   1491         print "Installation prefix directory: $prefix\n" if(defined($prefix));
   1492 
   1493         # Make the path relative since it will appear in all -I compiler flags.
   1494         # Long argument lists cause bizarre slowdowns in libtool.
   1495         my $relSourceDir = File::Spec->abs2rel($sourceDir) || ".";
   1496         $result = system "$relSourceDir/autogen.sh", @buildArgs;
   1497         if ($result ne 0) {
   1498             die "Failed to setup build environment using 'autotools'!\n";
   1499         }
   1500     }
   1501 
   1502     $result = system "$make $makeArgs";
   1503     if ($result ne 0) {
   1504         die "\nFailed to build WebKit using '$make'!\n";
   1505     }
   1506 
   1507     chdir ".." or die;
   1508     return $result;
   1509 }
   1510 
   1511 sub generateBuildSystemFromCMakeProject
   1512 {
   1513     my ($port, $prefixPath, @cmakeArgs) = @_;
   1514     my $config = configuration();
   1515     my $buildPath = File::Spec->catdir(baseProductDir(), $config);
   1516     File::Path::mkpath($buildPath) unless -d $buildPath;
   1517     my $originalWorkingDirectory = getcwd();
   1518     chdir($buildPath) or die;
   1519 
   1520     my @args;
   1521     push @args, "-DPORT=\"$port\"";
   1522     push @args, "-DCMAKE_INSTALL_PREFIX=\"$prefixPath\"" if $prefixPath;
   1523     if ($config =~ /release/i) {
   1524         push @args, "-DCMAKE_BUILD_TYPE=Release";
   1525     } elsif ($config =~ /debug/i) {
   1526         push @args, "-DCMAKE_BUILD_TYPE=Debug";
   1527     }
   1528     push @args, @cmakeArgs if @cmakeArgs;
   1529     push @args, '"' . File::Spec->catdir(sourceDir(), "Source") . '"';
   1530 
   1531     # We call system("cmake @args") instead of system("cmake", @args) so that @args is
   1532     # parsed for shell metacharacters.
   1533     my $returnCode = system("cmake @args");
   1534 
   1535     chdir($originalWorkingDirectory);
   1536     return $returnCode;
   1537 }
   1538 
   1539 sub buildCMakeGeneratedProject($)
   1540 {
   1541     my ($makeArgs) = @_;
   1542     my $config = configuration();
   1543     my $buildPath = File::Spec->catdir(baseProductDir(), $config);
   1544     if (! -d $buildPath) {
   1545         die "Must call generateBuildSystemFromCMakeProject() before building CMake project.";
   1546     }
   1547     my @args = ("--build", $buildPath, "--config", $config);
   1548     push @args, ("--", $makeArgs) if $makeArgs;
   1549 
   1550     # We call system("cmake @args") instead of system("cmake", @args) so that @args is
   1551     # parsed for shell metacharacters. In particular, $makeArgs may contain such metacharacters.
   1552     return system("cmake @args");
   1553 }
   1554 
   1555 sub cleanCMakeGeneratedProject()
   1556 {
   1557     my $config = configuration();
   1558     my $buildPath = File::Spec->catdir(baseProductDir(), $config);
   1559     if (-d $buildPath) {
   1560         return system("cmake", "--build", $buildPath, "--config", $config, "--target", "clean");
   1561     }
   1562     return 0;
   1563 }
   1564 
   1565 sub buildCMakeProjectOrExit($$$$@)
   1566 {
   1567     my ($clean, $port, $prefixPath, $makeArgs, @cmakeArgs) = @_;
   1568     my $returnCode;
   1569     if ($clean) {
   1570         $returnCode = exitStatus(cleanCMakeGeneratedProject());
   1571         exit($returnCode) if $returnCode;
   1572     }
   1573     $returnCode = exitStatus(generateBuildSystemFromCMakeProject($port, $prefixPath, @cmakeArgs));
   1574     exit($returnCode) if $returnCode;
   1575     $returnCode = exitStatus(buildCMakeGeneratedProject($makeArgs));
   1576     exit($returnCode) if $returnCode;
   1577 }
   1578 
   1579 sub buildQMakeProject($@)
   1580 {
   1581     my ($project, $clean, @buildParams) = @_;
   1582 
   1583     my @subdirs = ("JavaScriptCore", "WebCore", "WebKit/qt/Api");
   1584     if (grep { $_ eq $project } @subdirs) {
   1585         @subdirs = ($project);
   1586     } else {
   1587         $project = 0;
   1588     }
   1589 
   1590     my @buildArgs = ("-r");
   1591 
   1592     my $makeargs = "";
   1593     my $installHeaders;
   1594     my $installLibs;
   1595     for my $i (0 .. $#buildParams) {
   1596         my $opt = $buildParams[$i];
   1597         if ($opt =~ /^--qmake=(.*)/i ) {
   1598             $qmakebin = $1;
   1599         } elsif ($opt =~ /^--qmakearg=(.*)/i ) {
   1600             push @buildArgs, $1;
   1601         } elsif ($opt =~ /^--makeargs=(.*)/i ) {
   1602             $makeargs = $1;
   1603         } elsif ($opt =~ /^--install-headers=(.*)/i ) {
   1604             $installHeaders = $1;
   1605         } elsif ($opt =~ /^--install-libs=(.*)/i ) {
   1606             $installLibs = $1;
   1607         } else {
   1608             push @buildArgs, $opt;
   1609         }
   1610     }
   1611 
   1612     my $make = qtMakeCommand($qmakebin);
   1613     my $config = configuration();
   1614     push @buildArgs, "INSTALL_HEADERS=" . $installHeaders if defined($installHeaders);
   1615     push @buildArgs, "INSTALL_LIBS=" . $installLibs if defined($installLibs);
   1616     my $dir = File::Spec->canonpath(productDir());
   1617 
   1618 
   1619     # On Symbian qmake needs to run in the same directory where the pro file is located.
   1620     if (isSymbian()) {
   1621         $dir = $sourceDir . "/Source";
   1622     }
   1623 
   1624     File::Path::mkpath($dir);
   1625     chdir $dir or die "Failed to cd into " . $dir . "\n";
   1626 
   1627     print "Generating derived sources\n\n";
   1628 
   1629     push @buildArgs, "OUTPUT_DIR=" . $dir;
   1630 
   1631     my @dsQmakeArgs = @buildArgs;
   1632     push @dsQmakeArgs, "-r";
   1633     push @dsQmakeArgs, sourceDir() . "/Source/DerivedSources.pro";
   1634     if ($project) {
   1635         push @dsQmakeArgs, "-after SUBDIRS=" . $project. "/DerivedSources.pro";
   1636     }
   1637     push @dsQmakeArgs, "-o Makefile.DerivedSources";
   1638     print "Calling '$qmakebin @dsQmakeArgs' in " . $dir . "\n\n";
   1639     my $result = system "$qmakebin @dsQmakeArgs";
   1640     if ($result ne 0) {
   1641         die "Failed while running $qmakebin to generate derived sources!\n";
   1642     }
   1643 
   1644     if ($project ne "JavaScriptCore") {
   1645         # FIXME: Iterate over different source directories manually to workaround a problem with qmake+extraTargets+s60
   1646         # To avoid overwriting of Makefile.DerivedSources in the root dir use Makefile.DerivedSources.Tools for Tools
   1647         if (grep { $_ eq "CONFIG+=webkit2"} @buildArgs) {
   1648             push @subdirs, "WebKit2";
   1649             if ( -e sourceDir() ."/Tools/DerivedSources.pro" ) {
   1650                 @dsQmakeArgs = @buildArgs;
   1651                 push @dsQmakeArgs, "-r";
   1652                 push @dsQmakeArgs, sourceDir() . "/Tools/DerivedSources.pro";
   1653                 push @dsQmakeArgs, "-o Makefile.DerivedSources.Tools";
   1654                 print "Calling '$qmakebin @dsQmakeArgs' in " . $dir . "\n\n";
   1655                 my $result = system "$qmakebin @dsQmakeArgs";
   1656                 if ($result ne 0) {
   1657                     die "Failed while running $qmakebin to generate derived sources for Tools!\n";
   1658                 }
   1659                 push @subdirs, "WebKitTestRunner";
   1660             }
   1661         }
   1662     }
   1663 
   1664     for my $subdir (@subdirs) {
   1665         my $dsMakefile = "Makefile.DerivedSources";
   1666         print "Calling '$make $makeargs -C $subdir -f $dsMakefile generated_files' in " . $dir . "/$subdir\n\n";
   1667         if ($make eq "nmake") {
   1668             my $subdirWindows = $subdir;
   1669             $subdirWindows =~ s:/:\\:g;
   1670             $result = system "pushd $subdirWindows && $make $makeargs -f $dsMakefile generated_files && popd";
   1671         } else {
   1672             $result = system "$make $makeargs -C $subdir -f $dsMakefile generated_files";
   1673         }
   1674         if ($result ne 0) {
   1675             die "Failed to generate ${subdir}'s derived sources!\n";
   1676         }
   1677     }
   1678 
   1679     if ($config =~ m/debug/i) {
   1680         push @buildArgs, "CONFIG-=release";
   1681         push @buildArgs, "CONFIG+=debug";
   1682     } else {
   1683         my $passedConfig = passedConfiguration() || "";
   1684         if (!isDarwin() || $passedConfig =~ m/release/i) {
   1685             push @buildArgs, "CONFIG+=release";
   1686             push @buildArgs, "CONFIG-=debug";
   1687         } else {
   1688             push @buildArgs, "CONFIG+=debug";
   1689             push @buildArgs, "CONFIG+=debug_and_release";
   1690         }
   1691     }
   1692 
   1693     if ($project) {
   1694         push @buildArgs, "-after SUBDIRS=" . $project . "/" . $project . ".pro ";
   1695         if ($project eq "JavaScriptCore") {
   1696             push @buildArgs, "-after SUBDIRS+=" . $project . "/jsc.pro ";
   1697         }
   1698     }
   1699     push @buildArgs, sourceDir() . "/Source/WebKit.pro";
   1700     print "Calling '$qmakebin @buildArgs' in " . $dir . "\n\n";
   1701     print "Installation headers directory: $installHeaders\n" if(defined($installHeaders));
   1702     print "Installation libraries directory: $installLibs\n" if(defined($installLibs));
   1703 
   1704     $result = system "$qmakebin @buildArgs";
   1705     if ($result ne 0) {
   1706        die "Failed to setup build environment using $qmakebin!\n";
   1707     }
   1708 
   1709     my $makefile = "";
   1710     if (!$project) {
   1711         $buildArgs[-1] = sourceDir() . "/Tools/Tools.pro";
   1712         $makefile = "Makefile.Tools";
   1713 
   1714         # On Symbian qmake needs to run in the same directory where the pro file is located.
   1715         if (isSymbian()) {
   1716             $dir = $sourceDir . "/Tools";
   1717             chdir $dir or die "Failed to cd into " . $dir . "\n";
   1718             $makefile = "bld.inf";
   1719         }
   1720 
   1721         print "Calling '$qmakebin @buildArgs -o $makefile' in " . $dir . "\n\n";
   1722         $result = system "$qmakebin @buildArgs -o $makefile";
   1723         if ($result ne 0) {
   1724             die "Failed to setup build environment using $qmakebin!\n";
   1725         }
   1726     }
   1727 
   1728     if (!$project) {
   1729         # Manually create makefiles for the examples so we don't build by default
   1730         my $examplesDir = $dir . "/WebKit/qt/examples";
   1731         File::Path::mkpath($examplesDir);
   1732         $buildArgs[-1] = sourceDir() . "/Source/WebKit/qt/examples/examples.pro";
   1733         chdir $examplesDir or die;
   1734         print "Calling '$qmakebin @buildArgs' in " . $examplesDir . "\n\n";
   1735         $result = system "$qmakebin @buildArgs";
   1736         die "Failed to create makefiles for the examples!\n" if $result ne 0;
   1737         chdir $dir or die;
   1738     }
   1739 
   1740     my $makeTools = "echo";
   1741     if (!$project) {
   1742         $makeTools = "echo No Makefile for Tools. Skipping make";
   1743 
   1744         if (-e "$dir/$makefile") {
   1745             $makeTools = "$make $makeargs -f $makefile";
   1746         }
   1747     }
   1748 
   1749     if ($clean) {
   1750       print "Calling '$make $makeargs distclean' in " . $dir . "\n\n";
   1751       $result = system "$make $makeargs distclean";
   1752       $result = $result || system "$makeTools distclean";
   1753     } elsif (isSymbian()) {
   1754       print "\n\nWebKit is now configured for building, but you have to make\n";
   1755       print "a choice about the target yourself. To start the build run:\n\n";
   1756       print "    make release-armv5|debug-winscw|etc.\n\n";
   1757     } else {
   1758       print "Calling '$make $makeargs' in " . $dir . "\n\n";
   1759       $result = system "$make $makeargs";
   1760       $result = $result || system "$makeTools";
   1761     }
   1762 
   1763     chdir ".." or die;
   1764     return $result;
   1765 }
   1766 
   1767 sub buildQMakeQtProject($$@)
   1768 {
   1769     my ($project, $clean, @buildArgs) = @_;
   1770 
   1771     return buildQMakeProject("", $clean, @buildArgs);
   1772 }
   1773 
   1774 sub buildGtkProject
   1775 {
   1776     my ($project, $clean, @buildArgs) = @_;
   1777 
   1778     if ($project ne "WebKit" and $project ne "JavaScriptCore") {
   1779         die "Unsupported project: $project. Supported projects: WebKit, JavaScriptCore\n";
   1780     }
   1781 
   1782     return buildAutotoolsProject($project, $clean, @buildArgs);
   1783 }
   1784 
   1785 sub buildChromiumMakefile($$)
   1786 {
   1787     my ($target, $clean) = @_;
   1788     if ($clean) {
   1789         return system qw(rm -rf out);
   1790     }
   1791     my $config = configuration();
   1792     my $numCpus = numberOfCPUs();
   1793     my @command = ("make", "-fMakefile.chromium", "-j$numCpus", "BUILDTYPE=$config", $target);
   1794     print join(" ", @command) . "\n";
   1795     return system @command;
   1796 }
   1797 
   1798 sub buildChromiumVisualStudioProject($$)
   1799 {
   1800     my ($projectPath, $clean) = @_;
   1801 
   1802     my $config = configuration();
   1803     my $action = "/build";
   1804     $action = "/clean" if $clean;
   1805 
   1806     # Find Visual Studio installation.
   1807     my $vsInstallDir;
   1808     my $programFilesPath = $ENV{'PROGRAMFILES'} || "C:\\Program Files";
   1809     if ($ENV{'VSINSTALLDIR'}) {
   1810         $vsInstallDir = $ENV{'VSINSTALLDIR'};
   1811     } else {
   1812         $vsInstallDir = "$programFilesPath/Microsoft Visual Studio 8";
   1813     }
   1814     $vsInstallDir = `cygpath "$vsInstallDir"` if isCygwin();
   1815     chomp $vsInstallDir;
   1816     $vcBuildPath = "$vsInstallDir/Common7/IDE/devenv.com";
   1817     if (! -e $vcBuildPath) {
   1818         # Visual Studio not found, try VC++ Express
   1819         $vcBuildPath = "$vsInstallDir/Common7/IDE/VCExpress.exe";
   1820         if (! -e $vcBuildPath) {
   1821             print "*************************************************************\n";
   1822             print "Cannot find '$vcBuildPath'\n";
   1823             print "Please execute the file 'vcvars32.bat' from\n";
   1824             print "'$programFilesPath\\Microsoft Visual Studio 8\\VC\\bin\\'\n";
   1825             print "to setup the necessary environment variables.\n";
   1826             print "*************************************************************\n";
   1827             die;
   1828         }
   1829     }
   1830 
   1831     # Create command line and execute it.
   1832     my @command = ($vcBuildPath, $projectPath, $action, $config);
   1833     print "Building results into: ", baseProductDir(), "\n";
   1834     print join(" ", @command), "\n";
   1835     return system @command;
   1836 }
   1837 
   1838 sub buildChromium($@)
   1839 {
   1840     my ($clean, @options) = @_;
   1841 
   1842     # We might need to update DEPS or re-run GYP if things have changed.
   1843     if (checkForArgumentAndRemoveFromArrayRef("--update-chromium", \@options)) {
   1844         system("perl", "Tools/Scripts/update-webkit-chromium") == 0 or die $!;
   1845     }
   1846 
   1847     my $result = 1;
   1848     if (isDarwin()) {
   1849         # Mac build - builds the root xcode project.
   1850         $result = buildXCodeProject("Source/WebKit/chromium/WebKit", $clean, "-configuration", configuration(), @options);
   1851     } elsif (isCygwin() || isWindows()) {
   1852         # Windows build - builds the root visual studio solution.
   1853         $result = buildChromiumVisualStudioProject("Source/WebKit/chromium/WebKit.sln", $clean);
   1854     } elsif (isLinux()) {
   1855         # Linux build - build using make.
   1856         $ result = buildChromiumMakefile("all", $clean);
   1857     } else {
   1858         print STDERR "This platform is not supported by chromium.\n";
   1859     }
   1860     return $result;
   1861 }
   1862 
   1863 sub appleApplicationSupportPath
   1864 {
   1865     open INSTALL_DIR, "</proc/registry/HKEY_LOCAL_MACHINE/SOFTWARE/Apple\ Inc./Apple\ Application\ Support/InstallDir";
   1866     my $path = <INSTALL_DIR>;
   1867     $path =~ s/[\r\n\x00].*//;
   1868     close INSTALL_DIR;
   1869 
   1870     my $unixPath = `cygpath -u '$path'`;
   1871     chomp $unixPath;
   1872     return $unixPath;
   1873 }
   1874 
   1875 sub setPathForRunningWebKitApp
   1876 {
   1877     my ($env) = @_;
   1878 
   1879     if (isAppleWinWebKit()) {
   1880         $env->{PATH} = join(':', productDir(), dirname(installedSafariPath()), appleApplicationSupportPath(), $env->{PATH} || "");
   1881     } elsif (isQt()) {
   1882         my $qtLibs = `$qmakebin -query QT_INSTALL_LIBS`;
   1883         $qtLibs =~ s/[\n|\r]$//g;
   1884         $env->{PATH} = join(';', $qtLibs, productDir() . "/lib", $env->{PATH} || "");
   1885     }
   1886 }
   1887 
   1888 sub runSafari
   1889 {
   1890     my ($debugger) = @_;
   1891 
   1892     if (isAppleMacWebKit()) {
   1893         return system "$FindBin::Bin/gdb-safari", argumentsForConfiguration() if $debugger;
   1894 
   1895         my $productDir = productDir();
   1896         print "Starting Safari with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
   1897         $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
   1898         $ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES";
   1899         if (!isTiger() && architecture()) {
   1900             return system "arch", "-" . architecture(), safariPath(), @ARGV;
   1901         } else {
   1902             return system safariPath(), @ARGV;
   1903         }
   1904     }
   1905 
   1906     if (isAppleWinWebKit()) {
   1907         my $result;
   1908         my $productDir = productDir();
   1909         if ($debugger) {
   1910             setupCygwinEnv();
   1911             chomp($ENV{WEBKITNIGHTLY} = `cygpath -wa "$productDir"`);
   1912             my $safariPath = safariPath();
   1913             chomp($safariPath = `cygpath -wa "$safariPath"`);
   1914             $result = system $vcBuildPath, "/debugexe", "\"$safariPath\"", @ARGV;
   1915         } else {
   1916             $result = system File::Spec->catfile(productDir(), "WebKit.exe"), @ARGV;
   1917         }
   1918         return $result if $result;
   1919     }
   1920 
   1921     return 1;
   1922 }
   1923 
   1924 sub runMiniBrowser
   1925 {
   1926     if (isAppleMacWebKit()) {
   1927         my $productDir = productDir();
   1928         print "Starting MiniBrowser with DYLD_FRAMEWORK_PATH set to point to $productDir.\n";
   1929         $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
   1930         $ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES";
   1931         my $miniBrowserPath = "$productDir/MiniBrowser.app/Contents/MacOS/MiniBrowser";
   1932         if (!isTiger() && architecture()) {
   1933             return system "arch", "-" . architecture(), $miniBrowserPath, @ARGV;
   1934         } else {
   1935             return system $miniBrowserPath, @ARGV;
   1936         }
   1937     }
   1938 
   1939     return 1;
   1940 }
   1941 
   1942 sub debugMiniBrowser
   1943 {
   1944     if (isAppleMacWebKit()) {
   1945         my $gdbPath = "/usr/bin/gdb";
   1946         die "Can't find gdb executable. Is gdb installed?\n" unless -x $gdbPath;
   1947 
   1948         my $productDir = productDir();
   1949 
   1950         $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
   1951         $ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = 'YES';
   1952 
   1953         my $miniBrowserPath = "$productDir/MiniBrowser.app/Contents/MacOS/MiniBrowser";
   1954 
   1955         print "Starting MiniBrowser under gdb with DYLD_FRAMEWORK_PATH set to point to built WebKit2 in $productDir.\n";
   1956         my @architectureFlags = ("-arch", architecture()) if !isTiger();
   1957         exec $gdbPath, @architectureFlags, $miniBrowserPath or die;
   1958         return;
   1959     }
   1960     
   1961     return 1;
   1962 }
   1963 
   1964 sub runWebKitTestRunner
   1965 {
   1966     if (isAppleMacWebKit()) {
   1967         my $productDir = productDir();
   1968         print "Starting WebKitTestRunner with DYLD_FRAMEWORK_PATH set to point to $productDir.\n";
   1969         $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
   1970         $ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES";
   1971         my $webKitTestRunnerPath = "$productDir/WebKitTestRunner";
   1972         if (!isTiger() && architecture()) {
   1973             return system "arch", "-" . architecture(), $webKitTestRunnerPath, @ARGV;
   1974         } else {
   1975             return system $webKitTestRunnerPath, @ARGV;
   1976         }
   1977     }
   1978 
   1979     return 1;
   1980 }
   1981 
   1982 sub debugWebKitTestRunner
   1983 {
   1984     if (isAppleMacWebKit()) {
   1985         my $gdbPath = "/usr/bin/gdb";
   1986         die "Can't find gdb executable. Is gdb installed?\n" unless -x $gdbPath;
   1987 
   1988         my $productDir = productDir();
   1989         $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
   1990         $ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = 'YES';
   1991 
   1992         my $webKitTestRunnerPath = "$productDir/WebKitTestRunner";
   1993 
   1994         print "Starting WebKitTestRunner under gdb with DYLD_FRAMEWORK_PATH set to point to $productDir.\n";
   1995         my @architectureFlags = ("-arch", architecture()) if !isTiger();
   1996         exec $gdbPath, @architectureFlags, $webKitTestRunnerPath or die;
   1997         return;
   1998     }
   1999 
   2000     return 1;
   2001 }
   2002 
   2003 sub runTestWebKitAPI
   2004 {
   2005     if (isAppleMacWebKit()) {
   2006         my $productDir = productDir();
   2007         print "Starting TestWebKitAPI with DYLD_FRAMEWORK_PATH set to point to $productDir.\n";
   2008         $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
   2009         $ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES";
   2010         my $testWebKitAPIPath = "$productDir/TestWebKitAPI";
   2011         if (!isTiger() && architecture()) {
   2012             return system "arch", "-" . architecture(), $testWebKitAPIPath, @ARGV;
   2013         } else {
   2014             return system $testWebKitAPIPath, @ARGV;
   2015         }
   2016     }
   2017 
   2018     return 1;
   2019 }
   2020 
   2021 1;
   2022