1 # Copyright (C) 2005, 2006, 2007, 2010, 2011, 2012, 2013 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 # Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
10 # 1. Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 # notice, this list of conditions and the following disclaimer in the
14 # documentation and/or other materials provided with the distribution.
15 # 3. Neither the name of Apple Inc. ("Apple") nor the names of
16 # its contributors may be used to endorse or promote products derived
17 # from this software without specific prior written permission.
19 # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 # DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 # Module to share code to get to WebKit directories.
36 use Digest::MD5 qw(md5_hex);
39 use File::Path qw(mkpath rmtree);
47 our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
52 &XcodeOptionStringNoConfig
57 &cmakeBasedPortArguments
63 &printHelpAndExitForRunAndDebugWebKitAppIfNeeded
74 use constant USE_OPEN_COMMAND => 1; # Used in runMacWebKitApp().
75 use constant INCLUDE_OPTIONS_FOR_DEBUGGING => 1;
83 my @baseProductDirOption;
86 my $configurationForVisualStudio;
87 my $configurationProductDir;
89 my $currentSVNRevision;
91 my $iPhoneSimulatorVersion;
101 my $isInspectorFrontend;
103 my $shouldTargetWebProcess;
104 my $shouldUseXPCServiceForWebProcess;
105 my $shouldUseGuardMalloc;
108 # Variables for Win32 support
109 my $programFilesPath;
113 my $windowsSourceDir;
115 my $willUseVCExpressWhenBuilding = 0;
117 # Defined in VCSUtils.
120 sub findMatchingArguments($$);
123 sub determineSourceDir
125 return if $sourceDir;
126 $sourceDir = $FindBin::Bin;
127 $sourceDir =~ s|/+$||; # Remove trailing '/' as we would die later
129 # walks up path checking each directory to see if it is the main WebKit project dir,
130 # defined by containing Sources, WebCore, and WebKit
131 until ((-d "$sourceDir/Source" && -d "$sourceDir/Source/WebCore" && -d "$sourceDir/Source/WebKit") || (-d "$sourceDir/Internal" && -d "$sourceDir/OpenSource"))
133 if ($sourceDir !~ s|/[^/]+$||) {
134 die "Could not find top level webkit directory above source directory using FindBin.\n";
138 $sourceDir = "$sourceDir/OpenSource" if -d "$sourceDir/OpenSource";
141 sub currentPerlPath()
145 $thisPerl .= $Config{_exe} unless $thisPerl =~ m/$Config{_exe}$/i;
150 # used for scripts which are stored in a non-standard location
156 sub determineXcodeVersion
158 return if defined $xcodeVersion;
159 my $xcodebuildVersionOutput = `xcodebuild -version`;
160 $xcodeVersion = ($xcodebuildVersionOutput =~ /Xcode ([0-9](\.[0-9]+)*)/) ? $1 : "3.0";
163 sub readXcodeUserDefault($)
165 my ($unprefixedKey) = @_;
167 determineXcodeVersion();
169 my $xcodeDefaultsDomain = (eval "v$xcodeVersion" lt v4) ? "com.apple.Xcode" : "com.apple.dt.Xcode";
170 my $xcodeDefaultsPrefix = (eval "v$xcodeVersion" lt v4) ? "PBX" : "IDE";
171 my $devnull = File::Spec->devnull();
173 my $value = `defaults read $xcodeDefaultsDomain ${xcodeDefaultsPrefix}${unprefixedKey} 2> ${devnull}`;
180 sub determineBaseProductDir
182 return if defined $baseProductDir;
183 determineSourceDir();
185 my $setSharedPrecompsDir;
186 $baseProductDir = $ENV{"WEBKIT_OUTPUTDIR"};
188 if (!defined($baseProductDir) and isAppleMacWebKit()) {
189 # Silently remove ~/Library/Preferences/xcodebuild.plist which can
190 # cause build failure. The presence of
191 # ~/Library/Preferences/xcodebuild.plist can prevent xcodebuild from
192 # respecting global settings such as a custom build products directory
193 # (<rdar://problem/5585899>).
194 my $personalPlistFile = $ENV{HOME} . "/Library/Preferences/xcodebuild.plist";
195 if (-e $personalPlistFile) {
196 unlink($personalPlistFile) || die "Could not delete $personalPlistFile: $!";
199 determineXcodeVersion();
201 if (eval "v$xcodeVersion" ge v4) {
202 my $buildLocationStyle = join '', readXcodeUserDefault("BuildLocationStyle");
203 if ($buildLocationStyle eq "Custom") {
204 my $buildLocationType = join '', readXcodeUserDefault("CustomBuildLocationType");
205 # FIXME: Read CustomBuildIntermediatesPath and set OBJROOT accordingly.
206 $baseProductDir = readXcodeUserDefault("CustomBuildProductsPath") if $buildLocationType eq "Absolute";
209 # DeterminedByTargets corresponds to a setting of "Legacy" in Xcode.
210 # It is the only build location style for which SHARED_PRECOMPS_DIR is not
211 # overridden when building from within Xcode.
212 $setSharedPrecompsDir = 1 if $buildLocationStyle ne "DeterminedByTargets";
215 if (!defined($baseProductDir)) {
216 $baseProductDir = join '', readXcodeUserDefault("ApplicationwideBuildSettings");
217 $baseProductDir = $1 if $baseProductDir =~ /SYMROOT\s*=\s*\"(.*?)\";/s;
220 undef $baseProductDir unless $baseProductDir =~ /^\//;
223 if (!defined($baseProductDir)) { # Port-specific checks failed, use default
224 $baseProductDir = "$sourceDir/WebKitBuild";
227 if (isGit() && isGitBranchBuild()) {
228 my $branch = gitBranch();
229 $baseProductDir = "$baseProductDir/$branch";
232 if (isAppleMacWebKit()) {
233 $baseProductDir =~ s|^\Q$(SRCROOT)/..\E$|$sourceDir|;
234 $baseProductDir =~ s|^\Q$(SRCROOT)/../|$sourceDir/|;
235 $baseProductDir =~ s|^~/|$ENV{HOME}/|;
236 die "Can't handle Xcode product directory with a ~ in it.\n" if $baseProductDir =~ /~/;
237 die "Can't handle Xcode product directory with a variable in it.\n" if $baseProductDir =~ /\$/;
238 @baseProductDirOption = ("SYMROOT=$baseProductDir", "OBJROOT=$baseProductDir");
239 push(@baseProductDirOption, "SHARED_PRECOMPS_DIR=${baseProductDir}/PrecompiledHeaders") if $setSharedPrecompsDir;
243 my $dosBuildPath = `cygpath --windows \"$baseProductDir\"`;
245 $ENV{"WEBKIT_OUTPUTDIR"} = $dosBuildPath;
246 my $unixBuildPath = `cygpath --unix \"$baseProductDir\"`;
247 chomp $unixBuildPath;
248 $baseProductDir = $unixBuildPath;
252 sub setBaseProductDir($)
254 ($baseProductDir) = @_;
257 sub determineConfiguration
259 return if defined $configuration;
260 determineBaseProductDir();
261 if (open CONFIGURATION, "$baseProductDir/Configuration") {
262 $configuration = <CONFIGURATION>;
265 if ($configuration) {
266 chomp $configuration;
267 # compatibility for people who have old Configuration files
268 $configuration = "Release" if $configuration eq "Deployment";
269 $configuration = "Debug" if $configuration eq "Development";
271 $configuration = "Release";
274 if ($configuration && isWinCairo()) {
275 unless ($configuration =~ /_WinCairo$/) {
276 $configuration .= "_WinCairo";
281 sub determineArchitecture
283 return if defined $architecture;
284 # make sure $architecture is defined in all cases
287 determineBaseProductDir();
290 if (isGtkAutotools()) {
291 determineConfigurationProductDir();
292 my $host_triple = `grep -E '^host = ' $configurationProductDir/GNUmakefile 2> /dev/null`;
293 if ($host_triple =~ m/^host = ([^-]+)-/) {
294 # We have a configured build tree; use it.
297 } elsif (isAppleMacWebKit()) {
298 if (open ARCHITECTURE, "$baseProductDir/Architecture") {
299 $architecture = <ARCHITECTURE>;
305 if (not defined $xcodeSDK or $xcodeSDK =~ /^(\/$|macosx)/) {
306 my $supports64Bit = `sysctl -n hw.optional.x86_64`;
307 chomp $supports64Bit;
308 $architecture = 'x86_64' if $supports64Bit;
309 } elsif ($xcodeSDK =~ /^iphonesimulator/) {
310 $architecture = 'x86_64';
311 } elsif ($xcodeSDK =~ /^iphoneos/) {
312 $architecture = 'armv7';
315 } elsif (isEfl() || isGtkCMake()) {
316 my $host_processor = "";
317 $host_processor = `cmake --system-information | grep CMAKE_SYSTEM_PROCESSOR`;
318 if ($host_processor =~ m/^CMAKE_SYSTEM_PROCESSOR \"([^"]+)\"/) {
319 # We have a configured build tree; use it.
321 $architecture = 'x86_64' if $architecture eq 'amd64';
325 if (!$architecture && (isGtk() || isAppleMacWebKit() || isEfl())) {
326 # Fall back to output of `arch', if it is present.
327 $architecture = `arch`;
331 if (!$architecture && (isGtk() || isAppleMacWebKit() || isEfl())) {
332 # Fall back to output of `uname -m', if it is present.
333 $architecture = `uname -m`;
337 $architecture = 'x86_64' if ($architecture =~ /amd64/ && isBSD());
340 sub determineNumberOfCPUs
342 return if defined $numberOfCPUs;
343 if (defined($ENV{NUMBER_OF_PROCESSORS})) {
344 $numberOfCPUs = $ENV{NUMBER_OF_PROCESSORS};
345 } elsif (isLinux()) {
346 # First try the nproc utility, if it exists. If we get no
347 # results fall back to just interpretting /proc directly.
348 chomp($numberOfCPUs = `nproc --all 2> /dev/null`);
349 if ($numberOfCPUs eq "") {
350 $numberOfCPUs = (grep /processor/, `cat /proc/cpuinfo`);
352 } elsif (isWindows() || isCygwin()) {
354 $numberOfCPUs = `ls /proc/registry/HKEY_LOCAL_MACHINE/HARDWARE/DESCRIPTION/System/CentralProcessor | wc -w`;
355 } elsif (isDarwin() || isBSD()) {
356 chomp($numberOfCPUs = `sysctl -n hw.ncpu`);
360 sub determineMaxCPULoad
362 return if defined $maxCPULoad;
363 if (defined($ENV{MAX_CPU_LOAD})) {
364 $maxCPULoad = $ENV{MAX_CPU_LOAD};
370 my ($productDir) = @_;
372 $jscName .= "_debug" if configuration() eq "Debug_All";
373 $jscName .= ".exe" if (isWindows() || isCygwin());
374 return "$productDir/$jscName" if -e "$productDir/$jscName";
375 return "$productDir/JavaScriptCore.framework/Resources/$jscName";
378 sub argumentsForConfiguration()
380 determineConfiguration();
381 determineArchitecture();
384 push(@args, '--debug') if ($configuration =~ "^Debug");
385 push(@args, '--release') if ($configuration =~ "^Release");
386 push(@args, '--32-bit') if ($architecture ne "x86_64" and !isWin64());
387 push(@args, '--64-bit') if (isWin64());
388 push(@args, '--gtkautotools') if isGtkAutotools();
389 push(@args, '--gtk') if isGtkCMake();
390 push(@args, '--efl') if isEfl();
391 push(@args, '--wincairo') if isWinCairo();
392 push(@args, '--wince') if isWinCE();
393 push(@args, '--inspector-frontend') if isInspectorFrontend();
397 sub determineXcodeSDK
399 return if defined $xcodeSDK;
401 if (checkForArgumentAndRemoveFromARGVGettingValue("--sdk", \$sdk)) {
403 } elsif (checkForArgumentAndRemoveFromARGV("--device")) {
404 $xcodeSDK = 'iphoneos.internal';
405 } elsif (checkForArgumentAndRemoveFromARGV("--sim") ||
406 checkForArgumentAndRemoveFromARGV("--simulator")) {
407 $xcodeSDK = 'iphonesimulator';
417 sub xcodeSDKPlatformName()
420 return "" if !defined $xcodeSDK;
421 return "iphoneos" if $xcodeSDK =~ /iphoneos/i;
422 return "iphonesimulator" if $xcodeSDK =~ /iphonesimulator/i;
423 return "macosx" if $xcodeSDK =~ /macosx/i;
424 die "Couldn't determine platform name from Xcode SDK";
431 die "Can't find the SDK path because no Xcode SDK was specified" if not $xcodeSDK;
433 my $sdkPath = `xcrun --sdk $xcodeSDK --show-sdk-path` if $xcodeSDK;
434 die 'Failed to get SDK path from xcrun' if $?;
443 return $programFilesPath if defined $programFilesPath;
445 $programFilesPath = $ENV{'PROGRAMFILES(X86)'} || $ENV{'PROGRAMFILES'} || "C:\\Program Files";
447 return $programFilesPath;
450 sub visualStudioInstallDir
452 return $vsInstallDir if defined $vsInstallDir;
454 if ($ENV{'VSINSTALLDIR'}) {
455 $vsInstallDir = $ENV{'VSINSTALLDIR'};
456 $vsInstallDir =~ s|[\\/]$||;
458 $vsInstallDir = File::Spec->catdir(programFilesPath(), "Microsoft Visual Studio 12.0");
460 chomp($vsInstallDir = `cygpath "$vsInstallDir"`) if isCygwin();
462 return $vsInstallDir;
465 sub visualStudioVersion
467 return $vsVersion if defined $vsVersion;
469 my $installDir = visualStudioInstallDir();
471 $vsVersion = ($installDir =~ /Microsoft Visual Studio ([0-9]+\.[0-9]*)/) ? $1 : "12";
476 sub determineConfigurationForVisualStudio
478 return if defined $configurationForVisualStudio;
479 determineConfiguration();
480 # FIXME: We should detect when Debug_All or Production has been chosen.
481 $configurationForVisualStudio = $configuration . (isWin64() ? "|x64" : "|Win32");
484 sub usesPerConfigurationBuildDirectory
486 # [Gtk] We don't have Release/Debug configurations in straight
487 # autotool builds (non build-webkit). In this case and if
488 # WEBKIT_OUTPUTDIR exist, use that as our configuration dir. This will
489 # allows us to run run-webkit-tests without using build-webkit.
490 return ($ENV{"WEBKIT_OUTPUTDIR"} && isGtk()) || isAppleWinWebKit();
493 sub determineConfigurationProductDir
495 return if defined $configurationProductDir;
496 determineBaseProductDir();
497 determineConfiguration();
498 if (isAppleWinWebKit() || isWinCairo()) {
499 my $binDir = isWin64() ? "bin64" : "bin32";
500 $configurationProductDir = File::Spec->catdir($baseProductDir, $configuration, $binDir);
502 if (usesPerConfigurationBuildDirectory()) {
503 $configurationProductDir = "$baseProductDir";
505 $configurationProductDir = "$baseProductDir/$configuration";
506 $configurationProductDir .= "-" . xcodeSDKPlatformName() if isIOSWebKit();
511 sub setConfigurationProductDir($)
513 ($configurationProductDir) = @_;
516 sub determineCurrentSVNRevision
518 # We always update the current SVN revision here, and leave the caching
519 # to currentSVNRevision(), so that changes to the SVN revision while the
520 # script is running can be picked up by calling this function again.
521 determineSourceDir();
522 $currentSVNRevision = svnRevisionForDirectory($sourceDir);
523 return $currentSVNRevision;
529 determineSourceDir();
530 chdir $sourceDir or die;
535 determineBaseProductDir();
536 return $baseProductDir;
541 determineSourceDir();
547 determineConfigurationProductDir();
548 return $configurationProductDir;
553 my $productDir = productDir();
554 $productDir .= "/bin" if (isEfl() || isGtkCMake());
555 $productDir .= "/Programs" if isGtkAutotools();
562 determineConfiguration();
563 return $configuration;
566 sub configurationForVisualStudio()
568 determineConfigurationForVisualStudio();
569 return $configurationForVisualStudio;
572 sub currentSVNRevision
574 determineCurrentSVNRevision() if not defined $currentSVNRevision;
575 return $currentSVNRevision;
580 determineGenerateDsym();
581 return $generateDsym;
584 sub determineGenerateDsym()
586 return if defined($generateDsym);
587 $generateDsym = checkForArgumentAndRemoveFromARGV("--dsym");
590 sub argumentsForXcode()
593 push @args, "DEBUG_INFORMATION_FORMAT=dwarf-with-dsym" if generateDsym();
599 determineBaseProductDir();
600 determineConfiguration();
601 determineArchitecture();
604 my @sdkOption = ($xcodeSDK ? "SDKROOT=$xcodeSDK" : ());
605 my @architectureOption = ($architecture ? "ARCHS=$architecture" : ());
607 return (@baseProductDirOption, "-configuration", $configuration, @architectureOption, @sdkOption, argumentsForXcode());
610 sub XcodeOptionString
612 return join " ", XcodeOptions();
615 sub XcodeOptionStringNoConfig
617 return join " ", @baseProductDirOption;
620 sub XcodeCoverageSupportOptions()
622 my @coverageSupportOptions = ();
623 push @coverageSupportOptions, "GCC_GENERATE_TEST_COVERAGE_FILES=YES";
624 push @coverageSupportOptions, "GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES";
625 return @coverageSupportOptions;
628 my $passedConfiguration;
629 my $searchedForPassedConfiguration;
630 sub determinePassedConfiguration
632 return if $searchedForPassedConfiguration;
633 $searchedForPassedConfiguration = 1;
634 $passedConfiguration = undef;
636 if (checkForArgumentAndRemoveFromARGV("--debug")) {
637 $passedConfiguration = "Debug";
638 } elsif(checkForArgumentAndRemoveFromARGV("--release")) {
639 $passedConfiguration = "Release";
640 } elsif (checkForArgumentAndRemoveFromARGV("--profile") || checkForArgumentAndRemoveFromARGV("--profiling")) {
641 $passedConfiguration = "Profiling";
644 $passedConfiguration .= "_WinCairo" if (defined($passedConfiguration) && isWinCairo() && isCygwin());
647 sub passedConfiguration
649 determinePassedConfiguration();
650 return $passedConfiguration;
657 if (my $config = shift @_) {
658 $configuration = $config;
662 determinePassedConfiguration();
663 $configuration = $passedConfiguration if $passedConfiguration;
667 my $passedArchitecture;
668 my $searchedForPassedArchitecture;
669 sub determinePassedArchitecture
671 return if $searchedForPassedArchitecture;
672 $searchedForPassedArchitecture = 1;
674 $passedArchitecture = undef;
675 if (checkForArgumentAndRemoveFromARGV("--32-bit")) {
676 if (isAppleMacWebKit()) {
677 # PLATFORM_IOS: Don't run `arch` command inside Simulator environment
679 delete $ENV{DYLD_ROOT_PATH};
680 delete $ENV{DYLD_FRAMEWORK_PATH};
682 $passedArchitecture = `arch`;
683 chomp $passedArchitecture;
688 sub passedArchitecture
690 determinePassedArchitecture();
691 return $passedArchitecture;
696 determineArchitecture();
697 return $architecture;
702 determineNumberOfCPUs();
703 return $numberOfCPUs;
708 determineMaxCPULoad();
714 if (my $arch = shift @_) {
715 $architecture = $arch;
719 determinePassedArchitecture();
720 $architecture = $passedArchitecture if $passedArchitecture;
723 sub skipSafariExecutableEntitlementChecks
725 return `defaults read /Library/Preferences/org.webkit.BuildConfiguration SkipSafariExecutableEntitlementChecks 2>/dev/null` eq "1\n";
728 sub executableHasEntitlements
730 my $executablePath = shift;
731 return (`codesign -d --entitlements - $executablePath 2>&1` =~ /<key>/);
734 sub safariPathFromSafariBundle
736 my ($safariBundle) = @_;
738 if (isAppleMacWebKit()) {
739 my $safariPath = "$safariBundle/Contents/MacOS/Safari";
740 return $safariPath if skipSafariExecutableEntitlementChecks();
742 my $safariForWebKitDevelopmentPath = "$safariBundle/Contents/MacOS/SafariForWebKitDevelopment";
743 return $safariForWebKitDevelopmentPath if -f $safariForWebKitDevelopmentPath && executableHasEntitlements($safariPath);
747 return $safariBundle if isAppleWinWebKit();
750 sub installedSafariPath
754 if (isAppleMacWebKit()) {
755 $safariBundle = "/Applications/Safari.app";
756 } elsif (isAppleWinWebKit()) {
757 $safariBundle = readRegistryString("/HKLM/SOFTWARE/Apple Inc./Safari/InstallDir");
758 $safariBundle =~ s/[\r\n]+$//;
759 $safariBundle = `cygpath -u '$safariBundle'` if isCygwin();
760 $safariBundle =~ s/[\r\n]+$//;
761 $safariBundle .= "Safari.exe";
764 return safariPathFromSafariBundle($safariBundle);
770 # Use WEBKIT_SAFARI environment variable if present.
771 my $safariBundle = $ENV{WEBKIT_SAFARI};
772 if (!$safariBundle) {
773 determineConfigurationProductDir();
774 # Use Safari.app in product directory if present (good for Safari development team).
775 if (isAppleMacWebKit() && -d "$configurationProductDir/Safari.app") {
776 $safariBundle = "$configurationProductDir/Safari.app";
777 } elsif (isAppleWinWebKit()) {
778 my $path = "$configurationProductDir/Safari.exe";
779 my $debugPath = "$configurationProductDir/Safari_debug.exe";
781 if (configuration() eq "Debug_All" && -x $debugPath) {
782 $safariBundle = $debugPath;
784 $safariBundle = $path;
787 if (!$safariBundle) {
788 return installedSafariPath();
791 my $safariPath = safariPathFromSafariBundle($safariBundle);
792 die "Can't find executable at $safariPath.\n" if isAppleMacWebKit() && !-x $safariPath;
796 sub builtDylibPathForName
798 my $libraryName = shift;
799 determineConfigurationProductDir();
802 # WebKitGTK+ for GTK2, WebKitGTK+ for GTK3, and WebKit2 respectively.
803 my @libraries = ("libwebkitgtk-1.0", "libwebkitgtk-3.0", "libwebkit2gtk-3.0");
804 my $extension = isDarwin() ? ".dylib" : ".so";
806 my $builtLibraryPath = "$configurationProductDir/.libs/";
808 $builtLibraryPath = "$configurationProductDir/lib/";
811 foreach $libraryName (@libraries) {
812 my $libraryPath = "$builtLibraryPath" . $libraryName . $extension;
813 return $libraryPath if -e $libraryPath;
819 return "$configurationProductDir/lib/libewebkit2.so";
821 return "$configurationProductDir/lib/libewebkit.so";
824 return "$configurationProductDir/$libraryName";
827 return "$configurationProductDir/$libraryName.framework/$libraryName";
829 if (isAppleMacWebKit()) {
830 return "$configurationProductDir/$libraryName.framework/Versions/A/$libraryName";
832 if (isAppleWinWebKit()) {
833 if ($libraryName eq "JavaScriptCore") {
834 return "$baseProductDir/lib/$libraryName.lib";
836 return "$baseProductDir/$libraryName.intermediate/$configuration/$libraryName.intermediate/$libraryName.lib";
840 die "Unsupported platform, can't determine built library locations.\nTry `build-webkit --help` for more information.\n";
843 # Check to see that all the frameworks are built.
844 sub checkFrameworks # FIXME: This is a poor name since only the Mac calls built WebCore a Framework.
846 return if isCygwin() || isWindows();
847 my @frameworks = ("JavaScriptCore", "WebCore");
848 push(@frameworks, "WebKit") if isAppleMacWebKit(); # FIXME: This seems wrong, all ports should have a WebKit these days.
849 for my $framework (@frameworks) {
850 my $path = builtDylibPathForName($framework);
851 die "Can't find built framework at \"$path\".\n" unless -e $path;
855 sub isInspectorFrontend()
857 determineIsInspectorFrontend();
858 return $isInspectorFrontend;
861 sub determineIsInspectorFrontend()
863 return if defined($isInspectorFrontend);
864 $isInspectorFrontend = checkForArgumentAndRemoveFromARGV("--inspector-frontend");
870 my $devnull = File::Spec->devnull();
871 return `$command --version 2> $devnull`;
874 sub checkForArgumentAndRemoveFromARGV($)
876 my $argToCheck = shift;
877 return checkForArgumentAndRemoveFromArrayRef($argToCheck, \@ARGV);
880 sub checkForArgumentAndRemoveFromArrayRefGettingValue($$$)
882 my ($argToCheck, $valueRef, $arrayRef) = @_;
883 my $argumentStartRegEx = qr#^$argToCheck(?:=\S|$)#;
885 for (; $i < @$arrayRef; ++$i) {
886 last if $arrayRef->[$i] =~ $argumentStartRegEx;
888 if ($i >= @$arrayRef) {
889 return $$valueRef = undef;
891 my ($key, $value) = split("=", $arrayRef->[$i]);
892 splice(@$arrayRef, $i, 1);
893 if (defined($value)) {
894 # e.g. --sdk=iphonesimulator
895 return $$valueRef = $value;
897 return $$valueRef = splice(@$arrayRef, $i, 1); # e.g. --sdk iphonesimulator
900 sub checkForArgumentAndRemoveFromARGVGettingValue($$)
902 my ($argToCheck, $valueRef) = @_;
903 return checkForArgumentAndRemoveFromArrayRefGettingValue($argToCheck, $valueRef, \@ARGV);
906 sub findMatchingArguments($$)
908 my ($argToCheck, $arrayRef) = @_;
910 foreach my $index (0 .. $#$arrayRef) {
911 my $opt = $$arrayRef[$index];
912 if ($opt =~ /^$argToCheck$/i ) {
913 push(@matchingIndices, $index);
916 return @matchingIndices;
921 my ($argToCheck, $arrayRef) = @_;
922 my @matchingIndices = findMatchingArguments($argToCheck, $arrayRef);
923 return scalar @matchingIndices > 0;
926 sub checkForArgumentAndRemoveFromArrayRef
928 my ($argToCheck, $arrayRef) = @_;
929 my @indicesToRemove = findMatchingArguments($argToCheck, $arrayRef);
930 my $removeOffset = 0;
931 foreach my $index (@indicesToRemove) {
932 splice(@$arrayRef, $index - $removeOffset++, 1);
934 return scalar @indicesToRemove > 0;
939 if (defined($isWK2)) {
942 if (checkForArgumentAndRemoveFromARGV("-2")) {
952 return if defined($isEfl);
953 $isEfl = checkForArgumentAndRemoveFromARGV("--efl");
962 sub determineIsGtkCMake()
964 return if defined($isGtkCMake);
965 $isGtkCMake = checkForArgumentAndRemoveFromARGV("--gtk");
970 determineIsGtkCMake();
976 determineIsGtkAutotools();
977 return $isGtkAutotools;
982 return isGtkCMake() || isGtkAutotools();
985 sub determineIsGtkAutotools()
987 return if defined($isGtkAutotools);
988 $isGtkAutotools = checkForArgumentAndRemoveFromARGV("--gtkautotools");
997 sub determineIsWinCE()
999 return if defined($isWinCE);
1000 $isWinCE = checkForArgumentAndRemoveFromARGV("--wince");
1003 # Determine if this is debian, ubuntu, linspire, or something similar.
1006 return -e "/etc/debian_version";
1011 return -e "/etc/fedora-release";
1016 determineIsWinCairo();
1020 sub determineIsWinCairo()
1022 return if defined($isWinCairo);
1023 $isWinCairo = checkForArgumentAndRemoveFromARGV("--wincairo");
1032 sub determineIsWin64()
1034 return if defined($isWin64);
1035 $isWin64 = checkForArgumentAndRemoveFromARGV("--64-bit");
1040 return ($^O eq "cygwin") || 0;
1045 return isWindows() || isCygwin();
1048 sub determineWinVersion()
1050 return if $winVersion;
1052 if (!isAnyWindows()) {
1057 my $versionString = `cmd /c ver`;
1058 $versionString =~ /(\d)\.(\d)\.(\d+)/;
1069 determineWinVersion();
1075 return isAnyWindows() && winVersion()->{major} == 6 && winVersion()->{minor} == 1 && winVersion()->{build} == 7600;
1078 sub isWindowsVista()
1080 return isAnyWindows() && winVersion()->{major} == 6 && winVersion()->{minor} == 0;
1085 return isAnyWindows() && winVersion()->{major} == 5 && winVersion()->{minor} == 1;
1090 return ($^O eq "darwin") || 0;
1095 return ($^O eq "MSWin32") || 0;
1100 return ($^O eq "linux") || 0;
1105 return ($^O eq "freebsd") || ($^O eq "openbsd") || ($^O eq "netbsd") || 0;
1110 return ($Config{archname} =~ /^arm[v\-]/) || ($Config{archname} =~ /^aarch64[v\-]/);
1113 sub isCrossCompilation()
1116 $compiler = $ENV{'CC'} if (defined($ENV{'CC'}));
1117 if ($compiler =~ /gcc/) {
1118 my $compiler_options = `$compiler -v 2>&1`;
1119 my @host = $compiler_options =~ m/--host=(.*?)\s/;
1120 my @target = $compiler_options =~ m/--target=(.*?)\s/;
1122 return ($host[0] ne "" && $target[0] ne "" && $host[0] ne $target[0]);
1129 return isAppleMacWebKit() || isAppleWinWebKit();
1132 sub isAppleMacWebKit()
1134 return isDarwin() && !isGtk();
1137 sub isAppleWinWebKit()
1139 return (isCygwin() || isWindows()) && !isWinCairo() && !isGtk() && !isWinCE();
1142 sub willUseIOSDeviceSDKWhenBuilding()
1144 return xcodeSDKPlatformName() eq "iphoneos";
1147 sub willUseIOSSimulatorSDKWhenBuilding()
1149 return xcodeSDKPlatformName() eq "iphonesimulator";
1154 determineXcodeSDK();
1155 return isAppleMacWebKit() && (willUseIOSDeviceSDKWhenBuilding() || willUseIOSSimulatorSDKWhenBuilding());
1158 sub isPerianInstalled()
1160 if (!isAppleWebKit()) {
1164 if (-d "/Library/QuickTime/Perian.component") {
1168 if (-d "$ENV{HOME}/Library/QuickTime/Perian.component") {
1175 sub determineIPhoneSimulatorVersion()
1177 return if $iPhoneSimulatorVersion;
1179 if (!isIOSWebKit()) {
1180 $iPhoneSimulatorVersion = -1;
1184 my $version = `/usr/local/bin/psw_vers -productVersion`;
1185 my @splitVersion = split(/\./, $version);
1186 @splitVersion >= 2 or die "Invalid version $version";
1187 $iPhoneSimulatorVersion = {
1188 "major" => $splitVersion[0],
1189 "minor" => $splitVersion[1],
1190 "subminor" => defined($splitVersion[2] ? $splitVersion[2] : 0),
1194 sub iPhoneSimulatorVersion()
1196 determineIPhoneSimulatorVersion();
1197 return $iPhoneSimulatorVersion;
1200 sub determineNmPath()
1204 if (isAppleMacWebKit()) {
1205 $nmPath = `xcrun -find nm`;
1208 $nmPath = "nm" if !$nmPath;
1217 sub determineOSXVersion()
1219 return if $osXVersion;
1226 my $version = `sw_vers -productVersion`;
1227 my @splitVersion = split(/\./, $version);
1228 @splitVersion >= 2 or die "Invalid version $version";
1230 "major" => $splitVersion[0],
1231 "minor" => $splitVersion[1],
1232 "subminor" => (defined($splitVersion[2]) ? $splitVersion[2] : 0),
1238 determineOSXVersion();
1244 return isDarwin() && osXVersion()->{"minor"} == 6;
1249 return isDarwin() && osXVersion()->{"minor"} == 7;
1254 return $ENV{'OS'} eq 'Windows_NT';
1257 sub shouldTargetWebProcess
1259 determineShouldTargetWebProcess();
1260 return $shouldTargetWebProcess;
1263 sub determineShouldTargetWebProcess
1265 return if defined($shouldTargetWebProcess);
1266 $shouldTargetWebProcess = checkForArgumentAndRemoveFromARGV("--target-web-process");
1269 sub shouldUseXPCServiceForWebProcess
1271 determineShouldUseXPCServiceForWebProcess();
1272 return $shouldUseXPCServiceForWebProcess;
1275 sub determineShouldUseXPCServiceForWebProcess
1277 return if defined($shouldUseXPCServiceForWebProcess);
1278 $shouldUseXPCServiceForWebProcess = checkForArgumentAndRemoveFromARGV("--use-web-process-xpc-service");
1283 determineDebugger();
1287 sub determineDebugger
1289 return if defined($debugger);
1291 determineXcodeVersion();
1292 if (eval "v$xcodeVersion" ge v4.5) {
1298 if (checkForArgumentAndRemoveFromARGV("--use-lldb")) {
1302 if (checkForArgumentAndRemoveFromARGV("--use-gdb")) {
1307 sub appendToEnvironmentVariableList
1309 my ($environmentVariableName, $value) = @_;
1311 if (defined($ENV{$environmentVariableName})) {
1312 $ENV{$environmentVariableName} .= ":" . $value;
1314 $ENV{$environmentVariableName} = $value;
1318 sub setUpGuardMallocIfNeeded
1324 if (!defined($shouldUseGuardMalloc)) {
1325 $shouldUseGuardMalloc = checkForArgumentAndRemoveFromARGV("--guard-malloc");
1328 if ($shouldUseGuardMalloc) {
1329 appendToEnvironmentVariableList("DYLD_INSERT_LIBRARIES", "/usr/lib/libgmalloc.dylib");
1333 sub relativeScriptsDir()
1335 my $scriptDir = File::Spec->catpath("", File::Spec->abs2rel($FindBin::Bin, getcwd()), "");
1336 if ($scriptDir eq "") {
1344 my $relativeScriptsPath = relativeScriptsDir();
1345 if (isGtk() || isEfl() || isWinCE()) {
1346 return "$relativeScriptsPath/run-launcher";
1347 } elsif (isAppleWebKit()) {
1348 return "$relativeScriptsPath/run-safari";
1355 return "GtkLauncher";
1356 } elsif (isAppleMacWebKit()) {
1358 } elsif (isAppleWinWebKit()) {
1359 return "WinLauncher";
1361 return "EWebLauncher/MiniBrowser";
1362 } elsif (isWinCE()) {
1363 return "WinCELauncher";
1367 sub checkRequiredSystemConfig
1370 chomp(my $productVersion = `sw_vers -productVersion`);
1371 if (eval "v$productVersion" lt v10.7.5) {
1372 print "*************************************************************\n";
1373 print "Mac OS X Version 10.7.5 or later is required to build WebKit.\n";
1374 print "You have " . $productVersion . ", thus the build will most likely fail.\n";
1375 print "*************************************************************\n";
1377 my $xcodebuildVersionOutput = `xcodebuild -version`;
1378 my $xcodeVersion = ($xcodebuildVersionOutput =~ /Xcode ([0-9](\.[0-9]+)*)/) ? $1 : undef;
1379 if (!$xcodeVersion || $xcodeVersion && eval "v$xcodeVersion" lt v4.6) {
1380 print "*************************************************************\n";
1381 print "Xcode Version 4.6 or later is required to build WebKit.\n";
1382 print "You have an earlier version of Xcode, thus the build will\n";
1383 print "most likely fail. The latest Xcode is available from the App Store.\n";
1384 print "*************************************************************\n";
1386 } elsif (isGtk() or isEfl() or isWindows()) {
1387 my @cmds = qw(bison gperf flex);
1389 my $oldPath = $ENV{PATH};
1390 foreach my $cmd (@cmds) {
1391 push @missing, $cmd if not commandExists($cmd);
1395 my $list = join ", ", @missing;
1396 die "ERROR: $list missing but required to build WebKit.\n";
1399 # Win32 and other platforms may want to check for minimum config
1402 sub determineWindowsSourceDir()
1404 return if $windowsSourceDir;
1405 $windowsSourceDir = sourceDir();
1406 chomp($windowsSourceDir = `cygpath -w '$windowsSourceDir'`) if isCygwin();
1409 sub windowsSourceDir()
1411 determineWindowsSourceDir();
1412 return $windowsSourceDir;
1415 sub windowsSourceSourceDir()
1417 return windowsSourceDir() . "\\Source";
1420 sub windowsLibrariesDir()
1422 return windowsSourceDir() . "\\WebKitLibraries\\win";
1425 sub windowsOutputDir()
1427 return windowsSourceDir() . "\\WebKitBuild";
1433 my $val = system qw(regtool get), '\\HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\\' . $font . ' (TrueType)';
1437 sub checkInstalledTools()
1439 # SVN 1.7.10 is known to be compatible with current servers. SVN 1.8.x seems to be missing some authentication
1440 # protocols we use for svn.webkit.org:
1441 my $svnVersion = `svn --version | grep "\\sversion"`;
1443 if (!$? and $svnVersion =~ /1\.8\./) {
1444 print "svn 1.7.10 is known to be compatible with our servers. You are running $svnVersion,\nwhich may not work properly.\n"
1447 # Python 2.7.3 as shipped by Cygwin prevents the build from completing due to some issue with handling of
1448 # environment variables. Avoid until this is corrected.
1449 my $pythonVer = `python --version 2>&1`;
1450 die "You must have Python installed to build WebKit.\n" if ($?);
1451 die "Python 2.7.3 is not compatible with the WebKit build. Please downgrade to Python 2.6.8.\n" if ($pythonVer =~ /2\.7\.3/);
1453 # MathML requires fonts that do not ship with Windows (at least through Windows 8). Warn the user if they are missing
1454 my @fonts = qw(STIXGeneral-Regular MathJax_Main-Regular);
1456 foreach my $font (@fonts) {
1457 push @missing, $font if not fontExists($font);
1460 if (scalar @missing > 0) {
1461 print "*************************************************************\n";
1462 print "Mathematical fonts, such as STIX and MathJax, are needed to\n";
1463 print "use the MathML feature. You do not appear to have these fonts\n";
1464 print "on your system.\n\n";
1465 print "You can download a suitable set of fonts from the following URL:\n";
1466 print "https://developer.mozilla.org/Mozilla/MathML_Projects/Fonts\n";
1467 print "*************************************************************\n";
1470 print "Installed tools are correct for the WebKit build.\n";
1473 sub setupAppleWinEnv()
1475 return unless isAppleWinWebKit();
1477 checkInstalledTools();
1479 if (isWindowsNT()) {
1480 my $restartNeeded = 0;
1481 my %variablesToSet = ();
1483 # FIXME: We should remove this explicit version check for cygwin once we stop supporting Cygwin 1.7.9 or older versions.
1484 # https://bugs.webkit.org/show_bug.cgi?id=85791
1485 my $uname_version = (POSIX::uname())[2];
1486 $uname_version =~ s/\(.*\)//; # Remove the trailing cygwin version, if any.
1487 if (version->parse($uname_version) < version->parse("1.7.10")) {
1488 # Setting the environment variable 'CYGWIN' to 'tty' makes cygwin enable extra support (i.e., termios)
1489 # for UNIX-like ttys in the Windows console
1490 $variablesToSet{CYGWIN} = "tty" unless $ENV{CYGWIN};
1493 # Those environment variables must be set to be able to build inside Visual Studio.
1494 $variablesToSet{WEBKIT_LIBRARIES} = windowsLibrariesDir() unless $ENV{WEBKIT_LIBRARIES};
1495 $variablesToSet{WEBKIT_OUTPUTDIR} = windowsOutputDir() unless $ENV{WEBKIT_OUTPUTDIR};
1496 $variablesToSet{MSBUILDDISABLENODEREUSE} = "1" unless $ENV{MSBUILDDISABLENODEREUSE};
1498 foreach my $variable (keys %variablesToSet) {
1499 print "Setting the Environment Variable '" . $variable . "' to '" . $variablesToSet{$variable} . "'\n\n";
1500 system qw(regtool -s set), '\\HKEY_CURRENT_USER\\Environment\\' . $variable, $variablesToSet{$variable};
1501 $restartNeeded ||= $variable eq "WEBKIT_LIBRARIES" || $variable eq "WEBKIT_OUTPUTDIR";
1504 if ($restartNeeded) {
1505 print "Please restart your computer before attempting to build inside Visual Studio.\n\n";
1508 if (!defined $ENV{'WEBKIT_LIBRARIES'} || !$ENV{'WEBKIT_LIBRARIES'}) {
1509 print "Warning: You must set the 'WebKit_Libraries' environment variable\n";
1510 print " to be able build WebKit from within Visual Studio 2013 and newer.\n";
1511 print " Make sure that 'WebKit_Libraries' points to the\n";
1512 print " 'WebKitLibraries/win' directory, not the 'WebKitLibraries/' directory.\n\n";
1514 if (!defined $ENV{'WEBKIT_OUTPUTDIR'} || !$ENV{'WEBKIT_OUTPUTDIR'}) {
1515 print "Warning: You must set the 'WebKit_OutputDir' environment variable\n";
1516 print " to be able build WebKit from within Visual Studio 2013 and newer.\n\n";
1518 if (!defined $ENV{'MSBUILDDISABLENODEREUSE'} || !$ENV{'MSBUILDDISABLENODEREUSE'}) {
1519 print "Warning: You should set the 'MSBUILDDISABLENODEREUSE' environment variable to '1'\n";
1520 print " to avoid periodic locked log files when building.\n\n";
1523 # FIXME (125180): Remove the following temporary 64-bit support once official support is available.
1524 if (isWin64() and !$ENV{'WEBKIT_64_SUPPORT'}) {
1525 print "Warning: You must set the 'WEBKIT_64_SUPPORT' environment variable\n";
1526 print " to be able run WebKit or JavaScriptCore tests.\n\n";
1530 sub setupCygwinEnv()
1532 return if !isCygwin() && !isWindows();
1533 return if $vcBuildPath;
1535 my $programFilesPath = programFilesPath();
1536 $vcBuildPath = File::Spec->catfile(visualStudioInstallDir(), qw(Common7 IDE devenv.com));
1537 if (-e $vcBuildPath) {
1538 # Visual Studio is installed;
1539 if (visualStudioVersion() eq "12") {
1540 $vcBuildPath = File::Spec->catfile(visualStudioInstallDir(), qw(Common7 IDE devenv.exe));
1543 # Visual Studio not found, try VC++ Express
1544 $vcBuildPath = File::Spec->catfile(visualStudioInstallDir(), qw(Common7 IDE WDExpress.exe));
1545 if (! -e $vcBuildPath) {
1546 print "*************************************************************\n";
1547 print "Cannot find '$vcBuildPath'\n";
1548 print "Please execute the file 'vcvars32.bat' from\n";
1549 print "'$programFilesPath\\Microsoft Visual Studio 12.0\\VC\\bin\\'\n";
1550 print "to setup the necessary environment variables.\n";
1551 print "*************************************************************\n";
1554 $willUseVCExpressWhenBuilding = 1;
1557 print "Building results into: ", baseProductDir(), "\n";
1558 print "WEBKIT_OUTPUTDIR is set to: ", $ENV{"WEBKIT_OUTPUTDIR"}, "\n";
1559 print "WEBKIT_LIBRARIES is set to: ", $ENV{"WEBKIT_LIBRARIES"}, "\n";
1560 # FIXME (125180): Remove the following temporary 64-bit support once official support is available.
1561 print "WEBKIT_64_SUPPORT is set to: ", $ENV{"WEBKIT_64_SUPPORT"}, "\n" if isWin64();
1564 sub dieIfWindowsPlatformSDKNotInstalled
1566 my $registry32Path = "/proc/registry/";
1567 my $registry64Path = "/proc/registry64/";
1568 my @windowsPlatformSDKRegistryEntries = (
1569 "HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Microsoft SDKs/Windows/v8.0A",
1570 "HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Microsoft SDKs/Windows/v8.0",
1571 "HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Microsoft SDKs/Windows/v7.1A",
1572 "HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Microsoft SDKs/Windows/v7.0A",
1573 "HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/MicrosoftSDK/InstalledSDKs/D2FF9F89-8AA2-4373-8A31-C838BF4DBBE1",
1576 # FIXME: It would be better to detect whether we are using 32- or 64-bit Windows
1577 # and only check the appropriate entry. But for now we just blindly check both.
1578 my $recommendedPlatformSDK = $windowsPlatformSDKRegistryEntries[0];
1580 while (@windowsPlatformSDKRegistryEntries) {
1581 my $windowsPlatformSDKRegistryEntry = shift @windowsPlatformSDKRegistryEntries;
1582 return if (-e $registry32Path . $windowsPlatformSDKRegistryEntry) || (-e $registry64Path . $windowsPlatformSDKRegistryEntry);
1585 print "*************************************************************\n";
1586 print "Cannot find registry entry '$recommendedPlatformSDK'.\n";
1587 print "Please download and install the Microsoft Windows SDK\n";
1588 print "from <http://www.microsoft.com/en-us/download/details.aspx?id=8279>.\n\n";
1589 print "Then follow step 2 in the Windows section of the \"Installing Developer\n";
1590 print "Tools\" instructions at <http://www.webkit.org/building/tools.html>.\n";
1591 print "*************************************************************\n";
1595 sub copyInspectorFrontendFiles
1597 my $productDir = productDir();
1598 my $sourceInspectorPath = sourceDir() . "/Source/WebCore/inspector/front-end/";
1599 my $inspectorResourcesDirPath = $ENV{"WEBKITINSPECTORRESOURCESDIR"};
1601 if (!defined($inspectorResourcesDirPath)) {
1602 $inspectorResourcesDirPath = "";
1605 if (isAppleMacWebKit()) {
1606 if (isIOSWebKit()) {
1607 $inspectorResourcesDirPath = $productDir . "/WebCore.framework/inspector";
1609 $inspectorResourcesDirPath = $productDir . "/WebCore.framework/Resources/inspector";
1611 } elsif (isAppleWinWebKit() || isWinCairo()) {
1612 $inspectorResourcesDirPath = $productDir . "/WebKit.resources/inspector";
1614 my $prefix = $ENV{"WebKitInstallationPrefix"};
1615 $inspectorResourcesDirPath = (defined($prefix) ? $prefix : "/usr/share") . "/webkit-1.0/webinspector";
1617 my $prefix = $ENV{"WebKitInstallationPrefix"};
1618 $inspectorResourcesDirPath = (defined($prefix) ? $prefix : "/usr/share") . "/ewebkit/webinspector";
1621 if (! -d $inspectorResourcesDirPath) {
1622 print "*************************************************************\n";
1623 print "Cannot find '$inspectorResourcesDirPath'.\n" if (defined($inspectorResourcesDirPath));
1624 print "Make sure that you have built WebKit first.\n" if (! -d $productDir || defined($inspectorResourcesDirPath));
1625 print "Optionally, set the environment variable 'WebKitInspectorResourcesDir'\n";
1626 print "to point to the directory that contains the WebKit Inspector front-end\n";
1627 print "files for the built WebCore framework.\n";
1628 print "*************************************************************\n";
1632 if (isAppleMacWebKit()) {
1633 my $sourceLocalizedStrings = sourceDir() . "/Source/WebCore/English.lproj/localizedStrings.js";
1634 my $destinationLocalizedStrings;
1635 if (isIOSWebKit()) {
1636 $destinationLocalizedStrings = $productDir . "/WebCore.framework/English.lproj/localizedStrings.js";
1638 $destinationLocalizedStrings = $productDir . "/WebCore.framework/Resources/English.lproj/localizedStrings.js";
1640 system "ditto", $sourceLocalizedStrings, $destinationLocalizedStrings;
1643 my $exitStatus = system "rsync", "-aut", "--exclude=/.DS_Store", "--exclude=*.re2js", "--exclude=.svn/", $sourceInspectorPath, $inspectorResourcesDirPath;
1644 return $exitStatus if $exitStatus;
1646 if (isIOSWebKit()) {
1647 chdir($productDir . "/WebCore.framework");
1648 return system "zip", "--quiet", "--exclude=*.qrc", "-r", "inspector-remote.zip", "inspector";
1651 return 0; # Success; did copy files.
1654 sub buildXCodeProject($$@)
1656 my ($project, $clean, @extraOptions) = @_;
1659 push(@extraOptions, "-alltargets");
1660 push(@extraOptions, "clean");
1663 return system "xcodebuild", "-project", "$project.xcodeproj", @extraOptions;
1666 sub usingVisualStudioExpress()
1669 return $willUseVCExpressWhenBuilding;
1672 sub buildVisualStudioProject
1674 my ($project, $clean) = @_;
1677 my $config = configurationForVisualStudio();
1679 dieIfWindowsPlatformSDKNotInstalled() if $willUseVCExpressWhenBuilding;
1681 chomp($project = `cygpath -w "$project"`) if isCygwin();
1683 my $action = "/build";
1688 my @command = ($vcBuildPath, $project, $action, $config);
1690 print join(" ", @command), "\n";
1691 return system @command;
1694 sub autotoolsFlag($$)
1696 my ($flag, $feature) = @_;
1697 my $prefix = $flag ? "--enable" : "--disable";
1699 return $prefix . '-' . $feature;
1702 sub runAutogenForAutotoolsProjectIfNecessary($@)
1704 my ($dir, $prefix, $sourceDir, $project, $joinedOverridableFeatures, @buildArgs) = @_;
1706 # Always enable introspection when building WebKitGTK+.
1707 unshift(@buildArgs, "--enable-introspection");
1709 # Also, always enable developer mode for developer/test builds.
1710 unshift(@buildArgs, "--enable-developer-mode");
1712 # Optimize for running WebKit inside the build tree
1713 unshift(@buildArgs, "--disable-fast-install");
1715 my $joinedBuildArgs = join(" ", @buildArgs);
1717 if (-e "GNUmakefile") {
1718 # Just assume that build-jsc will never be used to reconfigure JSC. Later
1719 # we can go back and make this more complicated if the demand is there.
1720 if ($project ne "WebKit") {
1724 # Run autogen.sh again if either the features overrided by build-webkit or build arguments have changed.
1725 if (!isCachedArgumentfileOutOfDate("WebKitFeatureOverrides.txt", $joinedOverridableFeatures)
1726 && !isCachedArgumentfileOutOfDate("previous-autogen-arguments.txt", $joinedBuildArgs)) {
1731 print "Calling autogen.sh in " . $dir . "\n\n";
1732 print "Installation prefix directory: $prefix\n" if(defined($prefix));
1734 # Only for WebKit, write the autogen.sh arguments to a file so that we can detect
1735 # when they change and automatically re-run it.
1736 if ($project eq 'WebKit') {
1737 open(OVERRIDABLE_FEATURES, ">WebKitFeatureOverrides.txt");
1738 print OVERRIDABLE_FEATURES $joinedOverridableFeatures;
1739 close(OVERRIDABLE_FEATURES);
1741 open(AUTOTOOLS_ARGUMENTS, ">previous-autogen-arguments.txt");
1742 print AUTOTOOLS_ARGUMENTS $joinedBuildArgs;
1743 close(AUTOTOOLS_ARGUMENTS);
1746 # Make the path relative since it will appear in all -I compiler flags.
1747 # Long argument lists cause bizarre slowdowns in libtool.
1748 my $relSourceDir = File::Spec->abs2rel($sourceDir) || ".";
1750 # Compiler options to keep floating point values consistent
1751 # between 32-bit and 64-bit architectures. The options are also
1752 # used on Chromium build.
1753 determineArchitecture();
1754 if ($architecture ne "x86_64" && !isARM() && !isCrossCompilation()) {
1755 $ENV{'CXXFLAGS'} = "-march=pentium4 -msse2 -mfpmath=sse " . ($ENV{'CXXFLAGS'} || "");
1758 # Prefix the command with jhbuild run.
1759 unshift(@buildArgs, "$relSourceDir/autogen.sh");
1760 unshift(@buildArgs, jhbuildWrapperPrefixIfNeeded());
1761 if (system(@buildArgs) ne 0) {
1762 die "Calling autogen.sh failed!\n";
1766 sub getJhbuildPath()
1768 my @jhbuildPath = File::Spec->splitdir(baseProductDir());
1769 if (isGit() && isGitBranchBuild() && gitBranch()) {
1772 push(@jhbuildPath, "Dependencies");
1773 return File::Spec->catdir(@jhbuildPath);
1776 sub isCachedArgumentfileOutOfDate($@)
1778 my ($filename, $currentContents) = @_;
1780 if (! -e $filename) {
1784 open(CONTENTS_FILE, $filename);
1785 chomp(my $previousContents = <CONTENTS_FILE>);
1786 close(CONTENTS_FILE);
1788 if ($previousContents ne $currentContents) {
1789 print "Contents for file $filename have changed.\n";
1790 print "Previous contents were: $previousContents\n\n";
1791 print "New contents are: $currentContents\n";
1798 sub buildAutotoolsProject($@)
1800 my ($project, $clean, $prefix, $makeArgs, $noWebKit1, $noWebKit2, @features) = @_;
1802 my $make = $ENV{'MAKE'} //= 'make';
1803 my $dir = productDir();
1804 my $config = passedConfiguration() || configuration();
1806 # Use rm to clean the build directory since distclean may miss files
1807 if ($clean && -d $dir) {
1808 system "rm", "-rf", "$dir";
1812 File::Path::mkpath($dir) or die "Failed to create build directory " . $dir
1814 chdir $dir or die "Failed to cd into " . $dir . "\n";
1820 my @buildArgs = @ARGV;
1822 unshift(@buildArgs, "--disable-webkit1");
1825 unshift(@buildArgs, "--disable-webkit2");
1828 # Configurable features listed here should be kept in sync with the
1829 # features for which there exists a configuration option in configure.ac.
1830 my %configurableFeatures = (
1831 "battery-status" => 1,
1841 # These features are ones which build-webkit cannot control, typically because
1842 # they can only be active when we have the proper dependencies.
1843 my %unsetFeatures = (
1844 "accelerated-2d-canvas" => 1,
1847 my @overridableFeatures = ();
1848 foreach (@features) {
1849 if ($configurableFeatures{$_->{option}}) {
1850 push @buildArgs, autotoolsFlag(${$_->{value}}, $_->{option});;
1851 } elsif (!$unsetFeatures{$_->{option}}) {
1852 push @overridableFeatures, $_->{define} . "=" . (${$_->{value}} ? "1" : "0");
1856 $makeArgs = $makeArgs || "";
1857 $makeArgs = $makeArgs . " " . $ENV{"WebKitMakeArguments"} if $ENV{"WebKitMakeArguments"};
1859 # Automatically determine the number of CPUs for make only
1860 # if make arguments haven't already been specified.
1861 if ($makeArgs eq "") {
1862 $makeArgs = "-j" . numberOfCPUs();
1865 # WebKit is the default target, so we don't need to specify anything.
1866 if ($project eq "JavaScriptCore") {
1867 $makeArgs .= " jsc";
1868 } elsif ($project eq "WTF") {
1869 $makeArgs .= " libWTF.la";
1872 $prefix = $ENV{"WebKitInstallationPrefix"} if !defined($prefix);
1873 push @buildArgs, "--prefix=" . $prefix if defined($prefix);
1875 # Check if configuration is Debug.
1876 my $debug = $config =~ m/debug/i;
1878 push @buildArgs, "--enable-debug";
1880 push @buildArgs, "--disable-debug";
1883 if (checkForArgumentAndRemoveFromArrayRef("--update-gtk", \@buildArgs)) {
1884 # Force autogen to run, to catch the possibly updated libraries.
1885 system("rm -f previous-autogen-arguments.txt");
1887 system("perl", "$sourceDir/Tools/Scripts/update-webkitgtk-libs") == 0 or die $!;
1890 # If GNUmakefile exists, don't run autogen.sh unless its arguments
1891 # have changed. The makefile should be smart enough to track autotools
1892 # dependencies and re-run autogen.sh when build files change.
1893 my $joinedOverridableFeatures = join(" ", @overridableFeatures);
1894 runAutogenForAutotoolsProjectIfNecessary($dir, $prefix, $sourceDir, $project, $joinedOverridableFeatures, @buildArgs);
1896 my $runWithJhbuild = join(" ", jhbuildWrapperPrefixIfNeeded());
1897 if (system("$runWithJhbuild $make $makeArgs") ne 0) {
1898 die "\nFailed to build WebKit using '$make'!\n";
1903 if (!checkForArgumentAndRemoveFromARGV("--disable-gtk-doc")) {
1904 if ($project eq 'WebKit' && !isCrossCompilation() && !($noWebKit1 && $noWebKit2)) {
1905 my @docGenerationOptions = ("$sourceDir/Tools/gtk/generate-gtkdoc", "--skip-html");
1906 unshift(@docGenerationOptions, jhbuildWrapperPrefixIfNeeded());
1908 if (system(@docGenerationOptions)) {
1909 die "\n gtkdoc did not build without warnings\n";
1917 sub jhbuildWrapperPrefixIfNeeded()
1919 if (-e getJhbuildPath()) {
1920 my @prefix = (File::Spec->catfile(sourceDir(), "Tools", "jhbuild", "jhbuild-wrapper"));
1922 push(@prefix, "--efl");
1924 push(@prefix, "--gtk");
1926 push(@prefix, "run");
1934 sub cmakeCachePath()
1936 return File::Spec->catdir(baseProductDir(), configuration(), "CMakeCache.txt");
1939 sub shouldRemoveCMakeCache(@)
1941 my ($cacheFilePath, @buildArgs) = @_;
1950 # We check this first, because we always want to create this file for a fresh build.
1951 my $productDir = File::Spec->catdir(baseProductDir(), configuration());
1952 my $optionsCache = File::Spec->catdir($productDir, "build-webkit-options.txt");
1953 my $joinedBuildArgs = join(" ", @buildArgs);
1954 if (isCachedArgumentfileOutOfDate($optionsCache, $joinedBuildArgs)) {
1955 File::Path::mkpath($productDir) unless -d $productDir;
1956 open(CACHED_ARGUMENTS, ">", $optionsCache);
1957 print CACHED_ARGUMENTS $joinedBuildArgs;
1958 close(CACHED_ARGUMENTS);
1963 my $cmakeCache = cmakeCachePath();
1964 unless (-e $cmakeCache) {
1968 my $cacheFileModifiedTime = stat($cmakeCache)->mtime;
1969 my $platformConfiguration = File::Spec->catdir(sourceDir(), "Source", "cmake", "Options" . cmakeBasedPortName() . ".cmake");
1970 if ($cacheFileModifiedTime < stat($platformConfiguration)->mtime) {
1974 my $globalConfiguration = File::Spec->catdir(sourceDir(), "Source", "cmake", "OptionsCommon.cmake");
1975 if ($cacheFileModifiedTime < stat($globalConfiguration)->mtime) {
1982 sub removeCMakeCache(@)
1984 my (@buildArgs) = @_;
1985 if (shouldRemoveCMakeCache(@buildArgs)) {
1986 my $cmakeCache = cmakeCachePath();
1987 unlink($cmakeCache) if -e $cmakeCache;
1993 # Test both ninja and ninja-build. Fedora uses ninja-build and has patched CMake to also call ninja-build.
1994 system('which ninja > /dev/null || which ninja-build > /dev/null');
1998 sub cmakeGeneratedBuildfile(@)
2000 my ($willUseNinja) = @_;
2001 if ($willUseNinja) {
2002 return File::Spec->catfile(baseProductDir(), configuration(), "build.ninja")
2004 return File::Spec->catfile(baseProductDir(), configuration(), "Makefile")
2008 sub generateBuildSystemFromCMakeProject
2010 my ($port, $prefixPath, @cmakeArgs, $additionalCMakeArgs) = @_;
2011 my $config = configuration();
2012 my $buildPath = File::Spec->catdir(baseProductDir(), $config);
2013 File::Path::mkpath($buildPath) unless -d $buildPath;
2014 my $originalWorkingDirectory = getcwd();
2015 chdir($buildPath) or die;
2017 # For GTK+ we try to be smart about when to rerun cmake, so that we can have faster incremental builds.
2018 my $willUseNinja = isGtk() && canUseNinja();
2019 if (isGtk() && -e cmakeCachePath() && -e cmakeGeneratedBuildfile($willUseNinja)) {
2024 push @args, "-DPORT=\"$port\"";
2025 push @args, "-DCMAKE_INSTALL_PREFIX=\"$prefixPath\"" if $prefixPath;
2026 push @args, "-DSHARED_CORE=ON" if isEfl() && $ENV{"ENABLE_DRT"};
2027 if ($config =~ /release/i) {
2028 push @args, "-DCMAKE_BUILD_TYPE=Release";
2029 } elsif ($config =~ /debug/i) {
2030 push @args, "-DCMAKE_BUILD_TYPE=Debug";
2033 if ($willUseNinja) {
2035 push @args, "Ninja";
2038 # Don't warn variables which aren't used by cmake ports.
2039 push @args, "--no-warn-unused-cli";
2040 push @args, @cmakeArgs if @cmakeArgs;
2041 push @args, $additionalCMakeArgs if $additionalCMakeArgs;
2043 push @args, '"' . sourceDir() . '"';
2045 # Compiler options to keep floating point values consistent
2046 # between 32-bit and 64-bit architectures.
2047 determineArchitecture();
2048 if ($architecture ne "x86_64" && !isARM() && !isCrossCompilation()) {
2049 $ENV{'CXXFLAGS'} = "-march=pentium4 -msse2 -mfpmath=sse " . ($ENV{'CXXFLAGS'} || "");
2052 # We call system("cmake @args") instead of system("cmake", @args) so that @args is
2053 # parsed for shell metacharacters.
2054 my $wrapper = join(" ", jhbuildWrapperPrefixIfNeeded()) . " ";
2055 my $returnCode = system($wrapper . "cmake @args");
2057 chdir($originalWorkingDirectory);
2061 sub buildCMakeGeneratedProject($)
2063 my ($makeArgs) = @_;
2064 my $config = configuration();
2065 my $buildPath = File::Spec->catdir(baseProductDir(), $config);
2066 if (! -d $buildPath) {
2067 die "Must call generateBuildSystemFromCMakeProject() before building CMake project.";
2070 my $command = "cmake";
2071 my @args = ("--build", $buildPath, "--config", $config);
2072 push @args, ("--", $makeArgs) if $makeArgs;
2074 # GTK uses a build script to preserve colors and pretty-printing.
2076 chdir "$buildPath" or die;
2077 $command = "$buildPath/build.sh";
2078 @args = ($makeArgs);
2081 # We call system("cmake @args") instead of system("cmake", @args) so that @args is
2082 # parsed for shell metacharacters. In particular, $makeArgs may contain such metacharacters.
2083 my $wrapper = join(" ", jhbuildWrapperPrefixIfNeeded()) . " ";
2084 return system($wrapper . "$command @args");
2088 sub cleanCMakeGeneratedProject()
2090 my $config = configuration();
2091 my $buildPath = File::Spec->catdir(baseProductDir(), $config);
2092 if (-d $buildPath) {
2093 return system("cmake", "--build", $buildPath, "--config", $config, "--target", "clean");
2098 sub buildCMakeProjectOrExit($$$$@)
2100 my ($clean, $port, $prefixPath, $makeArgs, @cmakeArgs) = @_;
2103 exit(exitStatus(cleanCMakeGeneratedProject())) if $clean;
2105 if (isEfl() && checkForArgumentAndRemoveFromARGV("--update-efl")) {
2106 system("perl", "$sourceDir/Tools/Scripts/update-webkitefl-libs") == 0 or die $!;
2109 if (isGtk() && checkForArgumentAndRemoveFromARGV("--update-gtk")) {
2110 system("perl", "$sourceDir/Tools/Scripts/update-webkitgtk-libs") == 0 or die $!;
2113 $returnCode = exitStatus(generateBuildSystemFromCMakeProject($port, $prefixPath, @cmakeArgs));
2114 exit($returnCode) if $returnCode;
2116 $returnCode = exitStatus(buildCMakeGeneratedProject($makeArgs));
2117 exit($returnCode) if $returnCode;
2121 sub cmakeBasedPortArguments()
2123 return ('-G "Visual Studio 8 2005 STANDARDSDK_500 (ARMV4I)"') if isWinCE();
2127 sub cmakeBasedPortName()
2129 return "Efl" if isEfl();
2130 return "WinCE" if isWinCE();
2131 return "GTK" if isGtkCMake();
2137 return isEfl() || isWinCE() || isGtkCMake();
2142 my ($prompt, $default) = @_;
2143 my $defaultValue = $default ? "[$default]" : "";
2144 print "$prompt $defaultValue: ";
2145 chomp(my $input = <STDIN>);
2146 return $input ? $input : $default;
2151 my ($project, $clean, $prefix, $makeArgs, $noWebKit1, $noWebKit2, @features) = @_;
2153 if ($project ne "WebKit" and $project ne "JavaScriptCore" and $project ne "WTF") {
2154 die "Unsupported project: $project. Supported projects: WebKit, JavaScriptCore, WTF\n";
2157 return buildAutotoolsProject($project, $clean, $prefix, $makeArgs, $noWebKit1, $noWebKit2, @features);
2160 sub appleApplicationSupportPath
2163 # FIXME (125180): Remove the following once official 64-bit Windows support is available.
2164 return $ENV{"WEBKIT_64_SUPPORT"}, "\n" if isWin64();
2167 open INSTALL_DIR, "</proc/registry/HKEY_LOCAL_MACHINE/SOFTWARE/Apple\ Inc./Apple\ Application\ Support/InstallDir";
2168 my $path = <INSTALL_DIR>;
2169 $path =~ s/[\r\n\x00].*//;
2172 my $unixPath = `cygpath -u '$path'`;
2177 sub setPathForRunningWebKitApp
2181 if (isAppleWinWebKit()) {
2182 $env->{PATH} = join(':', productDir(), dirname(installedSafariPath()), appleApplicationSupportPath(), $env->{PATH} || "");
2183 } elsif (isWinCairo()) {
2184 my $winCairoBin = sourceDir() . "/WebKitLibraries/win/" . (isWin64() ? "bin64/" : "bin32/");
2185 my $gstreamerBin = isWin64() ? $ENV{"GSTREAMER_1_0_ROOT_X86_64"} . "bin" : $ENV{"GSTREAMER_1_0_ROOT_X86"} . "bin";
2186 $env->{PATH} = join(':', productDir(), $winCairoBin, $gstreamerBin, $env->{PATH} || "");
2190 sub printHelpAndExitForRunAndDebugWebKitAppIfNeeded
2192 return unless checkForArgumentAndRemoveFromARGV("--help");
2194 my ($includeOptionsForDebugging) = @_;
2197 Usage: @{[basename($0)]} [options] [args ...]
2198 --help Show this help message
2199 --no-saved-state Launch the application without state restoration (OS X 10.7 and later)
2200 --guard-malloc Enable Guard Malloc (OS X only)
2201 --use-web-process-xpc-service Launch the Web Process as an XPC Service (OS X only)
2204 if ($includeOptionsForDebugging) {
2206 --target-web-process Debug the web process
2207 --use-gdb Use GDB (this is the default when using Xcode 4.4 or earlier)
2208 --use-lldb Use LLDB (this is the default when using Xcode 4.5 or later)
2215 sub argumentsForRunAndDebugMacWebKitApp()
2218 if (checkForArgumentAndRemoveFromARGV("--no-saved-state")) {
2219 push @args, ("-ApplePersistenceIgnoreStateQuietly", "YES");
2220 # FIXME: Don't set ApplePersistenceIgnoreState once all supported OS versions respect ApplePersistenceIgnoreStateQuietly (rdar://15032886).
2221 push @args, ("-ApplePersistenceIgnoreState", "YES");
2223 push @args, ("-WebKit2UseXPCServiceForWebProcess", "YES") if shouldUseXPCServiceForWebProcess();
2224 unshift @args, @ARGV;
2229 sub runMacWebKitApp($;$)
2231 my ($appPath, $useOpenCommand) = @_;
2232 my $productDir = productDir();
2233 print "Starting @{[basename($appPath)]} with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
2234 $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
2235 $ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES";
2237 setUpGuardMallocIfNeeded();
2239 if (defined($useOpenCommand) && $useOpenCommand == USE_OPEN_COMMAND) {
2240 return system("open", "-W", "-a", $appPath, "--args", argumentsForRunAndDebugMacWebKitApp());
2242 if (architecture()) {
2243 return system "arch", "-" . architecture(), $appPath, argumentsForRunAndDebugMacWebKitApp();
2245 return system { $appPath } $appPath, argumentsForRunAndDebugMacWebKitApp();
2248 sub execMacWebKitAppForDebugging($)
2251 my $architectureSwitch;
2252 my $argumentsSeparator;
2254 if (debugger() eq "lldb") {
2255 $architectureSwitch = "--arch";
2256 $argumentsSeparator = "--";
2257 } elsif (debugger() eq "gdb") {
2258 $architectureSwitch = "-arch";
2259 $argumentsSeparator = "--args";
2261 die "Unknown debugger $debugger.\n";
2264 my $debuggerPath = `xcrun -find $debugger`;
2265 chomp $debuggerPath;
2266 die "Can't find the $debugger executable.\n" unless -x $debuggerPath;
2268 my $productDir = productDir();
2269 $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
2270 $ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES";
2272 setUpGuardMallocIfNeeded();
2274 my @architectureFlags = ($architectureSwitch, architecture());
2275 if (!shouldTargetWebProcess()) {
2276 print "Starting @{[basename($appPath)]} under $debugger with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
2277 exec { $debuggerPath } $debuggerPath, @architectureFlags, $argumentsSeparator, $appPath, argumentsForRunAndDebugMacWebKitApp() or die;
2279 if (shouldUseXPCServiceForWebProcess()) {
2280 die "Targetting the Web Process is not compatible with using an XPC Service for the Web Process at this time.";
2283 my $webProcessShimPath = File::Spec->catfile($productDir, "SecItemShim.dylib");
2284 my $webProcessPath = File::Spec->catdir($productDir, "WebProcess.app");
2285 my $webKit2ExecutablePath = File::Spec->catfile($productDir, "WebKit2.framework", "WebKit2");
2287 appendToEnvironmentVariableList("DYLD_INSERT_LIBRARIES", $webProcessShimPath);
2289 print "Starting WebProcess under $debugger with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
2290 exec { $debuggerPath } $debuggerPath, @architectureFlags, $argumentsSeparator, $webProcessPath, $webKit2ExecutablePath, "-type", "webprocess", "-client-executable", $appPath or die;
2296 if (isAppleMacWebKit()) {
2298 execMacWebKitAppForDebugging(safariPath());
2301 return 1; # Unsupported platform; can't debug Safari on this platform.
2307 if (isAppleMacWebKit()) {
2308 return runMacWebKitApp(safariPath());
2311 if (isAppleWinWebKit()) {
2313 my $productDir = productDir();
2314 my $webKitLauncherPath = File::Spec->catfile(productDir(), "WinLauncher.exe");
2315 return system { $webKitLauncherPath } $webKitLauncherPath, @ARGV;
2318 return 1; # Unsupported platform; can't run Safari on this platform.
2323 if (isAppleMacWebKit()) {
2324 return runMacWebKitApp(File::Spec->catfile(productDir(), "MiniBrowser.app", "Contents", "MacOS", "MiniBrowser"));
2330 sub debugMiniBrowser
2332 if (isAppleMacWebKit()) {
2333 execMacWebKitAppForDebugging(File::Spec->catfile(productDir(), "MiniBrowser.app", "Contents", "MacOS", "MiniBrowser"));
2339 sub runWebKitTestRunner
2341 if (isAppleMacWebKit()) {
2342 return runMacWebKitApp(File::Spec->catfile(productDir(), "WebKitTestRunner"));
2344 my $productDir = productDir();
2345 my $injectedBundlePath = "$productDir/Libraries/.libs/libTestRunnerInjectedBundle";
2346 print "Starting WebKitTestRunner with TEST_RUNNER_INJECTED_BUNDLE_FILENAME set to point to $injectedBundlePath.\n";
2347 $ENV{TEST_RUNNER_INJECTED_BUNDLE_FILENAME} = $injectedBundlePath;
2348 my @args = ("$productDir/Programs/WebKitTestRunner", @ARGV);
2349 return system {$args[0] } @args;
2355 sub debugWebKitTestRunner
2357 if (isAppleMacWebKit()) {
2358 execMacWebKitAppForDebugging(File::Spec->catfile(productDir(), "WebKitTestRunner"));
2364 sub readRegistryString
2366 my ($valueName) = @_;
2367 chomp(my $string = `regtool --wow32 get "$valueName"`);
2371 sub writeRegistryString
2373 my ($valueName, $string) = @_;
2375 my $error = system "regtool", "--wow32", "set", "-s", $valueName, $string;
2377 # On Windows Vista/7 with UAC enabled, regtool will fail to modify the registry, but will still
2378 # return a successful exit code. So we double-check here that the value we tried to write to the
2379 # registry was really written.
2380 return !$error && readRegistryString($valueName) eq $string;