1# Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved. 2# 3# Redistribution and use in source and binary forms, with or without 4# modification, are permitted provided that the following conditions 5# are met: 6# 7# 1. Redistributions of source code must retain the above copyright 8# notice, this list of conditions and the following disclaimer. 9# 2. Redistributions in binary form must reproduce the above copyright 10# notice, this list of conditions and the following disclaimer in the 11# documentation and/or other materials provided with the distribution. 12# 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 13# its contributors may be used to endorse or promote products derived 14# from this software without specific prior written permission. 15# 16# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 17# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 20# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 27# Module to share code to get to WebKit directories. 28 29use strict; 30use warnings; 31use FindBin; 32use File::Basename; 33use POSIX; 34use VCSUtils; 35 36BEGIN { 37 use Exporter (); 38 our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); 39 $VERSION = 1.00; 40 @ISA = qw(Exporter); 41 @EXPORT = qw(&chdirWebKit &baseProductDir &productDir &XcodeOptions &XcodeOptionString &XcodeOptionStringNoConfig &passedConfiguration &setConfiguration &safariPath &checkFrameworks ¤tSVNRevision); 42 %EXPORT_TAGS = ( ); 43 @EXPORT_OK = (); 44} 45 46our @EXPORT_OK; 47 48my $baseProductDir; 49my @baseProductDirOption; 50my $configuration; 51my $configurationForVisualStudio; 52my $configurationProductDir; 53my $sourceDir; 54my $currentSVNRevision; 55my $osXVersion; 56my $isQt; 57my $isGtk; 58my $isWx; 59my $forceRun64Bit; 60 61# Variables for Win32 support 62my $vcBuildPath; 63my $windowsTmpPath; 64 65sub determineSourceDir 66{ 67 return if $sourceDir; 68 $sourceDir = $FindBin::Bin; 69 $sourceDir =~ s|/+$||; # Remove trailing '/' as we would die later 70 71 # walks up path checking each directory to see if it is the main WebKit project dir, 72 # defined by containing JavaScriptCore, WebCore, and WebKit 73 until ((-d "$sourceDir/JavaScriptCore" && -d "$sourceDir/WebCore" && -d "$sourceDir/WebKit") || (-d "$sourceDir/Internal" && -d "$sourceDir/OpenSource")) 74 { 75 if ($sourceDir !~ s|/[^/]+$||) { 76 die "Could not find top level webkit directory above source directory using FindBin.\n"; 77 } 78 } 79 80 $sourceDir = "$sourceDir/OpenSource" if -d "$sourceDir/OpenSource"; 81} 82 83# used for scripts which are stored in a non-standard location 84sub setSourceDir($) 85{ 86 ($sourceDir) = @_; 87} 88 89sub determineBaseProductDir 90{ 91 return if defined $baseProductDir; 92 determineSourceDir(); 93 if (isOSX()) { 94 open PRODUCT, "defaults read com.apple.Xcode PBXApplicationwideBuildSettings 2> /dev/null |" or die; 95 $baseProductDir = join '', <PRODUCT>; 96 close PRODUCT; 97 98 $baseProductDir = $1 if $baseProductDir =~ /SYMROOT\s*=\s*\"(.*?)\";/s; 99 undef $baseProductDir unless $baseProductDir =~ /^\//; 100 101 if (!defined($baseProductDir)) { 102 open PRODUCT, "defaults read com.apple.Xcode PBXProductDirectory 2> /dev/null |" or die; 103 $baseProductDir = <PRODUCT>; 104 close PRODUCT; 105 if ($baseProductDir) { 106 chomp $baseProductDir; 107 undef $baseProductDir unless $baseProductDir =~ /^\//; 108 } 109 } 110 } else { 111 $baseProductDir = $ENV{"WEBKITOUTPUTDIR"}; 112 if (isCygwin() && $baseProductDir) { 113 my $unixBuildPath = `cygpath --unix \"$baseProductDir\"`; 114 chomp $unixBuildPath; 115 $baseProductDir = $unixBuildPath; 116 } 117 } 118 119 if ($baseProductDir && isOSX()) { 120 $baseProductDir =~ s|^\Q$(SRCROOT)/..\E$|$sourceDir|; 121 $baseProductDir =~ s|^\Q$(SRCROOT)/../|$sourceDir/|; 122 $baseProductDir =~ s|^~/|$ENV{HOME}/|; 123 die "Can't handle Xcode product directory with a ~ in it.\n" if $baseProductDir =~ /~/; 124 die "Can't handle Xcode product directory with a variable in it.\n" if $baseProductDir =~ /\$/; 125 @baseProductDirOption = (); 126 } 127 128 if (!defined($baseProductDir)) { 129 $baseProductDir = "$sourceDir/WebKitBuild"; 130 131 if (isGit() && isGitBranchBuild()) { 132 my $branch = gitBranch(); 133 $baseProductDir = "$baseProductDir/$branch"; 134 } 135 136 @baseProductDirOption = ("SYMROOT=$baseProductDir", "OBJROOT=$baseProductDir") if (isOSX()); 137 if (isCygwin()) { 138 my $dosBuildPath = `cygpath --windows \"$baseProductDir\"`; 139 chomp $dosBuildPath; 140 $ENV{"WEBKITOUTPUTDIR"} = $dosBuildPath; 141 } 142 } 143} 144 145sub setBaseProductDir($) 146{ 147 ($baseProductDir) = @_; 148} 149 150sub determineConfiguration 151{ 152 return if defined $configuration; 153 determineBaseProductDir(); 154 if (open CONFIGURATION, "$baseProductDir/Configuration") { 155 $configuration = <CONFIGURATION>; 156 close CONFIGURATION; 157 } 158 if ($configuration) { 159 chomp $configuration; 160 # compatibility for people who have old Configuration files 161 $configuration = "Release" if $configuration eq "Deployment"; 162 $configuration = "Debug" if $configuration eq "Development"; 163 } else { 164 $configuration = "Release"; 165 } 166} 167 168sub determineConfigurationForVisualStudio 169{ 170 return if defined $configurationForVisualStudio; 171 determineConfiguration(); 172 $configurationForVisualStudio = $configuration; 173 return unless $configuration eq "Debug"; 174 setupCygwinEnv(); 175 chomp(my $dir = `cygpath -ua '$ENV{WEBKITLIBRARIESDIR}'`); 176 $configurationForVisualStudio = "Debug_Internal" if -f "$dir/bin/CoreFoundation_debug.dll"; 177} 178 179sub determineConfigurationProductDir 180{ 181 return if defined $configurationProductDir; 182 determineBaseProductDir(); 183 determineConfiguration(); 184 if (isCygwin() && !isWx()) { 185 $configurationProductDir = "$baseProductDir/bin"; 186 } else { 187 $configurationProductDir = "$baseProductDir/$configuration"; 188 } 189} 190 191sub setConfigurationProductDir($) 192{ 193 ($configurationProductDir) = @_; 194} 195 196sub determineCurrentSVNRevision 197{ 198 return if defined $currentSVNRevision; 199 determineSourceDir(); 200 my $svnInfo = `LC_ALL=C svn info $sourceDir | grep Revision:`; 201 ($currentSVNRevision) = ($svnInfo =~ m/Revision: (\d+).*/g); 202 die "Unable to determine current SVN revision in $sourceDir" unless (defined $currentSVNRevision); 203 return $currentSVNRevision; 204} 205 206 207sub chdirWebKit 208{ 209 determineSourceDir(); 210 chdir $sourceDir or die; 211} 212 213sub baseProductDir 214{ 215 determineBaseProductDir(); 216 return $baseProductDir; 217} 218 219sub sourceDir 220{ 221 determineSourceDir(); 222 return $sourceDir; 223} 224 225sub productDir 226{ 227 determineConfigurationProductDir(); 228 return $configurationProductDir; 229} 230 231sub configuration() 232{ 233 determineConfiguration(); 234 return $configuration; 235} 236 237sub configurationForVisualStudio() 238{ 239 determineConfigurationForVisualStudio(); 240 return $configurationForVisualStudio; 241} 242 243sub currentSVNRevision 244{ 245 determineCurrentSVNRevision(); 246 return $currentSVNRevision; 247} 248 249sub XcodeOptions 250{ 251 determineBaseProductDir(); 252 determineConfiguration(); 253 return (@baseProductDirOption, "-configuration", $configuration); 254} 255 256sub XcodeOptionString 257{ 258 return join " ", XcodeOptions(); 259} 260 261sub XcodeOptionStringNoConfig 262{ 263 return join " ", @baseProductDirOption; 264} 265 266my $passedConfiguration; 267my $searchedForPassedConfiguration; 268sub determinePassedConfiguration 269{ 270 return if $searchedForPassedConfiguration; 271 $searchedForPassedConfiguration = 1; 272 273 my $isWinCairo = grep(/^--cairo-win32$/i, @ARGV); 274 275 for my $i (0 .. $#ARGV) { 276 my $opt = $ARGV[$i]; 277 if ($opt =~ /^--debug$/i || $opt =~ /^--devel/i) { 278 splice(@ARGV, $i, 1); 279 $passedConfiguration = "Debug"; 280 $passedConfiguration .= "_Cairo" if ($isWinCairo && isCygwin()); 281 return; 282 } 283 if ($opt =~ /^--release$/i || $opt =~ /^--deploy/i) { 284 splice(@ARGV, $i, 1); 285 $passedConfiguration = "Release"; 286 $passedConfiguration .= "_Cairo" if ($isWinCairo && isCygwin()); 287 return; 288 } 289 if ($opt =~ /^--profil(e|ing)$/i) { 290 splice(@ARGV, $i, 1); 291 $passedConfiguration = "Profiling"; 292 $passedConfiguration .= "_Cairo" if ($isWinCairo && isCygwin()); 293 return; 294 } 295 } 296 $passedConfiguration = undef; 297} 298 299sub passedConfiguration 300{ 301 determinePassedConfiguration(); 302 return $passedConfiguration; 303} 304 305sub setConfiguration 306{ 307 if (my $config = shift @_) { 308 $configuration = $config; 309 return; 310 } 311 312 determinePassedConfiguration(); 313 $configuration = $passedConfiguration if $passedConfiguration; 314} 315 316sub safariPathFromSafariBundle 317{ 318 my ($safariBundle) = @_; 319 320 return "$safariBundle/Contents/MacOS/Safari" if isOSX(); 321 return $safariBundle if isCygwin(); 322} 323 324sub installedSafariPath 325{ 326 my $safariBundle; 327 328 if (isOSX()) { 329 $safariBundle = "/Applications/Safari.app"; 330 } elsif (isCygwin()) { 331 $safariBundle = `"$configurationProductDir/FindSafari.exe"`; 332 $safariBundle =~ s/[\r\n]+$//; 333 $safariBundle = `cygpath -u '$safariBundle'`; 334 $safariBundle =~ s/[\r\n]+$//; 335 $safariBundle .= "Safari.exe"; 336 } 337 338 return safariPathFromSafariBundle($safariBundle); 339} 340 341# Locate Safari. 342sub safariPath 343{ 344 # Use WEBKIT_SAFARI environment variable if present. 345 my $safariBundle = $ENV{WEBKIT_SAFARI}; 346 if (!$safariBundle) { 347 determineConfigurationProductDir(); 348 # Use Safari.app in product directory if present (good for Safari development team). 349 if (isOSX() && -d "$configurationProductDir/Safari.app") { 350 $safariBundle = "$configurationProductDir/Safari.app"; 351 } elsif (isCygwin() && -x "$configurationProductDir/bin/Safari.exe") { 352 $safariBundle = "$configurationProductDir/bin/Safari.exe"; 353 } else { 354 return installedSafariPath(); 355 } 356 } 357 my $safariPath = safariPathFromSafariBundle($safariBundle); 358 die "Can't find executable at $safariPath.\n" if isOSX() && !-x $safariPath; 359 return $safariPath; 360} 361 362sub builtDylibPathForName 363{ 364 my $framework = shift; 365 determineConfigurationProductDir(); 366 if (isQt() or isGtk()) { 367 return "$configurationProductDir/$framework"; 368 } 369 if (isOSX()) { 370 return "$configurationProductDir/$framework.framework/Versions/A/$framework"; 371 } 372 if (isCygwin()) { 373 if ($framework eq "JavaScriptCore") { 374 return "$baseProductDir/lib/$framework.lib"; 375 } else { 376 return "$baseProductDir/$framework.intermediate/$configuration/$framework.intermediate/$framework.lib"; 377 } 378 } 379 380 die "Unsupported platform, can't determine built library locations."; 381} 382 383# Check to see that all the frameworks are built. 384sub checkFrameworks 385{ 386 return if isCygwin(); 387 my @frameworks = ("JavaScriptCore", "WebCore"); 388 push(@frameworks, "WebKit") if isOSX(); 389 for my $framework (@frameworks) { 390 my $path = builtDylibPathForName($framework); 391 die "Can't find built framework at \"$path\".\n" unless -x $path; 392 } 393} 394 395sub hasSVGSupport 396{ 397 return 0 if isCygwin(); 398 399 my $path = shift; 400 401 if (isQt()) { 402 return 1; 403 } 404 405 if (isGtk() and $path =~ /WebCore/) { 406 $path .= "/../.libs/webkit-1.0.so"; 407 } 408 409 my $hasSVGSupport = 0; 410 if (-e $path) { 411 open NM, "-|", "nm", $path or die; 412 while (<NM>) { 413 $hasSVGSupport = 1 if /SVGElement/; 414 } 415 close NM; 416 } 417 return $hasSVGSupport; 418} 419 420sub removeLibraryDependingOnSVG 421{ 422 my $frameworkName = shift; 423 my $shouldHaveSVG = shift; 424 425 my $path = builtDylibPathForName($frameworkName); 426 return unless -x $path; 427 428 my $hasSVG = hasSVGSupport($path); 429 system "rm -f $path" if ($shouldHaveSVG xor $hasSVG); 430} 431 432sub checkWebCoreSVGSupport 433{ 434 my $required = shift; 435 my $framework = "WebCore"; 436 my $path = builtDylibPathForName($framework); 437 my $hasSVG = hasSVGSupport($path); 438 if ($required && !$hasSVG) { 439 die "$framework at \"$path\" does not include SVG Support, please run build-webkit --svg\n"; 440 } 441 return $hasSVG; 442} 443 444sub isQt() 445{ 446 determineIsQt(); 447 return $isQt; 448} 449 450sub checkArgv($) 451{ 452 my $argToCheck = shift; 453 foreach my $opt (@ARGV) { 454 if ($opt =~ /^$argToCheck/i ) { 455 @ARGV = grep(!/^$argToCheck/i, @ARGV); 456 return 1; 457 } 458 } 459 return 0; 460} 461 462sub determineIsQt() 463{ 464 return if defined($isQt); 465 466 # Allow override in case QTDIR is not set. 467 if (checkArgv("--qt")) { 468 $isQt = 1; 469 return; 470 } 471 472 # The presence of QTDIR only means Qt if --gtk is not on the command-line 473 if (isGtk()) { 474 $isQt = 0; 475 return; 476 } 477 478 $isQt = defined($ENV{'QTDIR'}); 479} 480 481sub isGtk() 482{ 483 determineIsGtk(); 484 return $isGtk; 485} 486 487sub determineIsGtk() 488{ 489 return if defined($isGtk); 490 491 if (checkArgv("--gtk")) { 492 $isGtk = 1; 493 } else { 494 $isGtk = 0; 495 } 496} 497 498sub isWx() 499{ 500 determineIsWx(); 501 return $isWx; 502} 503 504sub determineIsWx() 505{ 506 return if defined($isWx); 507 508 if (checkArgv("--wx")) { 509 $isWx = 1; 510 } else { 511 $isWx = 0; 512 } 513} 514 515# Determine if this is debian, ubuntu, linspire, or something similar. 516sub isDebianBased() 517{ 518 return -e "/etc/debian_version"; 519} 520 521sub isCygwin() 522{ 523 return ($^O eq "cygwin") || 0; 524} 525 526sub isDarwin() 527{ 528 return ($^O eq "darwin") || 0; 529} 530 531# isOSX() only returns true for Apple's port, not for other ports that can be 532# built/run on OS X. 533sub isOSX() 534{ 535 return isDarwin() unless (isQt() or isGtk() or isWx()); 536 return 0; 537} 538 539sub determineOSXVersion() 540{ 541 return if $osXVersion; 542 543 if (!isOSX()) { 544 $osXVersion = -1; 545 return; 546 } 547 548 my $version = `sw_vers -productVersion`; 549 my @splitVersion = split(/\./, $version); 550 @splitVersion >= 2 or die "Invalid version $version"; 551 $osXVersion = { 552 "major" => $splitVersion[0], 553 "minor" => $splitVersion[1], 554 "subminor" => (defined($splitVersion[2]) ? $splitVersion[2] : 0), 555 }; 556} 557 558sub osXVersion() 559{ 560 determineOSXVersion(); 561 return $osXVersion; 562} 563 564sub isTiger() 565{ 566 return isOSX() && osXVersion()->{"minor"} == 4; 567} 568 569sub isLeopard() 570{ 571 return isOSX() && osXVersion()->{"minor"} == 5; 572} 573 574sub isSnowLeopard() 575{ 576 return isOSX() && osXVersion()->{"minor"} == 6; 577} 578 579sub relativeScriptsDir() 580{ 581 my $scriptDir = File::Spec->catpath("", File::Spec->abs2rel(dirname($0), getcwd()), ""); 582 if ($scriptDir eq "") { 583 $scriptDir = "."; 584 } 585 return $scriptDir; 586} 587 588sub launcherPath() 589{ 590 my $relativeScriptsPath = relativeScriptsDir(); 591 if (isGtk() || isQt()) { 592 return "$relativeScriptsPath/run-launcher"; 593 } elsif (isOSX() || isCygwin()) { 594 return "$relativeScriptsPath/run-safari"; 595 } 596} 597 598sub launcherName() 599{ 600 if (isGtk()) { 601 return "GtkLauncher"; 602 } elsif (isQt()) { 603 return "QtLauncher"; 604 } elsif (isOSX() || isCygwin()) { 605 return "Safari"; 606 } 607} 608 609sub checkRequiredSystemConfig 610{ 611 if (isOSX()) { 612 chomp(my $productVersion = `sw_vers -productVersion`); 613 if ($productVersion lt "10.4") { 614 print "*************************************************************\n"; 615 print "Mac OS X Version 10.4.0 or later is required to build WebKit.\n"; 616 print "You have " . $productVersion . ", thus the build will most likely fail.\n"; 617 print "*************************************************************\n"; 618 } 619 my $xcodeVersion = `xcodebuild -version`; 620 if ($xcodeVersion !~ /DevToolsCore-(\d+)/ || $1 < 747) { 621 print "*************************************************************\n"; 622 print "Xcode Version 2.3 or later is required to build WebKit.\n"; 623 print "You have an earlier version of Xcode, thus the build will\n"; 624 print "most likely fail. The latest Xcode is available from the web:\n"; 625 print "http://developer.apple.com/tools/xcode\n"; 626 print "*************************************************************\n"; 627 } 628 } elsif (isGtk() or isQt() or isWx()) { 629 my @cmds = qw(flex bison gperf); 630 my @missing = (); 631 foreach my $cmd (@cmds) { 632 if (not `$cmd --version`) { 633 push @missing, $cmd; 634 } 635 } 636 if (@missing) { 637 my $list = join ", ", @missing; 638 die "ERROR: $list missing but required to build WebKit.\n"; 639 } 640 } 641 # Win32 and other platforms may want to check for minimum config 642} 643 644sub setupCygwinEnv() 645{ 646 return if !isCygwin(); 647 return if $vcBuildPath; 648 649 my $programFilesPath = `cygpath "$ENV{'PROGRAMFILES'}"`; 650 chomp $programFilesPath; 651 $vcBuildPath = "$programFilesPath/Microsoft Visual Studio 8/Common7/IDE/devenv.com"; 652 if (! -e $vcBuildPath) { 653 # VC++ not found, try VC++ Express 654 my $vsInstallDir; 655 if ($ENV{'VSINSTALLDIR'}) { 656 $vsInstallDir = $ENV{'VSINSTALLDIR'}; 657 } else { 658 $programFilesPath = $ENV{'PROGRAMFILES'} || "C:\\Program Files"; 659 $vsInstallDir = "$programFilesPath/Microsoft Visual Studio 8"; 660 } 661 $vsInstallDir = `cygpath "$vsInstallDir"`; 662 chomp $vsInstallDir; 663 $vcBuildPath = "$vsInstallDir/Common7/IDE/VCExpress.exe"; 664 if (! -e $vcBuildPath) { 665 print "*************************************************************\n"; 666 print "Cannot find '$vcBuildPath'\n"; 667 print "Please execute the file 'vcvars32.bat' from\n"; 668 print "'$programFilesPath\\Microsoft Visual Studio 8\\VC\\bin\\'\n"; 669 print "to setup the necessary environment variables.\n"; 670 print "*************************************************************\n"; 671 die; 672 } 673 } 674 675 my $qtSDKPath = "$programFilesPath/QuickTime SDK"; 676 if (0 && ! -e $qtSDKPath) { 677 print "*************************************************************\n"; 678 print "Cannot find '$qtSDKPath'\n"; 679 print "Please download the QuickTime SDK for Windows from\n"; 680 print "http://developer.apple.com/quicktime/download/\n"; 681 print "*************************************************************\n"; 682 die; 683 } 684 685 chomp($ENV{'WEBKITLIBRARIESDIR'} = `cygpath -wa "$sourceDir/WebKitLibraries/win"`) unless $ENV{'WEBKITLIBRARIESDIR'}; 686 687 $windowsTmpPath = `cygpath -w /tmp`; 688 chomp $windowsTmpPath; 689 print "Building results into: ", baseProductDir(), "\n"; 690 print "WEBKITOUTPUTDIR is set to: ", $ENV{"WEBKITOUTPUTDIR"}, "\n"; 691 print "WEBKITLIBRARIESDIR is set to: ", $ENV{"WEBKITLIBRARIESDIR"}, "\n"; 692} 693 694sub buildVisualStudioProject 695{ 696 my ($project, $clean) = @_; 697 setupCygwinEnv(); 698 699 my $config = configurationForVisualStudio(); 700 701 chomp(my $winProjectPath = `cygpath -w "$project"`); 702 703 my $command = "/build"; 704 if ($clean) { 705 $command = "/clean"; 706 } 707 708 print "$vcBuildPath $winProjectPath /build $config\n"; 709 return system $vcBuildPath, $winProjectPath, $command, $config; 710} 711 712sub retrieveQMakespecVar 713{ 714 my $mkspec = $_[0]; 715 my $varname = $_[1]; 716 717 my $compiler = "unknown"; 718 #print "retrieveMakespecVar " . $mkspec . ", " . $varname . "\n"; 719 720 local *SPEC; 721 open SPEC, "<$mkspec" or return "make"; 722 while (<SPEC>) { 723 if ($_ =~ /\s*include\((.+)\)/) { 724 # open the included mkspec 725 my $oldcwd = getcwd(); 726 (my $volume, my $directories, my $file) = File::Spec->splitpath($mkspec); 727 chdir "$volume$directories"; 728 $compiler = retrieveQMakespecVar($1, $varname); 729 chdir $oldcwd; 730 } elsif ($_ =~ /$varname\s*=\s*([^\s]+)/) { 731 $compiler = $1; 732 last; 733 } 734 } 735 close SPEC; 736 return $compiler; 737} 738 739sub qtMakeCommand($) 740{ 741 my ($qmakebin) = @_; 742 chomp(my $mkspec = `$qmakebin -query QMAKE_MKSPECS`); 743 $mkspec .= "/default"; 744 my $compiler = retrieveQMakespecVar("$mkspec/qmake.conf", "QMAKE_CC"); 745 746 #print "default spec: " . $mkspec . "\n"; 747 #print "compiler found: " . $compiler . "\n"; 748 749 if ($compiler eq "cl") { 750 return "nmake"; 751 } 752 753 return "make"; 754} 755 756sub autotoolsFlag($$) 757{ 758 my ($flag, $feature) = @_; 759 my $prefix = $flag ? "--enable" : "--disable"; 760 761 return $prefix . '-' . $feature; 762} 763 764sub buildAutotoolsProject($@) 765{ 766 my ($clean, @buildArgs) = @_; 767 768 my $make = 'make'; 769 my $dir = productDir(); 770 my $config = passedConfiguration() || configuration(); 771 my $prefix = $ENV{"WebKitInstallationPrefix"}; 772 773 # check if configuration is Debug 774 if ($config =~ m/debug/i) { 775 push @buildArgs, "--enable-debug"; 776 } else { 777 push @buildArgs, "--disable-debug"; 778 } 779 780 if (! -d $dir) { 781 system "mkdir", "-p", "$dir"; 782 if (! -d $dir) { 783 die "Failed to create build directory " . $dir; 784 } 785 } 786 787 chdir $dir or die "Failed to cd into " . $dir . "\n"; 788 789 my $result; 790 if ($clean) { 791 $result = system $make, "distclean"; 792 return 0; 793 } 794 795 print "Calling configure in " . $dir . "\n\n"; 796 print "Installation directory: $prefix\n" if(defined($prefix)); 797 798 $result = system "$sourceDir/autogen.sh", @buildArgs; 799 if ($result ne 0) { 800 die "Failed to setup build environment using 'autotools'!\n"; 801 } 802 803 $result = system $make; 804 if ($result ne 0) { 805 die "\nFailed to build WebKit using '$make'!\n"; 806 } 807 808 chdir ".." or die; 809 return $result; 810} 811 812sub buildQMakeProject($@) 813{ 814 my ($clean, @buildArgs) = @_; 815 816 push @buildArgs, "-r"; 817 818 my $qmakebin = "qmake"; # Allow override of the qmake binary from $PATH 819 for my $i (0 .. $#ARGV) { 820 my $opt = $ARGV[$i]; 821 if ($opt =~ /^--qmake=(.*)/i ) { 822 $qmakebin = $1; 823 } elsif ($opt =~ /^--qmakearg=(.*)/i ) { 824 push @buildArgs, $1; 825 } 826 } 827 828 my $make = qtMakeCommand($qmakebin); 829 my $config = configuration(); 830 my $prefix = $ENV{"WebKitInstallationPrefix"}; 831 832 push @buildArgs, "OUTPUT_DIR=" . baseProductDir() . "/$config"; 833 push @buildArgs, sourceDir() . "/WebKit.pro"; 834 if ($config =~ m/debug/i) { 835 push @buildArgs, "CONFIG-=release"; 836 push @buildArgs, "CONFIG+=debug"; 837 } else { 838 push @buildArgs, "CONFIG+=release"; 839 push @buildArgs, "CONFIG-=debug"; 840 } 841 842 my $dir = baseProductDir(); 843 if (! -d $dir) { 844 system "mkdir", "-p", "$dir"; 845 if (! -d $dir) { 846 die "Failed to create product directory " . $dir; 847 } 848 } 849 $dir = $dir . "/$config"; 850 if (! -d $dir) { 851 system "mkdir", "-p", "$dir"; 852 if (! -d $dir) { 853 die "Failed to create build directory " . $dir; 854 } 855 } 856 857 chdir $dir or die "Failed to cd into " . $dir . "\n"; 858 859 print "Calling '$qmakebin @buildArgs' in " . $dir . "\n\n"; 860 print "Installation directory: $prefix\n" if(defined($prefix)); 861 862 my $result = system $qmakebin, @buildArgs; 863 if ($result ne 0) { 864 die "Failed to setup build environment using $qmakebin!\n"; 865 } 866 867 if ($clean) { 868 $result = system "$make distclean"; 869 } else { 870 $result = system "$make"; 871 } 872 873 chdir ".." or die; 874 return $result; 875} 876 877sub buildQMakeQtProject($$) 878{ 879 my ($project, $clean) = @_; 880 881 my @buildArgs = ("CONFIG+=qt-port"); 882 return buildQMakeProject($clean, @buildArgs); 883} 884 885sub buildGtkProject($$@) 886{ 887 my ($project, $clean, @buildArgs) = @_; 888 889 if ($project ne "WebKit") { 890 die "The Gtk port builds JavaScriptCore, WebCore and WebKit in one shot! Only call it for 'WebKit'.\n"; 891 } 892 893 return buildAutotoolsProject($clean, @buildArgs); 894} 895 896sub setPathForRunningWebKitApp 897{ 898 my ($env) = @_; 899 900 return unless isCygwin(); 901 902 $env->{PATH} = join(':', productDir(), dirname(installedSafariPath()), $env->{PATH} || ""); 903} 904 905sub exitStatus($) 906{ 907 my ($returnvalue) = @_; 908 if ($^O eq "MSWin32") { 909 return $returnvalue >> 8; 910 } 911 return WEXITSTATUS($returnvalue); 912} 913 914sub runSafari 915{ 916 my ($debugger) = @_; 917 918 if (isOSX()) { 919 return system "$FindBin::Bin/gdb-safari", @ARGV if $debugger; 920 921 my $productDir = productDir(); 922 print "Starting Safari with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n"; 923 $ENV{DYLD_FRAMEWORK_PATH} = $productDir; 924 $ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES"; 925 exportArchPreference(); 926 if (!isTiger()) { 927 return system "arch", safariPath(), @ARGV; 928 } else { 929 return system safariPath(), @ARGV; 930 } 931 } 932 933 if (isCygwin()) { 934 my $script = "run-webkit-nightly.cmd"; 935 my $result = system "cp", "$FindBin::Bin/$script", productDir(); 936 return $result if $result; 937 938 my $cwd = getcwd(); 939 chdir productDir(); 940 941 my $debuggerFlag = $debugger ? "/debugger" : ""; 942 $result = system "cmd", "/c", "call $script $debuggerFlag"; 943 chdir $cwd; 944 return $result; 945 } 946 947 return 1; 948} 949 950sub setRun64Bit($) 951{ 952 ($forceRun64Bit) = @_; 953} 954 955sub preferredArchitecture 956{ 957 return unless isOSX(); 958 959 my $framework = shift; 960 $framework = "WebKit" if !defined($framework); 961 962 my $currentArchitecture = `arch`; 963 chomp($currentArchitecture); 964 965 my $run64Bit = 0; 966 if (!defined($forceRun64Bit)) { 967 my $frameworkPath = builtDylibPathForName($framework); 968 die "Couldn't find path for $framework" if !defined($frameworkPath); 969 # The binary is 64-bit if one of the architectures it contains has "64" in the name 970 $run64Bit = `lipo -info "$frameworkPath"` =~ /(are|architecture):.*64/; 971 } 972 973 if ($forceRun64Bit or $run64Bit) { 974 return ($currentArchitecture eq "i386") ? "x86_64" : "ppc64"; 975 } 976 return $currentArchitecture; 977} 978 979sub exportArchPreference 980{ 981 $ENV{ARCHPREFERENCE} = preferredArchitecture() if isOSX(); 982} 983 9841; 985