diff options
Diffstat (limited to 'Tools/Scripts/webkitdirs.pm')
-rwxr-xr-x | Tools/Scripts/webkitdirs.pm | 2505 |
1 files changed, 0 insertions, 2505 deletions
diff --git a/Tools/Scripts/webkitdirs.pm b/Tools/Scripts/webkitdirs.pm deleted file mode 100755 index dcb89eb7d..000000000 --- a/Tools/Scripts/webkitdirs.pm +++ /dev/null @@ -1,2505 +0,0 @@ -# Copyright (C) 2005-2007, 2010-2014 Apple Inc. All rights reserved. -# Copyright (C) 2009 Google Inc. All rights reserved. -# Copyright (C) 2011 Research In Motion Limited. All rights reserved. -# Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of Apple Inc. ("Apple") nor the names of -# its contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# Module to share code to get to WebKit directories. - -use strict; -use version; -use warnings; -use Config; -use Cwd qw(realpath); -use Digest::MD5 qw(md5_hex); -use FindBin; -use File::Basename; -use File::Find; -use File::Path qw(make_path mkpath rmtree); -use File::Spec; -use File::stat; -use List::Util; -use POSIX; -use Time::HiRes qw(usleep); -use VCSUtils; - -BEGIN { - use Exporter (); - our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); - $VERSION = 1.00; - @ISA = qw(Exporter); - @EXPORT = qw( - &XcodeCoverageSupportOptions - &XcodeOptionString - &XcodeOptionStringNoConfig - &XcodeOptions - &XcodeStaticAnalyzerOption - &appDisplayNameFromBundle - &baseProductDir - &chdirWebKit - &checkFrameworks - &cmakeBasedPortArguments - &cmakeBasedPortName - ¤tSVNRevision - &debugSafari - &findOrCreateSimulatorForIOSDevice - &iosSimulatorDeviceByName - &nmPath - &passedConfiguration - &printHelpAndExitForRunAndDebugWebKitAppIfNeeded - &productDir - &quitIOSSimulator - &relaunchIOSSimulator - &runIOSWebKitApp - &runMacWebKitApp - &safariPath - &setConfiguration - &setupMacWebKitEnvironment - &sharedCommandLineOptions - &sharedCommandLineOptionsUsage - USE_OPEN_COMMAND - ); - %EXPORT_TAGS = ( ); - @EXPORT_OK = (); -} - -use constant USE_OPEN_COMMAND => 1; # Used in runMacWebKitApp(). -use constant INCLUDE_OPTIONS_FOR_DEBUGGING => 1; -use constant SIMULATOR_DEVICE_STATE_SHUTDOWN => "1"; -use constant SIMULATOR_DEVICE_STATE_BOOTED => "3"; - -our @EXPORT_OK; - -my $architecture; -my $asanIsEnabled; -my $numberOfCPUs; -my $maxCPULoad; -my $baseProductDir; -my @baseProductDirOption; -my $configuration; -my $xcodeSDK; -my $configurationForVisualStudio; -my $configurationProductDir; -my $sourceDir; -my $currentSVNRevision; -my $debugger; -my $didLoadIPhoneSimulatorNotification; -my $nmPath; -my $osXVersion; -my $generateDsym; -my $isGtk; -my $isWinCairo; -my $isWin64; -my $isEfl; -my $isInspectorFrontend; -my $shouldTargetWebProcess; -my $shouldUseXPCServiceForWebProcess; -my $shouldUseGuardMalloc; -my $xcodeVersion; - -# Variables for Win32 support -my $programFilesPath; -my $vcBuildPath; -my $vsInstallDir; -my $msBuildInstallDir; -my $vsVersion; -my $windowsSourceDir; -my $winVersion; -my $willUseVCExpressWhenBuilding = 0; - -# Defined in VCSUtils. -sub exitStatus($); - -sub findMatchingArguments($$); -sub hasArgument($$); - -sub determineSourceDir -{ - return if $sourceDir; - $sourceDir = $FindBin::Bin; - $sourceDir =~ s|/+$||; # Remove trailing '/' as we would die later - - # walks up path checking each directory to see if it is the main WebKit project dir, - # defined by containing Sources, WebCore, and WebKit - until ((-d File::Spec->catdir($sourceDir, "Source") && -d File::Spec->catdir($sourceDir, "Source", "WebCore") && -d File::Spec->catdir($sourceDir, "Source", "WebKit")) || (-d File::Spec->catdir($sourceDir, "Internal") && -d File::Spec->catdir($sourceDir, "OpenSource"))) - { - if ($sourceDir !~ s|/[^/]+$||) { - die "Could not find top level webkit directory above source directory using FindBin.\n"; - } - } - - $sourceDir = File::Spec->catdir($sourceDir, "OpenSource") if -d File::Spec->catdir($sourceDir, "OpenSource"); -} - -sub currentPerlPath() -{ - my $thisPerl = $^X; - if ($^O ne 'VMS') { - $thisPerl .= $Config{_exe} unless $thisPerl =~ m/$Config{_exe}$/i; - } - return $thisPerl; -} - -# used for scripts which are stored in a non-standard location -sub setSourceDir($) -{ - ($sourceDir) = @_; -} - -sub determineNinjaVersion -{ - chomp(my $ninjaVersion = `ninja --version`); - return $ninjaVersion; -} - -sub determineXcodeVersion -{ - return if defined $xcodeVersion; - my $xcodebuildVersionOutput = `xcodebuild -version`; - $xcodeVersion = ($xcodebuildVersionOutput =~ /Xcode ([0-9](\.[0-9]+)*)/) ? $1 : "3.0"; -} - -sub readXcodeUserDefault($) -{ - my ($unprefixedKey) = @_; - - determineXcodeVersion(); - - my $xcodeDefaultsDomain = (eval "v$xcodeVersion" lt v4) ? "com.apple.Xcode" : "com.apple.dt.Xcode"; - my $xcodeDefaultsPrefix = (eval "v$xcodeVersion" lt v4) ? "PBX" : "IDE"; - my $devnull = File::Spec->devnull(); - - my $value = `defaults read $xcodeDefaultsDomain ${xcodeDefaultsPrefix}${unprefixedKey} 2> ${devnull}`; - return if $?; - - chomp $value; - return $value; -} - -sub determineBaseProductDir -{ - return if defined $baseProductDir; - determineSourceDir(); - - my $setSharedPrecompsDir; - $baseProductDir = $ENV{"WEBKIT_OUTPUTDIR"}; - - if (!defined($baseProductDir) and isAppleMacWebKit()) { - # Silently remove ~/Library/Preferences/xcodebuild.plist which can - # cause build failure. The presence of - # ~/Library/Preferences/xcodebuild.plist can prevent xcodebuild from - # respecting global settings such as a custom build products directory - # (<rdar://problem/5585899>). - my $personalPlistFile = $ENV{HOME} . "/Library/Preferences/xcodebuild.plist"; - if (-e $personalPlistFile) { - unlink($personalPlistFile) || die "Could not delete $personalPlistFile: $!"; - } - - determineXcodeVersion(); - - if (eval "v$xcodeVersion" ge v4) { - my $buildLocationStyle = join '', readXcodeUserDefault("BuildLocationStyle"); - if ($buildLocationStyle eq "Custom") { - my $buildLocationType = join '', readXcodeUserDefault("CustomBuildLocationType"); - # FIXME: Read CustomBuildIntermediatesPath and set OBJROOT accordingly. - $baseProductDir = readXcodeUserDefault("CustomBuildProductsPath") if $buildLocationType eq "Absolute"; - } - - # DeterminedByTargets corresponds to a setting of "Legacy" in Xcode. - # It is the only build location style for which SHARED_PRECOMPS_DIR is not - # overridden when building from within Xcode. - $setSharedPrecompsDir = 1 if $buildLocationStyle ne "DeterminedByTargets"; - } - - if (!defined($baseProductDir)) { - $baseProductDir = join '', readXcodeUserDefault("ApplicationwideBuildSettings"); - $baseProductDir = $1 if $baseProductDir =~ /SYMROOT\s*=\s*\"(.*?)\";/s; - } - - undef $baseProductDir unless $baseProductDir =~ /^\//; - } - - if (!defined($baseProductDir)) { # Port-specific checks failed, use default - $baseProductDir = "$sourceDir/WebKitBuild"; - } - - if (isGit() && isGitBranchBuild()) { - my $branch = gitBranch(); - $baseProductDir = "$baseProductDir/$branch"; - } - - if (isAppleMacWebKit()) { - $baseProductDir =~ s|^\Q$(SRCROOT)/..\E$|$sourceDir|; - $baseProductDir =~ s|^\Q$(SRCROOT)/../|$sourceDir/|; - $baseProductDir =~ s|^~/|$ENV{HOME}/|; - die "Can't handle Xcode product directory with a ~ in it.\n" if $baseProductDir =~ /~/; - die "Can't handle Xcode product directory with a variable in it.\n" if $baseProductDir =~ /\$/; - @baseProductDirOption = ("SYMROOT=$baseProductDir", "OBJROOT=$baseProductDir"); - push(@baseProductDirOption, "SHARED_PRECOMPS_DIR=${baseProductDir}/PrecompiledHeaders") if $setSharedPrecompsDir; - } - - if (isCygwin()) { - my $dosBuildPath = `cygpath --windows \"$baseProductDir\"`; - chomp $dosBuildPath; - $ENV{"WEBKIT_OUTPUTDIR"} = $dosBuildPath; - my $unixBuildPath = `cygpath --unix \"$baseProductDir\"`; - chomp $unixBuildPath; - $baseProductDir = $unixBuildPath; - } -} - -sub setBaseProductDir($) -{ - ($baseProductDir) = @_; -} - -sub determineConfiguration -{ - return if defined $configuration; - determineBaseProductDir(); - if (open CONFIGURATION, "$baseProductDir/Configuration") { - $configuration = <CONFIGURATION>; - close CONFIGURATION; - } - if ($configuration) { - chomp $configuration; - # compatibility for people who have old Configuration files - $configuration = "Release" if $configuration eq "Deployment"; - $configuration = "Debug" if $configuration eq "Development"; - } else { - $configuration = "Release"; - } -} - -sub determineArchitecture -{ - return if defined $architecture; - # make sure $architecture is defined in all cases - $architecture = ""; - - determineBaseProductDir(); - determineXcodeSDK(); - - if (isAppleMacWebKit()) { - if (open ARCHITECTURE, "$baseProductDir/Architecture") { - $architecture = <ARCHITECTURE>; - close ARCHITECTURE; - } - if ($architecture) { - chomp $architecture; - } else { - if (not defined $xcodeSDK or $xcodeSDK =~ /^(\/$|macosx)/) { - my $supports64Bit = `sysctl -n hw.optional.x86_64`; - chomp $supports64Bit; - $architecture = 'x86_64' if $supports64Bit; - } elsif ($xcodeSDK =~ /^iphonesimulator/) { - $architecture = 'x86_64'; - } elsif ($xcodeSDK =~ /^iphoneos/) { - $architecture = 'armv7'; - } - } - } elsif (isEfl() || isGtk()) { - my $host_processor = ""; - $host_processor = `cmake --system-information | grep CMAKE_SYSTEM_PROCESSOR`; - if ($host_processor =~ m/^CMAKE_SYSTEM_PROCESSOR \"([^"]+)\"/) { - # We have a configured build tree; use it. - $architecture = $1; - $architecture = 'x86_64' if $architecture eq 'amd64'; - } - } - - if (!$architecture && (isGtk() || isAppleMacWebKit() || isEfl())) { - # Fall back to output of `arch', if it is present. - $architecture = `arch`; - chomp $architecture; - } - - if (!$architecture && (isGtk() || isAppleMacWebKit() || isEfl())) { - # Fall back to output of `uname -m', if it is present. - $architecture = `uname -m`; - chomp $architecture; - } - - $architecture = 'x86_64' if ($architecture =~ /amd64/ && isBSD()); -} - -sub determineASanIsEnabled -{ - return if defined $asanIsEnabled; - determineBaseProductDir(); - - $asanIsEnabled = 0; - my $asanConfigurationValue; - - if (open ASAN, "$baseProductDir/ASan") { - $asanConfigurationValue = <ASAN>; - close ASAN; - chomp $asanConfigurationValue; - $asanIsEnabled = 1 if $asanConfigurationValue eq "YES"; - } -} - -sub determineNumberOfCPUs -{ - return if defined $numberOfCPUs; - if (defined($ENV{NUMBER_OF_PROCESSORS})) { - $numberOfCPUs = $ENV{NUMBER_OF_PROCESSORS}; - } elsif (isLinux()) { - # First try the nproc utility, if it exists. If we get no - # results fall back to just interpretting /proc directly. - chomp($numberOfCPUs = `nproc --all 2> /dev/null`); - if ($numberOfCPUs eq "") { - $numberOfCPUs = (grep /processor/, `cat /proc/cpuinfo`); - } - } elsif (isWindows() || isCygwin()) { - # Assumes cygwin - $numberOfCPUs = `ls /proc/registry/HKEY_LOCAL_MACHINE/HARDWARE/DESCRIPTION/System/CentralProcessor | wc -w`; - } elsif (isDarwin() || isBSD()) { - chomp($numberOfCPUs = `sysctl -n hw.ncpu`); - } -} - -sub determineMaxCPULoad -{ - return if defined $maxCPULoad; - if (defined($ENV{MAX_CPU_LOAD})) { - $maxCPULoad = $ENV{MAX_CPU_LOAD}; - } -} - -sub jscPath($) -{ - my ($productDir) = @_; - my $jscName = "jsc"; - $jscName .= "_debug" if configuration() eq "Debug_All"; - $jscName .= ".exe" if (isWindows() || isCygwin()); - return "$productDir/$jscName" if -e "$productDir/$jscName"; - return "$productDir/JavaScriptCore.framework/Resources/$jscName"; -} - -sub argumentsForConfiguration() -{ - determineConfiguration(); - determineArchitecture(); - determineXcodeSDK(); - - my @args = (); - # FIXME: Is it necessary to pass --debug, --release, --32-bit or --64-bit? - # These are determined automatically from stored configuration. - push(@args, '--debug') if ($configuration =~ "^Debug"); - push(@args, '--release') if ($configuration =~ "^Release"); - push(@args, '--device') if (defined $xcodeSDK && $xcodeSDK =~ /^iphoneos/); - push(@args, '--ios-simulator') if (defined $xcodeSDK && $xcodeSDK =~ /^iphonesimulator/); - push(@args, '--32-bit') if ($architecture ne "x86_64" and !isWin64()); - push(@args, '--64-bit') if (isWin64()); - push(@args, '--gtk') if isGtk(); - push(@args, '--efl') if isEfl(); - push(@args, '--wincairo') if isWinCairo(); - push(@args, '--inspector-frontend') if isInspectorFrontend(); - return @args; -} - -sub determineXcodeSDK -{ - return if defined $xcodeSDK; - my $sdk; - if (checkForArgumentAndRemoveFromARGVGettingValue("--sdk", \$sdk)) { - $xcodeSDK = $sdk; - } - if (checkForArgumentAndRemoveFromARGV("--device")) { - my $hasInternalSDK = exitStatus(system("xcrun --sdk iphoneos.internal --show-sdk-version > /dev/null 2>&1")) == 0; - $xcodeSDK ||= $hasInternalSDK ? "iphoneos.internal" : "iphoneos"; - } - if (checkForArgumentAndRemoveFromARGV("--ios-simulator")) { - $xcodeSDK ||= 'iphonesimulator'; - } -} - -sub xcodeSDK -{ - determineXcodeSDK(); - return $xcodeSDK; -} - -sub setXcodeSDK($) -{ - ($xcodeSDK) = @_; -} - - -sub xcodeSDKPlatformName() -{ - determineXcodeSDK(); - return "" if !defined $xcodeSDK; - return "iphoneos" if $xcodeSDK =~ /iphoneos/i; - return "iphonesimulator" if $xcodeSDK =~ /iphonesimulator/i; - return "macosx" if $xcodeSDK =~ /macosx/i; - die "Couldn't determine platform name from Xcode SDK"; -} - -sub XcodeSDKPath -{ - determineXcodeSDK(); - - die "Can't find the SDK path because no Xcode SDK was specified" if not $xcodeSDK; - - my $sdkPath = `xcrun --sdk $xcodeSDK --show-sdk-path` if $xcodeSDK; - die 'Failed to get SDK path from xcrun' if $?; - chomp $sdkPath; - - return $sdkPath; -} - -sub xcodeSDKVersion -{ - determineXcodeSDK(); - - die "Can't find the SDK version because no Xcode SDK was specified" if !$xcodeSDK; - - chomp(my $sdkVersion = `xcrun --sdk $xcodeSDK --show-sdk-version`); - die "Failed to get SDK version from xcrun" if exitStatus($?); - - return $sdkVersion; -} - -sub programFilesPath -{ - return $programFilesPath if defined $programFilesPath; - - $programFilesPath = $ENV{'PROGRAMFILES(X86)'} || $ENV{'PROGRAMFILES'} || "C:\\Program Files"; - - return $programFilesPath; -} - -sub visualStudioInstallDir -{ - return $vsInstallDir if defined $vsInstallDir; - - if ($ENV{'VSINSTALLDIR'}) { - $vsInstallDir = $ENV{'VSINSTALLDIR'}; - $vsInstallDir =~ s|[\\/]$||; - } else { - $vsInstallDir = File::Spec->catdir(programFilesPath(), "Microsoft Visual Studio 14.0"); - } - chomp($vsInstallDir = `cygpath "$vsInstallDir"`) if isCygwin(); - - print "Using Visual Studio: $vsInstallDir\n"; - return $vsInstallDir; -} - -sub msBuildInstallDir -{ - return $msBuildInstallDir if defined $msBuildInstallDir; - - $msBuildInstallDir = File::Spec->catdir(programFilesPath(), "MSBuild", "14.0", "Bin"); - - chomp($msBuildInstallDir = `cygpath "$msBuildInstallDir"`) if isCygwin(); - - print "Using MSBuild: $msBuildInstallDir\n"; - return $msBuildInstallDir; -} - -sub visualStudioVersion -{ - return $vsVersion if defined $vsVersion; - - my $installDir = visualStudioInstallDir(); - - $vsVersion = ($installDir =~ /Microsoft Visual Studio ([0-9]+\.[0-9]*)/) ? $1 : "14"; - - print "Using Visual Studio $vsVersion\n"; - return $vsVersion; -} - -sub determineConfigurationForVisualStudio -{ - return if defined $configurationForVisualStudio; - determineConfiguration(); - # FIXME: We should detect when Debug_All or Production has been chosen. - $configurationForVisualStudio = "/p:Configuration=" . $configuration; -} - -sub usesPerConfigurationBuildDirectory -{ - # [Gtk] We don't have Release/Debug configurations in straight - # autotool builds (non build-webkit). In this case and if - # WEBKIT_OUTPUTDIR exist, use that as our configuration dir. This will - # allows us to run run-webkit-tests without using build-webkit. - return ($ENV{"WEBKIT_OUTPUTDIR"} && isGtk()) || isAppleWinWebKit(); -} - -sub determineConfigurationProductDir -{ - return if defined $configurationProductDir; - determineBaseProductDir(); - determineConfiguration(); - if (isAppleWinWebKit() || isWinCairo()) { - my $binDir = isWin64() ? "bin64" : "bin32"; - $configurationProductDir = File::Spec->catdir($baseProductDir, $configuration, $binDir); - } else { - if (usesPerConfigurationBuildDirectory()) { - $configurationProductDir = "$baseProductDir"; - } else { - $configurationProductDir = "$baseProductDir/$configuration"; - $configurationProductDir .= "-" . xcodeSDKPlatformName() if isIOSWebKit(); - } - } -} - -sub setConfigurationProductDir($) -{ - ($configurationProductDir) = @_; -} - -sub determineCurrentSVNRevision -{ - # We always update the current SVN revision here, and leave the caching - # to currentSVNRevision(), so that changes to the SVN revision while the - # script is running can be picked up by calling this function again. - determineSourceDir(); - $currentSVNRevision = svnRevisionForDirectory($sourceDir); - return $currentSVNRevision; -} - - -sub chdirWebKit -{ - determineSourceDir(); - chdir $sourceDir or die; -} - -sub baseProductDir -{ - determineBaseProductDir(); - return $baseProductDir; -} - -sub sourceDir -{ - determineSourceDir(); - return $sourceDir; -} - -sub productDir -{ - determineConfigurationProductDir(); - return $configurationProductDir; -} - -sub jscProductDir -{ - my $productDir = productDir(); - $productDir .= "/bin" if (isEfl() || isGtk()); - - return $productDir; -} - -sub configuration() -{ - determineConfiguration(); - return $configuration; -} - -sub asanIsEnabled() -{ - determineASanIsEnabled(); - return $asanIsEnabled; -} - -sub configurationForVisualStudio() -{ - determineConfigurationForVisualStudio(); - return $configurationForVisualStudio; -} - -sub currentSVNRevision -{ - determineCurrentSVNRevision() if not defined $currentSVNRevision; - return $currentSVNRevision; -} - -sub generateDsym() -{ - determineGenerateDsym(); - return $generateDsym; -} - -sub determineGenerateDsym() -{ - return if defined($generateDsym); - $generateDsym = checkForArgumentAndRemoveFromARGV("--dsym"); -} - -sub argumentsForXcode() -{ - my @args = (); - push @args, "DEBUG_INFORMATION_FORMAT=dwarf-with-dsym" if generateDsym(); - return @args; -} - -sub XcodeOptions -{ - determineBaseProductDir(); - determineConfiguration(); - determineArchitecture(); - determineASanIsEnabled(); - determineXcodeSDK(); - - my @sdkOption = ($xcodeSDK ? "SDKROOT=$xcodeSDK" : ()); - my @architectureOption = ($architecture ? "ARCHS=$architecture" : ()); - my @asanOption = ($asanIsEnabled ? ("-xcconfig", sourceDir() . "/Tools/asan/asan.xcconfig", "ASAN_IGNORE=" . sourceDir() . "/Tools/asan/webkit-asan-ignore.txt") : ()); - - return ("-UseSanitizedBuildSystemEnvironment=YES", @baseProductDirOption, "-configuration", $configuration, @architectureOption, @sdkOption, @asanOption, argumentsForXcode()); -} - -sub XcodeOptionString -{ - return join " ", XcodeOptions(); -} - -sub XcodeOptionStringNoConfig -{ - return join " ", @baseProductDirOption; -} - -sub XcodeCoverageSupportOptions() -{ - my @coverageSupportOptions = (); - push @coverageSupportOptions, "GCC_GENERATE_TEST_COVERAGE_FILES=YES"; - push @coverageSupportOptions, "GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES"; - return @coverageSupportOptions; -} - -sub XcodeStaticAnalyzerOption() -{ - return "RUN_CLANG_STATIC_ANALYZER=YES"; -} - -my $passedConfiguration; -my $searchedForPassedConfiguration; -sub determinePassedConfiguration -{ - return if $searchedForPassedConfiguration; - $searchedForPassedConfiguration = 1; - $passedConfiguration = undef; - - if (checkForArgumentAndRemoveFromARGV("--debug")) { - $passedConfiguration = "Debug"; - } elsif(checkForArgumentAndRemoveFromARGV("--release")) { - $passedConfiguration = "Release"; - } elsif (checkForArgumentAndRemoveFromARGV("--profile") || checkForArgumentAndRemoveFromARGV("--profiling")) { - $passedConfiguration = "Profiling"; - } -} - -sub passedConfiguration -{ - determinePassedConfiguration(); - return $passedConfiguration; -} - -sub setConfiguration -{ - setArchitecture(); - - if (my $config = shift @_) { - $configuration = $config; - return; - } - - determinePassedConfiguration(); - $configuration = $passedConfiguration if $passedConfiguration; -} - - -my $passedArchitecture; -my $searchedForPassedArchitecture; -sub determinePassedArchitecture -{ - return if $searchedForPassedArchitecture; - $searchedForPassedArchitecture = 1; - - $passedArchitecture = undef; - if (checkForArgumentAndRemoveFromARGV("--32-bit")) { - if (isAppleMacWebKit()) { - # PLATFORM_IOS: Don't run `arch` command inside Simulator environment - local %ENV = %ENV; - delete $ENV{DYLD_ROOT_PATH}; - delete $ENV{DYLD_FRAMEWORK_PATH}; - - $passedArchitecture = `arch`; - chomp $passedArchitecture; - } - } -} - -sub passedArchitecture -{ - determinePassedArchitecture(); - return $passedArchitecture; -} - -sub architecture() -{ - determineArchitecture(); - return $architecture; -} - -sub numberOfCPUs() -{ - determineNumberOfCPUs(); - return $numberOfCPUs; -} - -sub maxCPULoad() -{ - determineMaxCPULoad(); - return $maxCPULoad; -} - -sub setArchitecture -{ - if (my $arch = shift @_) { - $architecture = $arch; - return; - } - - determinePassedArchitecture(); - $architecture = $passedArchitecture if $passedArchitecture; -} - -sub skipSafariExecutableEntitlementChecks -{ - return `defaults read /Library/Preferences/org.webkit.BuildConfiguration SkipSafariExecutableEntitlementChecks 2>/dev/null` eq "1\n"; -} - -sub executableHasEntitlements -{ - my $executablePath = shift; - return (`codesign -d --entitlements - $executablePath 2>&1` =~ /<key>/); -} - -sub safariPathFromSafariBundle -{ - my ($safariBundle) = @_; - - die "Safari path is only relevant on Apple Mac platform\n" unless isAppleMacWebKit(); - - my $safariPath = "$safariBundle/Contents/MacOS/Safari"; - return $safariPath if skipSafariExecutableEntitlementChecks(); - - my $safariForWebKitDevelopmentPath = "$safariBundle/Contents/MacOS/SafariForWebKitDevelopment"; - return $safariForWebKitDevelopmentPath if -f $safariForWebKitDevelopmentPath && executableHasEntitlements($safariPath); - - return $safariPath; -} - -sub installedSafariPath -{ - return safariPathFromSafariBundle("/Applications/Safari.app"); -} - -# Locate Safari. -sub safariPath -{ - die "Safari path is only relevant on Apple Mac platform\n" unless isAppleMacWebKit(); - - # Use WEBKIT_SAFARI environment variable if present. - my $safariBundle = $ENV{WEBKIT_SAFARI}; - if (!$safariBundle) { - determineConfigurationProductDir(); - # Use Safari.app in product directory if present (good for Safari development team). - if (-d "$configurationProductDir/Safari.app") { - $safariBundle = "$configurationProductDir/Safari.app"; - } - if (!$safariBundle) { - return installedSafariPath(); - } - } - my $safariPath = safariPathFromSafariBundle($safariBundle); - die "Can't find executable at $safariPath.\n" if !-x $safariPath; - return $safariPath; -} - -sub builtDylibPathForName -{ - my $libraryName = shift; - determineConfigurationProductDir(); - - if (isGtk()) { - my $extension = isDarwin() ? ".dylib" : ".so"; - return "$configurationProductDir/lib/libwebkit2gtk-4.0" . $extension; - } - if (isEfl()) { - return "$configurationProductDir/lib/libewebkit2.so"; - } - if (isIOSWebKit()) { - return "$configurationProductDir/$libraryName.framework/$libraryName"; - } - if (isAppleMacWebKit()) { - return "$configurationProductDir/$libraryName.framework/Versions/A/$libraryName"; - } - if (isAppleWinWebKit()) { - if ($libraryName eq "JavaScriptCore") { - return "$baseProductDir/lib/$libraryName.lib"; - } else { - return "$baseProductDir/$libraryName.intermediate/$configuration/$libraryName.intermediate/$libraryName.lib"; - } - } - - die "Unsupported platform, can't determine built library locations.\nTry `build-webkit --help` for more information.\n"; -} - -# Check to see that all the frameworks are built. -sub checkFrameworks # FIXME: This is a poor name since only the Mac calls built WebCore a Framework. -{ - return if isCygwin() || isWindows(); - my @frameworks = ("JavaScriptCore", "WebCore"); - push(@frameworks, "WebKit") if isAppleMacWebKit(); # FIXME: This seems wrong, all ports should have a WebKit these days. - for my $framework (@frameworks) { - my $path = builtDylibPathForName($framework); - die "Can't find built framework at \"$path\".\n" unless -e $path; - } -} - -sub isInspectorFrontend() -{ - determineIsInspectorFrontend(); - return $isInspectorFrontend; -} - -sub determineIsInspectorFrontend() -{ - return if defined($isInspectorFrontend); - $isInspectorFrontend = checkForArgumentAndRemoveFromARGV("--inspector-frontend"); -} - -sub commandExists($) -{ - my $command = shift; - my $devnull = File::Spec->devnull(); - - if (isAnyWindows()) { - return exitStatus(system("where /q $command >$devnull 2>&1")) == 0; - } - return exitStatus(system("which $command >$devnull 2>&1")) == 0; -} - -sub checkForArgumentAndRemoveFromARGV($) -{ - my $argToCheck = shift; - return checkForArgumentAndRemoveFromArrayRef($argToCheck, \@ARGV); -} - -sub checkForArgumentAndRemoveFromArrayRefGettingValue($$$) -{ - my ($argToCheck, $valueRef, $arrayRef) = @_; - my $argumentStartRegEx = qr#^$argToCheck(?:=\S|$)#; - my $i = 0; - for (; $i < @$arrayRef; ++$i) { - last if $arrayRef->[$i] =~ $argumentStartRegEx; - } - if ($i >= @$arrayRef) { - return $$valueRef = undef; - } - my ($key, $value) = split("=", $arrayRef->[$i]); - splice(@$arrayRef, $i, 1); - if (defined($value)) { - # e.g. --sdk=iphonesimulator - return $$valueRef = $value; - } - return $$valueRef = splice(@$arrayRef, $i, 1); # e.g. --sdk iphonesimulator -} - -sub checkForArgumentAndRemoveFromARGVGettingValue($$) -{ - my ($argToCheck, $valueRef) = @_; - return checkForArgumentAndRemoveFromArrayRefGettingValue($argToCheck, $valueRef, \@ARGV); -} - -sub findMatchingArguments($$) -{ - my ($argToCheck, $arrayRef) = @_; - my @matchingIndices; - foreach my $index (0 .. $#$arrayRef) { - my $opt = $$arrayRef[$index]; - if ($opt =~ /^$argToCheck$/i ) { - push(@matchingIndices, $index); - } - } - return @matchingIndices; -} - -sub hasArgument($$) -{ - my ($argToCheck, $arrayRef) = @_; - my @matchingIndices = findMatchingArguments($argToCheck, $arrayRef); - return scalar @matchingIndices > 0; -} - -sub checkForArgumentAndRemoveFromArrayRef -{ - my ($argToCheck, $arrayRef) = @_; - my @indicesToRemove = findMatchingArguments($argToCheck, $arrayRef); - my $removeOffset = 0; - foreach my $index (@indicesToRemove) { - splice(@$arrayRef, $index - $removeOffset++, 1); - } - return scalar @indicesToRemove > 0; -} - -sub determineIsEfl() -{ - return if defined($isEfl); - $isEfl = checkForArgumentAndRemoveFromARGV("--efl"); -} - -sub isEfl() -{ - determineIsEfl(); - return $isEfl; -} - -sub determineIsGtk() -{ - return if defined($isGtk); - $isGtk = checkForArgumentAndRemoveFromARGV("--gtk"); -} - -sub isGtk() -{ - determineIsGtk(); - return $isGtk; -} - -# Determine if this is debian, ubuntu, linspire, or something similar. -sub isDebianBased() -{ - return -e "/etc/debian_version"; -} - -sub isFedoraBased() -{ - return -e "/etc/fedora-release"; -} - -sub isWinCairo() -{ - determineIsWinCairo(); - return $isWinCairo; -} - -sub determineIsWinCairo() -{ - return if defined($isWinCairo); - $isWinCairo = checkForArgumentAndRemoveFromARGV("--wincairo"); -} - -sub isWin64() -{ - determineIsWin64(); - return $isWin64; -} - -sub determineIsWin64() -{ - return if defined($isWin64); - $isWin64 = checkForArgumentAndRemoveFromARGV("--64-bit"); -} - -sub isCygwin() -{ - return ($^O eq "cygwin") || 0; -} - -sub isAnyWindows() -{ - return isWindows() || isCygwin(); -} - -sub determineWinVersion() -{ - return if $winVersion; - - if (!isAnyWindows()) { - $winVersion = -1; - return; - } - - my $versionString = `cmd /c ver`; - $versionString =~ /(\d)\.(\d)\.(\d+)/; - - $winVersion = { - major => $1, - minor => $2, - build => $3, - }; -} - -sub winVersion() -{ - determineWinVersion(); - return $winVersion; -} - -sub isWindows7SP0() -{ - return isAnyWindows() && winVersion()->{major} == 6 && winVersion()->{minor} == 1 && winVersion()->{build} == 7600; -} - -sub isWindowsVista() -{ - return isAnyWindows() && winVersion()->{major} == 6 && winVersion()->{minor} == 0; -} - -sub isWindowsXP() -{ - return isAnyWindows() && winVersion()->{major} == 5 && winVersion()->{minor} == 1; -} - -sub isDarwin() -{ - return ($^O eq "darwin") || 0; -} - -sub isWindows() -{ - return ($^O eq "MSWin32") || 0; -} - -sub isLinux() -{ - return ($^O eq "linux") || 0; -} - -sub isBSD() -{ - return ($^O eq "freebsd") || ($^O eq "openbsd") || ($^O eq "netbsd") || 0; -} - -sub isARM() -{ - return ($Config{archname} =~ /^arm[v\-]/) || ($Config{archname} =~ /^aarch64[v\-]/); -} - -sub isCrossCompilation() -{ - my $compiler = ""; - $compiler = $ENV{'CC'} if (defined($ENV{'CC'})); - if ($compiler =~ /gcc/) { - my $compiler_options = `$compiler -v 2>&1`; - my @host = $compiler_options =~ m/--host=(.*?)\s/; - my @target = $compiler_options =~ m/--target=(.*?)\s/; - - return ($host[0] ne "" && $target[0] ne "" && $host[0] ne $target[0]); - } - return 0; -} - -sub isAppleWebKit() -{ - return isAppleMacWebKit() || isAppleWinWebKit(); -} - -sub isAppleMacWebKit() -{ - return isDarwin() && !isGtk(); -} - -sub isAppleWinWebKit() -{ - return (isCygwin() || isWindows()) && !isWinCairo() && !isGtk(); -} - -sub iOSSimulatorDevicesPath -{ - return "$ENV{HOME}/Library/Developer/CoreSimulator/Devices"; -} - -sub iOSSimulatorDevices -{ - eval "require Foundation"; - my $devicesPath = iOSSimulatorDevicesPath(); - opendir(DEVICES, $devicesPath); - my @udids = grep { - $_ =~ m/[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}/; - } readdir(DEVICES); - close(DEVICES); - - # FIXME: We should parse the device.plist file ourself and map the dictionary keys in it to known - # dictionary keys so as to decouple our representation of the plist from the actual structure - # of the plist, which may change. - my @devices = map { - Foundation::perlRefFromObjectRef(NSDictionary->dictionaryWithContentsOfFile_("$devicesPath/$_/device.plist")); - } @udids; - - return @devices; -} - -sub createiOSSimulatorDevice -{ - my $name = shift; - my $deviceTypeId = shift; - my $runtimeId = shift; - - my $created = system("xcrun", "--sdk", "iphonesimulator", "simctl", "create", $name, $deviceTypeId, $runtimeId) == 0; - die "Couldn't create simulator device: $name $deviceTypeId $runtimeId" if not $created; - - system("xcrun", "--sdk", "iphonesimulator", "simctl", "list"); - - print "Waiting for device to be created ...\n"; - sleep 5; - for (my $tries = 0; $tries < 5; $tries++){ - my @devices = iOSSimulatorDevices(); - foreach my $device (@devices) { - return $device if $device->{name} eq $name and $device->{deviceType} eq $deviceTypeId and $device->{runtime} eq $runtimeId; - } - sleep 5; - } - die "Device $name $deviceTypeId $runtimeId wasn't found in " . iOSSimulatorDevicesPath(); -} - -sub willUseIOSDeviceSDKWhenBuilding() -{ - return xcodeSDKPlatformName() eq "iphoneos"; -} - -sub willUseIOSSimulatorSDKWhenBuilding() -{ - return xcodeSDKPlatformName() eq "iphonesimulator"; -} - -sub isIOSWebKit() -{ - determineXcodeSDK(); - return isAppleMacWebKit() && (willUseIOSDeviceSDKWhenBuilding() || willUseIOSSimulatorSDKWhenBuilding()); -} - -sub determineNmPath() -{ - return if $nmPath; - - if (isAppleMacWebKit()) { - $nmPath = `xcrun -find nm`; - chomp $nmPath; - } - $nmPath = "nm" if !$nmPath; -} - -sub nmPath() -{ - determineNmPath(); - return $nmPath; -} - -sub determineOSXVersion() -{ - return if $osXVersion; - - if (!isDarwin()) { - $osXVersion = -1; - return; - } - - my $version = `sw_vers -productVersion`; - my @splitVersion = split(/\./, $version); - @splitVersion >= 2 or die "Invalid version $version"; - $osXVersion = { - "major" => $splitVersion[0], - "minor" => $splitVersion[1], - "subminor" => (defined($splitVersion[2]) ? $splitVersion[2] : 0), - }; -} - -sub osXVersion() -{ - determineOSXVersion(); - return $osXVersion; -} - -sub isWindowsNT() -{ - return $ENV{'OS'} eq 'Windows_NT'; -} - -sub shouldTargetWebProcess -{ - determineShouldTargetWebProcess(); - return $shouldTargetWebProcess; -} - -sub determineShouldTargetWebProcess -{ - return if defined($shouldTargetWebProcess); - $shouldTargetWebProcess = checkForArgumentAndRemoveFromARGV("--target-web-process"); -} - -sub shouldUseXPCServiceForWebProcess -{ - determineShouldUseXPCServiceForWebProcess(); - return $shouldUseXPCServiceForWebProcess; -} - -sub determineShouldUseXPCServiceForWebProcess -{ - return if defined($shouldUseXPCServiceForWebProcess); - $shouldUseXPCServiceForWebProcess = checkForArgumentAndRemoveFromARGV("--use-web-process-xpc-service"); -} - -sub debugger -{ - determineDebugger(); - return $debugger; -} - -sub determineDebugger -{ - return if defined($debugger); - - determineXcodeVersion(); - if (eval "v$xcodeVersion" ge v4.5) { - $debugger = "lldb"; - } else { - $debugger = "gdb"; - } - - if (checkForArgumentAndRemoveFromARGV("--use-lldb")) { - $debugger = "lldb"; - } - - if (checkForArgumentAndRemoveFromARGV("--use-gdb")) { - $debugger = "gdb"; - } -} - -sub appendToEnvironmentVariableList -{ - my ($environmentVariableName, $value) = @_; - - if (defined($ENV{$environmentVariableName})) { - $ENV{$environmentVariableName} .= ":" . $value; - } else { - $ENV{$environmentVariableName} = $value; - } -} - -sub sharedCommandLineOptions() -{ - return ( - "g|guard-malloc" => \$shouldUseGuardMalloc, - ); -} - -sub sharedCommandLineOptionsUsage -{ - my %opts = @_; - - my %switches = ( - '-g|--guard-malloc' => 'Use guardmalloc when running executable', - ); - - my $indent = " " x ($opts{indent} || 2); - my $switchWidth = List::Util::max(int($opts{switchWidth}), List::Util::max(map { length($_) } keys %switches) + ($opts{brackets} ? 2 : 0)); - - my $result = "Common switches:\n"; - - for my $switch (keys %switches) { - my $switchName = $opts{brackets} ? "[" . $switch . "]" : $switch; - $result .= sprintf("%s%-" . $switchWidth . "s %s\n", $indent, $switchName, $switches{$switch}); - } - - return $result; -} - -sub setUpGuardMallocIfNeeded -{ - if (!isDarwin()) { - return; - } - - if (!defined($shouldUseGuardMalloc)) { - $shouldUseGuardMalloc = checkForArgumentAndRemoveFromARGV("-g") || checkForArgumentAndRemoveFromARGV("--guard-malloc"); - } - - if ($shouldUseGuardMalloc) { - appendToEnvironmentVariableList("DYLD_INSERT_LIBRARIES", "/usr/lib/libgmalloc.dylib"); - } -} - -sub relativeScriptsDir() -{ - my $scriptDir = File::Spec->catpath("", File::Spec->abs2rel($FindBin::Bin, getcwd()), ""); - if ($scriptDir eq "") { - $scriptDir = "."; - } - return $scriptDir; -} - -sub launcherPath() -{ - my $relativeScriptsPath = relativeScriptsDir(); - if (isGtk() || isEfl()) { - return "$relativeScriptsPath/run-minibrowser"; - } elsif (isAppleWebKit()) { - return "$relativeScriptsPath/run-safari"; - } -} - -sub launcherName() -{ - if (isGtk() || isEfl()) { - return "MiniBrowser"; - } elsif (isAppleMacWebKit()) { - return "Safari"; - } elsif (isAppleWinWebKit()) { - return "WinLauncher"; - } -} - -sub checkRequiredSystemConfig -{ - if (isDarwin()) { - chomp(my $productVersion = `sw_vers -productVersion`); - if (eval "v$productVersion" lt v10.7.5) { - print "*************************************************************\n"; - print "Mac OS X Version 10.7.5 or later is required to build WebKit.\n"; - print "You have " . $productVersion . ", thus the build will most likely fail.\n"; - print "*************************************************************\n"; - } - my $xcodebuildVersionOutput = `xcodebuild -version`; - my $xcodeVersion = ($xcodebuildVersionOutput =~ /Xcode ([0-9](\.[0-9]+)*)/) ? $1 : undef; - if (!$xcodeVersion || $xcodeVersion && eval "v$xcodeVersion" lt v4.6) { - print "*************************************************************\n"; - print "Xcode Version 4.6 or later is required to build WebKit.\n"; - print "You have an earlier version of Xcode, thus the build will\n"; - print "most likely fail. The latest Xcode is available from the App Store.\n"; - print "*************************************************************\n"; - } - } elsif (isGtk() or isEfl() or isWindows()) { - my @cmds = qw(bison gperf flex); - my @missing = (); - my $oldPath = $ENV{PATH}; - foreach my $cmd (@cmds) { - push @missing, $cmd if not commandExists($cmd); - } - - if (@missing) { - my $list = join ", ", @missing; - die "ERROR: $list missing but required to build WebKit.\n"; - } - } - # Win32 and other platforms may want to check for minimum config -} - -sub determineWindowsSourceDir() -{ - return if $windowsSourceDir; - $windowsSourceDir = sourceDir(); - chomp($windowsSourceDir = `cygpath -w '$windowsSourceDir'`) if isCygwin(); -} - -sub windowsSourceDir() -{ - determineWindowsSourceDir(); - return $windowsSourceDir; -} - -sub windowsSourceSourceDir() -{ - return File::Spec->catdir(windowsSourceDir(), "Source"); -} - -sub windowsLibrariesDir() -{ - return File::Spec->catdir(windowsSourceDir(), "WebKitLibraries", "win"); -} - -sub windowsOutputDir() -{ - return File::Spec->catdir(windowsSourceDir(), "WebKitBuild"); -} - -sub fontExists($) -{ - my $font = shift; - my $cmd = "reg query \"HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\\" . $font ."\" 2>&1"; - my $val = `$cmd`; - return $? == 0; -} - -sub checkInstalledTools() -{ - # environment variables. Avoid until this is corrected. - my $pythonVer = `python --version 2>&1`; - die "You must have Python installed to build WebKit.\n" if ($?); - - # cURL 7.34.0 has a bug that prevents authentication with opensource.apple.com (and other things using SSL3). - my $curlVer = `curl --version 2> NUL`; - if (!$? and $curlVer =~ "(.*curl.*)") { - $curlVer = $1; - if ($curlVer =~ /libcurl\/7\.34\.0/) { - print "cURL version 7.34.0 has a bug that prevents authentication with SSL v2 or v3.\n"; - print "cURL 7.33.0 is known to work. The cURL projects is preparing an update to\n"; - print "correct this problem.\n\n"; - die "Please install a working cURL and try again.\n"; - } - } - - # MathML requires fonts that do not ship with Windows (at least through Windows 8). Warn the user if they are missing - my @fonts = qw(STIXGeneral-Regular MathJax_Main-Regular); - my @missing = (); - foreach my $font (@fonts) { - push @missing, $font if not fontExists($font); - } - - if (scalar @missing > 0) { - print "*************************************************************\n"; - print "Mathematical fonts, such as STIX and MathJax, are needed to\n"; - print "use the MathML feature. You do not appear to have these fonts\n"; - print "on your system.\n\n"; - print "You can download a suitable set of fonts from the following URL:\n"; - print "https://developer.mozilla.org/Mozilla/MathML_Projects/Fonts\n"; - print "*************************************************************\n"; - } - - print "Installed tools are correct for the WebKit build.\n"; -} - -sub setupAppleWinEnv() -{ - return unless isAppleWinWebKit(); - - checkInstalledTools(); - - if (isWindowsNT()) { - my $restartNeeded = 0; - my %variablesToSet = (); - - # FIXME: We should remove this explicit version check for cygwin once we stop supporting Cygwin 1.7.9 or older versions. - # https://bugs.webkit.org/show_bug.cgi?id=85791 - my $uname_version = (POSIX::uname())[2]; - $uname_version =~ s/\(.*\)//; # Remove the trailing cygwin version, if any. - $uname_version =~ s/\-.*$//; # Remove trailing dash-version content, if any - if (version->parse($uname_version) < version->parse("1.7.10")) { - # Setting the environment variable 'CYGWIN' to 'tty' makes cygwin enable extra support (i.e., termios) - # for UNIX-like ttys in the Windows console - $variablesToSet{CYGWIN} = "tty" unless $ENV{CYGWIN}; - } - - # Those environment variables must be set to be able to build inside Visual Studio. - $variablesToSet{WEBKIT_LIBRARIES} = windowsLibrariesDir() unless $ENV{WEBKIT_LIBRARIES}; - $variablesToSet{WEBKIT_OUTPUTDIR} = windowsOutputDir() unless $ENV{WEBKIT_OUTPUTDIR}; - $variablesToSet{MSBUILDDISABLENODEREUSE} = "1" unless $ENV{MSBUILDDISABLENODEREUSE}; - - foreach my $variable (keys %variablesToSet) { - print "Setting the Environment Variable '" . $variable . "' to '" . $variablesToSet{$variable} . "'\n\n"; - my $ret = system "setx", $variable, $variablesToSet{$variable}; - if ($ret != 0) { - system qw(regtool -s set), '\\HKEY_CURRENT_USER\\Environment\\' . $variable, $variablesToSet{$variable}; - } - $restartNeeded ||= $variable eq "WEBKIT_LIBRARIES" || $variable eq "WEBKIT_OUTPUTDIR"; - } - - if ($restartNeeded) { - print "Please restart your computer before attempting to build inside Visual Studio.\n\n"; - } - } else { - if (!defined $ENV{'WEBKIT_LIBRARIES'} || !$ENV{'WEBKIT_LIBRARIES'}) { - print "Warning: You must set the 'WebKit_Libraries' environment variable\n"; - print " to be able build WebKit from within Visual Studio 2013 and newer.\n"; - print " Make sure that 'WebKit_Libraries' points to the\n"; - print " 'WebKitLibraries/win' directory, not the 'WebKitLibraries/' directory.\n\n"; - } - if (!defined $ENV{'WEBKIT_OUTPUTDIR'} || !$ENV{'WEBKIT_OUTPUTDIR'}) { - print "Warning: You must set the 'WebKit_OutputDir' environment variable\n"; - print " to be able build WebKit from within Visual Studio 2013 and newer.\n\n"; - } - if (!defined $ENV{'MSBUILDDISABLENODEREUSE'} || !$ENV{'MSBUILDDISABLENODEREUSE'}) { - print "Warning: You should set the 'MSBUILDDISABLENODEREUSE' environment variable to '1'\n"; - print " to avoid periodic locked log files when building.\n\n"; - } - } - # FIXME (125180): Remove the following temporary 64-bit support once official support is available. - if (isWin64() and !$ENV{'WEBKIT_64_SUPPORT'}) { - print "Warning: You must set the 'WEBKIT_64_SUPPORT' environment variable\n"; - print " to be able run WebKit or JavaScriptCore tests.\n\n"; - } -} - -sub setupCygwinEnv() -{ - return if !isCygwin() && !isWindows(); - return if $vcBuildPath; - - my $programFilesPath = programFilesPath(); - my $visualStudioPath = File::Spec->catfile(visualStudioInstallDir(), qw(Common7 IDE devenv.com)); - if (-e $visualStudioPath) { - # Visual Studio is installed; - if (visualStudioVersion() eq "12") { - $visualStudioPath = File::Spec->catfile(visualStudioInstallDir(), qw(Common7 IDE devenv.exe)); - } - } else { - # Visual Studio not found, try VC++ Express - $visualStudioPath = File::Spec->catfile(visualStudioInstallDir(), qw(Common7 IDE WDExpress.exe)); - if (! -e $visualStudioPath) { - print "*************************************************************\n"; - print "Cannot find '$visualStudioPath'\n"; - print "Please execute the file 'vcvars32.bat' from\n"; - print "'$programFilesPath\\Microsoft Visual Studio 14.0\\VC\\bin\\'\n"; - print "to setup the necessary environment variables.\n"; - print "*************************************************************\n"; - die; - } - $willUseVCExpressWhenBuilding = 1; - } - - print "Building results into: ", baseProductDir(), "\n"; - print "WEBKIT_OUTPUTDIR is set to: ", $ENV{"WEBKIT_OUTPUTDIR"}, "\n"; - print "WEBKIT_LIBRARIES is set to: ", $ENV{"WEBKIT_LIBRARIES"}, "\n"; - # FIXME (125180): Remove the following temporary 64-bit support once official support is available. - print "WEBKIT_64_SUPPORT is set to: ", $ENV{"WEBKIT_64_SUPPORT"}, "\n" if isWin64(); - - # We will actually use MSBuild to build WebKit, but we need to find the Visual Studio install (above) to make - # sure we use the right options. - $vcBuildPath = File::Spec->catfile(msBuildInstallDir(), qw(MSBuild.exe)); - if (! -e $vcBuildPath) { - print "*************************************************************\n"; - print "Cannot find '$vcBuildPath'\n"; - print "Please make sure execute that the Microsoft .NET Framework SDK\n"; - print "is installed on this machine.\n"; - print "*************************************************************\n"; - die; - } -} - -sub dieIfWindowsPlatformSDKNotInstalled -{ - my $registry32Path = "/proc/registry/"; - my $registry64Path = "/proc/registry64/"; - my @windowsPlatformSDKRegistryEntries = ( - "HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Microsoft SDKs/Windows/v8.0A", - "HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Microsoft SDKs/Windows/v8.0", - "HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Microsoft SDKs/Windows/v7.1A", - "HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Microsoft SDKs/Windows/v7.0A", - "HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/MicrosoftSDK/InstalledSDKs/D2FF9F89-8AA2-4373-8A31-C838BF4DBBE1", - ); - - # FIXME: It would be better to detect whether we are using 32- or 64-bit Windows - # and only check the appropriate entry. But for now we just blindly check both. - my $recommendedPlatformSDK = $windowsPlatformSDKRegistryEntries[0]; - - while (@windowsPlatformSDKRegistryEntries) { - my $windowsPlatformSDKRegistryEntry = shift @windowsPlatformSDKRegistryEntries; - return if (-e $registry32Path . $windowsPlatformSDKRegistryEntry) || (-e $registry64Path . $windowsPlatformSDKRegistryEntry); - } - - print "*************************************************************\n"; - print "Cannot find registry entry '$recommendedPlatformSDK'.\n"; - print "Please download and install the Microsoft Windows SDK\n"; - print "from <http://www.microsoft.com/en-us/download/details.aspx?id=8279>.\n\n"; - print "Then follow step 2 in the Windows section of the \"Installing Developer\n"; - print "Tools\" instructions at <http://www.webkit.org/building/tools.html>.\n"; - print "*************************************************************\n"; - die; -} - -sub buildXCodeProject($$@) -{ - my ($project, $clean, @extraOptions) = @_; - - if ($clean) { - push(@extraOptions, "-alltargets"); - push(@extraOptions, "clean"); - } - - push(@extraOptions, ("-sdk", xcodeSDK())) if isIOSWebKit(); - - chomp($ENV{DSYMUTIL_NUM_THREADS} = `sysctl -n hw.activecpu`); - return system "xcodebuild", "-project", "$project.xcodeproj", @extraOptions; -} - -sub usingVisualStudioExpress() -{ - setupCygwinEnv(); - return $willUseVCExpressWhenBuilding; -} - -sub buildVisualStudioProject -{ - my ($project, $clean) = @_; - setupCygwinEnv(); - - my $config = configurationForVisualStudio(); - - dieIfWindowsPlatformSDKNotInstalled() if $willUseVCExpressWhenBuilding; - - chomp($project = `cygpath -w "$project"`) if isCygwin(); - - my $action = "/t:build"; - if ($clean) { - $action = "/t:clean"; - } - - my $platform = "/p:Platform=" . (isWin64() ? "x64" : "Win32"); - my $logPath = File::Spec->catdir($baseProductDir, $configuration); - make_path($logPath) unless -d $logPath or $logPath eq "."; - - my $errorLogFile = File::Spec->catfile($logPath, "webkit_errors.log"); - chomp($errorLogFile = `cygpath -w "$errorLogFile"`) if isCygwin(); - my $errorLogging = "/flp:LogFile=" . $errorLogFile . ";ErrorsOnly"; - - my $warningLogFile = File::Spec->catfile($logPath, "webkit_warnings.log"); - chomp($warningLogFile = `cygpath -w "$warningLogFile"`) if isCygwin(); - my $warningLogging = "/flp1:LogFile=" . $warningLogFile . ";WarningsOnly"; - - my @command = ($vcBuildPath, "/verbosity:minimal", $project, $action, $config, $platform, "/fl", $errorLogging, "/fl1", $warningLogging); - - print join(" ", @command), "\n"; - return system @command; -} - -sub getJhbuildPath() -{ - my @jhbuildPath = File::Spec->splitdir(baseProductDir()); - if (isGit() && isGitBranchBuild() && gitBranch()) { - pop(@jhbuildPath); - } - if (isEfl()) { - push(@jhbuildPath, "DependenciesEFL"); - } elsif (isGtk()) { - push(@jhbuildPath, "DependenciesGTK"); - } else { - die "Cannot get JHBuild path for platform that isn't GTK+ or EFL.\n"; - } - return File::Spec->catdir(@jhbuildPath); -} - -sub isCachedArgumentfileOutOfDate($@) -{ - my ($filename, $currentContents) = @_; - - if (! -e $filename) { - return 1; - } - - open(CONTENTS_FILE, $filename); - chomp(my $previousContents = <CONTENTS_FILE>); - close(CONTENTS_FILE); - - if ($previousContents ne $currentContents) { - print "Contents for file $filename have changed.\n"; - print "Previous contents were: $previousContents\n\n"; - print "New contents are: $currentContents\n"; - return 1; - } - - return 0; -} - -sub jhbuildWrapperPrefixIfNeeded() -{ - if (isWindows()) { - return (); - } - if (-e getJhbuildPath()) { - my @prefix = (File::Spec->catfile(sourceDir(), "Tools", "jhbuild", "jhbuild-wrapper")); - if (isEfl()) { - push(@prefix, "--efl"); - } elsif (isGtk()) { - push(@prefix, "--gtk"); - } - push(@prefix, "run"); - - return @prefix; - } - - return (); -} - -sub cmakeCachePath() -{ - return File::Spec->catdir(baseProductDir(), configuration(), "CMakeCache.txt"); -} - -sub shouldRemoveCMakeCache(@) -{ - my ($cacheFilePath, @buildArgs) = @_; - - # We check this first, because we always want to create this file for a fresh build. - my $productDir = File::Spec->catdir(baseProductDir(), configuration()); - my $optionsCache = File::Spec->catdir($productDir, "build-webkit-options.txt"); - my $joinedBuildArgs = join(" ", @buildArgs); - if (isCachedArgumentfileOutOfDate($optionsCache, $joinedBuildArgs)) { - File::Path::mkpath($productDir) unless -d $productDir; - open(CACHED_ARGUMENTS, ">", $optionsCache); - print CACHED_ARGUMENTS $joinedBuildArgs; - close(CACHED_ARGUMENTS); - - return 1; - } - - my $cmakeCache = cmakeCachePath(); - unless (-e $cmakeCache) { - return 0; - } - - my $cacheFileModifiedTime = stat($cmakeCache)->mtime; - my $platformConfiguration = File::Spec->catdir(sourceDir(), "Source", "cmake", "Options" . cmakeBasedPortName() . ".cmake"); - if ($cacheFileModifiedTime < stat($platformConfiguration)->mtime) { - return 1; - } - - my $globalConfiguration = File::Spec->catdir(sourceDir(), "Source", "cmake", "OptionsCommon.cmake"); - if ($cacheFileModifiedTime < stat($globalConfiguration)->mtime) { - return 1; - } - - my $inspectorUserInterfaceDircetory = File::Spec->catdir(sourceDir(), "Source", "WebInspectorUI", "UserInterface"); - if ($cacheFileModifiedTime < stat($inspectorUserInterfaceDircetory)->mtime) { - return 1; - } - - return 0; -} - -sub removeCMakeCache(@) -{ - my (@buildArgs) = @_; - if (shouldRemoveCMakeCache(@buildArgs)) { - my $cmakeCache = cmakeCachePath(); - unlink($cmakeCache) if -e $cmakeCache; - } -} - -sub canUseNinja(@) -{ - # Test both ninja and ninja-build. Fedora uses ninja-build and has patched CMake to also call ninja-build. - return commandExists("ninja") || commandExists("ninja-build"); -} - -sub canUseEclipse(@) -{ - return commandExists("eclipse"); -} - -sub cmakeGeneratedBuildfile(@) -{ - my ($willUseNinja) = @_; - if ($willUseNinja) { - return File::Spec->catfile(baseProductDir(), configuration(), "build.ninja") - } else { - return File::Spec->catfile(baseProductDir(), configuration(), "Makefile") - } -} - -sub generateBuildSystemFromCMakeProject -{ - my ($port, $prefixPath, @cmakeArgs, $additionalCMakeArgs) = @_; - my $config = configuration(); - my $buildPath = File::Spec->catdir(baseProductDir(), $config); - File::Path::mkpath($buildPath) unless -d $buildPath; - my $originalWorkingDirectory = getcwd(); - chdir($buildPath) or die; - - # We try to be smart about when to rerun cmake, so that we can have faster incremental builds. - my $willUseNinja = canUseNinja(); - if (-e cmakeCachePath() && -e cmakeGeneratedBuildfile($willUseNinja)) { - return 0; - } - - my @args; - push @args, "-DPORT=\"$port\""; - push @args, "-DCMAKE_INSTALL_PREFIX=\"$prefixPath\"" if $prefixPath; - push @args, "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON" if isGtk(); - if ($config =~ /release/i) { - push @args, "-DCMAKE_BUILD_TYPE=Release"; - } elsif ($config =~ /debug/i) { - push @args, "-DCMAKE_BUILD_TYPE=Debug"; - } - - if ($willUseNinja) { - push @args, "-G"; - if (canUseEclipse()) { - push @args, "'Eclipse CDT4 - Ninja'"; - } else { - push @args, "Ninja"; - } - } - - # GTK+ has a production mode, but build-webkit should always use developer mode. - push @args, "-DDEVELOPER_MODE=ON" if isEfl() || isGtk(); - - # Don't warn variables which aren't used by cmake ports. - push @args, "--no-warn-unused-cli"; - push @args, @cmakeArgs if @cmakeArgs; - push @args, $additionalCMakeArgs if $additionalCMakeArgs; - - push @args, '"' . sourceDir() . '"'; - - # Compiler options to keep floating point values consistent - # between 32-bit and 64-bit architectures. - determineArchitecture(); - if ($architecture ne "x86_64" && !isARM() && !isCrossCompilation() && !isWindows()) { - $ENV{'CXXFLAGS'} = "-march=pentium4 -msse2 -mfpmath=sse " . ($ENV{'CXXFLAGS'} || ""); - } - - # We call system("cmake @args") instead of system("cmake", @args) so that @args is - # parsed for shell metacharacters. - my $wrapper = join(" ", jhbuildWrapperPrefixIfNeeded()) . " "; - my $returnCode = system($wrapper . "cmake @args"); - - chdir($originalWorkingDirectory); - return $returnCode; -} - -sub buildCMakeGeneratedProject($) -{ - my ($makeArgs) = @_; - my $config = configuration(); - my $buildPath = File::Spec->catdir(baseProductDir(), $config); - if (! -d $buildPath) { - die "Must call generateBuildSystemFromCMakeProject() before building CMake project."; - } - - my $command = "cmake"; - my @args = ("--build", $buildPath, "--config", $config); - push @args, ("--", $makeArgs) if $makeArgs; - - # GTK can use a build script to preserve colors and pretty-printing. - if (isGtk() && -e "$buildPath/build.sh") { - chdir "$buildPath" or die; - $command = "$buildPath/build.sh"; - @args = ($makeArgs); - } - - if ($ENV{VERBOSE} && canUseNinja()) { - push @args, "-v"; - push @args, "-d keeprsp" if (version->parse(determineNinjaVersion()) >= version->parse("1.4.0")); - } - - # We call system("cmake @args") instead of system("cmake", @args) so that @args is - # parsed for shell metacharacters. In particular, $makeArgs may contain such metacharacters. - my $wrapper = join(" ", jhbuildWrapperPrefixIfNeeded()) . " "; - return system($wrapper . "$command @args"); - -} - -sub cleanCMakeGeneratedProject() -{ - my $config = configuration(); - my $buildPath = File::Spec->catdir(baseProductDir(), $config); - if (-d $buildPath) { - return system("cmake", "--build", $buildPath, "--config", $config, "--target", "clean"); - } - return 0; -} - -sub buildCMakeProjectOrExit($$$$@) -{ - my ($clean, $port, $prefixPath, $makeArgs, @cmakeArgs) = @_; - my $returnCode; - - exit(exitStatus(cleanCMakeGeneratedProject())) if $clean; - - if (isEfl() && checkForArgumentAndRemoveFromARGV("--update-efl")) { - system("perl", "$sourceDir/Tools/Scripts/update-webkitefl-libs") == 0 or die $!; - } - - if (isGtk() && checkForArgumentAndRemoveFromARGV("--update-gtk")) { - system("perl", "$sourceDir/Tools/Scripts/update-webkitgtk-libs") == 0 or die $!; - } - - $returnCode = exitStatus(generateBuildSystemFromCMakeProject($port, $prefixPath, @cmakeArgs)); - exit($returnCode) if $returnCode; - - $returnCode = exitStatus(buildCMakeGeneratedProject($makeArgs)); - exit($returnCode) if $returnCode; - return 0; -} - -sub cmakeBasedPortArguments() -{ - return (); -} - -sub cmakeBasedPortName() -{ - return "Efl" if isEfl(); - return "GTK" if isGtk(); - return ""; -} - -sub isCMakeBuild() -{ - return isEfl() || isGtk(); -} - -sub promptUser -{ - my ($prompt, $default) = @_; - my $defaultValue = $default ? "[$default]" : ""; - print "$prompt $defaultValue: "; - chomp(my $input = <STDIN>); - return $input ? $input : $default; -} - -sub appleApplicationSupportPath -{ - open INSTALL_DIR, "</proc/registry/HKEY_LOCAL_MACHINE/SOFTWARE/Apple\ Inc./Apple\ Application\ Support/InstallDir"; - my $path = <INSTALL_DIR>; - $path =~ s/[\r\n\x00].*//; - close INSTALL_DIR; - - my $unixPath = `cygpath -u '$path'`; - chomp $unixPath; - return $unixPath; -} - -sub setPathForRunningWebKitApp -{ - my ($env) = @_; - - if (isAppleWinWebKit()) { - $env->{PATH} = join(':', productDir(), appleApplicationSupportPath(), $env->{PATH} || ""); - } elsif (isWinCairo()) { - my $winCairoBin = sourceDir() . "/WebKitLibraries/win/" . (isWin64() ? "bin64/" : "bin32/"); - my $gstreamerBin = isWin64() ? $ENV{"GSTREAMER_1_0_ROOT_X86_64"} . "bin" : $ENV{"GSTREAMER_1_0_ROOT_X86"} . "bin"; - $env->{PATH} = join(':', productDir(), $winCairoBin, $gstreamerBin, $env->{PATH} || ""); - } -} - -sub printHelpAndExitForRunAndDebugWebKitAppIfNeeded -{ - return unless checkForArgumentAndRemoveFromARGV("--help"); - - my ($includeOptionsForDebugging) = @_; - - print STDERR <<EOF; -Usage: @{[basename($0)]} [options] [args ...] - --help Show this help message - --no-saved-state Launch the application without state restoration (OS X 10.7 and later) - -g|--guard-malloc Enable Guard Malloc (OS X only) - --use-web-process-xpc-service Launch the Web Process as an XPC Service (OS X only) -EOF - - if ($includeOptionsForDebugging) { - print STDERR <<EOF; - --target-web-process Debug the web process - --use-gdb Use GDB (this is the default when using Xcode 4.4 or earlier) - --use-lldb Use LLDB (this is the default when using Xcode 4.5 or later) -EOF - } - - exit(1); -} - -sub argumentsForRunAndDebugMacWebKitApp() -{ - my @args = (); - if (checkForArgumentAndRemoveFromARGV("--no-saved-state")) { - push @args, ("-ApplePersistenceIgnoreStateQuietly", "YES"); - # FIXME: Don't set ApplePersistenceIgnoreState once all supported OS versions respect ApplePersistenceIgnoreStateQuietly (rdar://15032886). - push @args, ("-ApplePersistenceIgnoreState", "YES"); - } - push @args, ("-WebKit2UseXPCServiceForWebProcess", "YES") if shouldUseXPCServiceForWebProcess(); - unshift @args, @ARGV; - - return @args; -} - -sub setupMacWebKitEnvironment($) -{ - my ($dyldFrameworkPath) = @_; - - $dyldFrameworkPath = File::Spec->rel2abs($dyldFrameworkPath); - - $ENV{DYLD_FRAMEWORK_PATH} = $ENV{DYLD_FRAMEWORK_PATH} ? join(":", $dyldFrameworkPath, $ENV{DYLD_FRAMEWORK_PATH}) : $dyldFrameworkPath; - $ENV{__XPC_DYLD_FRAMEWORK_PATH} = $dyldFrameworkPath; - $ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES"; - - setUpGuardMallocIfNeeded(); -} - -sub setupIOSWebKitEnvironment($) -{ - my ($dyldFrameworkPath) = @_; - $dyldFrameworkPath = File::Spec->rel2abs($dyldFrameworkPath); - - $ENV{DYLD_FRAMEWORK_PATH} = $dyldFrameworkPath; - $ENV{DYLD_LIBRARY_PATH} = $dyldFrameworkPath; - - setUpGuardMallocIfNeeded(); -} - -sub iosSimulatorApplicationsPath() -{ - return File::Spec->catdir(XcodeSDKPath(), "Applications"); -} - -sub installedMobileSafariBundle() -{ - return File::Spec->catfile(iosSimulatorApplicationsPath(), "MobileSafari.app"); -} - -sub mobileSafariBundle() -{ - determineConfigurationProductDir(); - - # Use MobileSafari.app in product directory if present. - if (isAppleMacWebKit() && -d "$configurationProductDir/MobileSafari.app") { - return "$configurationProductDir/MobileSafari.app"; - } - return installedMobileSafariBundle(); -} - -sub plistPathFromBundle($) -{ - my ($appBundle) = @_; - return "$appBundle/Info.plist" if -f "$appBundle/Info.plist"; # iOS app bundle - return "$appBundle/Contents/Info.plist" if -f "$appBundle/Contents/Info.plist"; # Mac app bundle - return ""; -} - -sub appIdentifierFromBundle($) -{ - my ($appBundle) = @_; - my $plistPath = File::Spec->rel2abs(plistPathFromBundle($appBundle)); # defaults(1) will complain if the specified path is not absolute. - chomp(my $bundleIdentifier = `defaults read '$plistPath' CFBundleIdentifier 2> /dev/null`); - return $bundleIdentifier; -} - -sub appDisplayNameFromBundle($) -{ - my ($appBundle) = @_; - my $plistPath = File::Spec->rel2abs(plistPathFromBundle($appBundle)); # defaults(1) will complain if the specified path is not absolute. - chomp(my $bundleDisplayName = `defaults read '$plistPath' CFBundleDisplayName 2> /dev/null`); - return $bundleDisplayName; -} - -sub waitUntilIOSSimulatorDeviceIsInState($$) -{ - my ($deviceUDID, $waitUntilState) = @_; - my $device = iosSimulatorDeviceByUDID($deviceUDID); - while ($device->{state} ne $waitUntilState) { - usleep(500 * 1000); # Waiting 500ms between file system polls does not make script run-safari feel sluggish. - $device = iosSimulatorDeviceByUDID($deviceUDID); - } -} - -sub relaunchIOSSimulator($) -{ - my ($simulatedDevice) = @_; - quitIOSSimulator($simulatedDevice->{UDID}); - - # FIXME: <rdar://problem/20916140> Switch to using CoreSimulator.framework for launching and quitting iOS Simulator - my $iosSimulatorBundleID = "com.apple.iphonesimulator"; - system("open", "-b", $iosSimulatorBundleID, "--args", "-CurrentDeviceUDID", $simulatedDevice->{UDID}) == 0 or die "Failed to open $iosSimulatorBundleID: $!"; - - waitUntilIOSSimulatorDeviceIsInState($simulatedDevice->{UDID}, SIMULATOR_DEVICE_STATE_BOOTED); -} - -sub quitIOSSimulator(;$) -{ - my ($waitForShutdownOfSimulatedDeviceUDID) = @_; - # FIXME: <rdar://problem/20916140> Switch to using CoreSimulator.framework for launching and quitting iOS Simulator - exitStatus(system {"osascript"} "osascript", "-e", 'tell application id "com.apple.iphonesimulator" to quit') == 0 or die "Failed to quit iOS Simulator: $!"; - if (!defined($waitForShutdownOfSimulatedDeviceUDID)) { - return; - } - # FIXME: We assume that $waitForShutdownOfSimulatedDeviceUDID was not booted using the simctl command line tool. - # Otherwise we will spin indefinitely since quiting the iOS Simulator will not shutdown this device. We - # should add a maximum time limit to wait for a device to shutdown and either return an error or die() - # on expiration of the time limit. - waitUntilIOSSimulatorDeviceIsInState($waitForShutdownOfSimulatedDeviceUDID, SIMULATOR_DEVICE_STATE_SHUTDOWN); -} - -sub iosSimulatorDeviceByName($) -{ - my ($simulatorName) = @_; - my $simulatorRuntime = iosSimulatorRuntime(); - my @devices = iOSSimulatorDevices(); - for my $device (@devices) { - if ($device->{name} eq $simulatorName && $device->{runtime} eq $simulatorRuntime) { - return $device; - } - } - return undef; -} - -sub iosSimulatorDeviceByUDID($) -{ - my ($simulatedDeviceUDID) = @_; - my $devicePlistPath = File::Spec->catfile(iOSSimulatorDevicesPath(), $simulatedDeviceUDID, "device.plist"); - if (!-f $devicePlistPath) { - return; - } - # FIXME: We should parse the device.plist file ourself and map the dictionary keys in it to known - # dictionary keys so as to decouple our representation of the plist from the actual structure - # of the plist, which may change. - eval "require Foundation"; - return Foundation::perlRefFromObjectRef(NSDictionary->dictionaryWithContentsOfFile_($devicePlistPath)); -} - -sub iosSimulatorRuntime() -{ - my $xcodeSDKVersion = xcodeSDKVersion(); - $xcodeSDKVersion =~ s/\./-/; - return "com.apple.CoreSimulator.SimRuntime.iOS-$xcodeSDKVersion"; -} - -sub findOrCreateSimulatorForIOSDevice($) -{ - my ($simulatorNameSuffix) = @_; - my $simulatorName; - my $simulatorDeviceType; - if (architecture() eq "x86_64") { - $simulatorName = "iPhone 5s " . $simulatorNameSuffix; - $simulatorDeviceType = "com.apple.CoreSimulator.SimDeviceType.iPhone-5s"; - } else { - $simulatorName = "iPhone 5 " . $simulatorNameSuffix; - $simulatorDeviceType = "com.apple.CoreSimulator.SimDeviceType.iPhone-5"; - } - my $simulatedDevice = iosSimulatorDeviceByName($simulatorName); - return $simulatedDevice if $simulatedDevice; - return createiOSSimulatorDevice($simulatorName, $simulatorDeviceType, iosSimulatorRuntime()); -} - -sub isIOSSimulatorSystemInstalledApp($) -{ - my ($appBundle) = @_; - my $simulatorApplicationsPath = realpath(iosSimulatorApplicationsPath()); - return substr(realpath($appBundle), 0, length($simulatorApplicationsPath)) eq $simulatorApplicationsPath; -} - -sub hasUserInstalledAppInSimulatorDevice($$) -{ - my ($appIdentifier, $simulatedDeviceUDID) = @_; - my $userInstalledAppPath = File::Spec->catfile($ENV{HOME}, "Library", "Developer", "CoreSimulator", "Devices", $simulatedDeviceUDID, "data", "Containers", "Bundle", "Application"); - if (!-d $userInstalledAppPath) { - return 0; # No user installed apps. - } - local @::userInstalledAppBundles; - my $wantedFunction = sub { - my $file = $_; - - # Ignore hidden files and directories. - if ($file =~ /^\../) { - $File::Find::prune = 1; - return; - } - - return if !-d $file || $file !~ /\.app$/; - push @::userInstalledAppBundles, $File::Find::name; - $File::Find::prune = 1; # Do not traverse contents of app bundle. - }; - find($wantedFunction, $userInstalledAppPath); - for my $userInstalledAppBundle (@::userInstalledAppBundles) { - if (appIdentifierFromBundle($userInstalledAppBundle) eq $appIdentifier) { - return 1; # Has user installed app. - } - } - return 0; # Does not have user installed app. -} - -sub isSimulatorDeviceBooted($) -{ - my ($simulatedDeviceUDID) = @_; - my $device = iosSimulatorDeviceByUDID($simulatedDeviceUDID); - return $device && $device->{state} eq SIMULATOR_DEVICE_STATE_BOOTED; -} - -sub runIOSWebKitAppInSimulator($;$) -{ - my ($appBundle, $simulatorOptions) = @_; - my $productDir = productDir(); - my $appDisplayName = appDisplayNameFromBundle($appBundle); - my $appIdentifier = appIdentifierFromBundle($appBundle); - my $simulatedDevice = findOrCreateSimulatorForIOSDevice("For WebKit Development"); - my $simulatedDeviceUDID = $simulatedDevice->{UDID}; - - my $willUseSystemInstalledApp = isIOSSimulatorSystemInstalledApp($appBundle); - if ($willUseSystemInstalledApp) { - if (hasUserInstalledAppInSimulatorDevice($appIdentifier, $simulatedDeviceUDID)) { - # Restore the system-installed app in the simulator device corresponding to $appBundle as it - # was previously overwritten with a custom built version of the app. - # FIXME: Only restore the system-installed version of the app instead of erasing all contents and settings. - print "Quitting iOS Simulator...\n"; - quitIOSSimulator($simulatedDeviceUDID); - print "Erasing contents and settings for simulator device \"$simulatedDevice->{name}\".\n"; - exitStatus(system("xcrun", "--sdk", "iphonesimulator", "simctl", "erase", $simulatedDeviceUDID)) == 0 or die; - } - # FIXME: We assume that if $simulatedDeviceUDID is not booted then iOS Simulator is not open. However - # $simulatedDeviceUDID may have been booted using the simctl command line tool. If $simulatedDeviceUDID - # was booted using simctl then we should shutdown the device and launch iOS Simulator to boot it again. - if (!isSimulatorDeviceBooted($simulatedDeviceUDID)) { - print "Launching iOS Simulator...\n"; - relaunchIOSSimulator($simulatedDevice); - } - } else { - # FIXME: We should killall(1) any running instances of $appBundle before installing it to ensure - # that simctl launch opens the latest installed version of the app. For now we quit and - # launch the iOS Simulator again to ensure there are no running instances of $appBundle. - print "Quitting and launching iOS Simulator...\n"; - relaunchIOSSimulator($simulatedDevice); - - print "Installing $appBundle.\n"; - # Install custom built app, overwriting an app with the same app identifier if one exists. - exitStatus(system("xcrun", "--sdk", "iphonesimulator", "simctl", "install", $simulatedDeviceUDID, $appBundle)) == 0 or die; - - } - - $simulatorOptions = {} unless $simulatorOptions; - - my %simulatorENV; - %simulatorENV = %{$simulatorOptions->{applicationEnvironment}} if $simulatorOptions->{applicationEnvironment}; - { - local %ENV; # Shadow global-scope %ENV so that changes to it will not be seen outside of this scope. - setupIOSWebKitEnvironment($productDir); - %simulatorENV = %ENV; - } - my $applicationArguments = \@ARGV; - $applicationArguments = $simulatorOptions->{applicationArguments} if $simulatorOptions && $simulatorOptions->{applicationArguments}; - - # Prefix the environment variables with SIMCTL_CHILD_ per `xcrun simctl help launch`. - foreach my $key (keys %simulatorENV) { - $ENV{"SIMCTL_CHILD_$key"} = $simulatorENV{$key}; - } - - print "Starting $appDisplayName with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n"; - return exitStatus(system("xcrun", "--sdk", "iphonesimulator", "simctl", "launch", $simulatedDeviceUDID, $appIdentifier, @$applicationArguments)); -} - -sub runIOSWebKitApp($) -{ - my ($appBundle) = @_; - if (willUseIOSDeviceSDKWhenBuilding()) { - die "Only running Safari in iOS Simulator is supported now."; - } - if (willUseIOSSimulatorSDKWhenBuilding()) { - return runIOSWebKitAppInSimulator($appBundle); - } - die "Not using an iOS SDK." -} - -sub runMacWebKitApp($;$) -{ - my ($appPath, $useOpenCommand) = @_; - my $productDir = productDir(); - print "Starting @{[basename($appPath)]} with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n"; - - local %ENV = %ENV; - setupMacWebKitEnvironment($productDir); - - if (defined($useOpenCommand) && $useOpenCommand == USE_OPEN_COMMAND) { - return system("open", "-W", "-a", $appPath, "--args", argumentsForRunAndDebugMacWebKitApp()); - } - if (architecture()) { - return system "arch", "-" . architecture(), $appPath, argumentsForRunAndDebugMacWebKitApp(); - } - return system { $appPath } $appPath, argumentsForRunAndDebugMacWebKitApp(); -} - -sub execMacWebKitAppForDebugging($) -{ - my ($appPath) = @_; - my $architectureSwitch; - my $argumentsSeparator; - - if (debugger() eq "lldb") { - $architectureSwitch = "--arch"; - $argumentsSeparator = "--"; - } elsif (debugger() eq "gdb") { - $architectureSwitch = "-arch"; - $argumentsSeparator = "--args"; - } else { - die "Unknown debugger $debugger.\n"; - } - - my $debuggerPath = `xcrun -find $debugger`; - chomp $debuggerPath; - die "Can't find the $debugger executable.\n" unless -x $debuggerPath; - - my $productDir = productDir(); - setupMacWebKitEnvironment($productDir); - - my @architectureFlags = ($architectureSwitch, architecture()); - if (!shouldTargetWebProcess()) { - print "Starting @{[basename($appPath)]} under $debugger with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n"; - exec { $debuggerPath } $debuggerPath, @architectureFlags, $argumentsSeparator, $appPath, argumentsForRunAndDebugMacWebKitApp() or die; - } else { - if (shouldUseXPCServiceForWebProcess()) { - die "Targeting the Web Process is not compatible with using an XPC Service for the Web Process at this time."; - } - - my $webProcessShimPath = File::Spec->catfile($productDir, "SecItemShim.dylib"); - my $webProcessPath = File::Spec->catdir($productDir, "WebProcess.app"); - my $webKit2ExecutablePath = File::Spec->catfile($productDir, "WebKit2.framework", "WebKit2"); - - appendToEnvironmentVariableList("DYLD_INSERT_LIBRARIES", $webProcessShimPath); - - print "Starting WebProcess under $debugger with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n"; - exec { $debuggerPath } $debuggerPath, @architectureFlags, $argumentsSeparator, $webProcessPath, $webKit2ExecutablePath, "-type", "webprocess", "-client-executable", $appPath or die; - } -} - -sub debugSafari -{ - if (isAppleMacWebKit()) { - checkFrameworks(); - execMacWebKitAppForDebugging(safariPath()); - } - - return 1; # Unsupported platform; can't debug Safari on this platform. -} - -sub runSafari -{ - if (isIOSWebKit()) { - return runIOSWebKitApp(mobileSafariBundle()); - } - - if (isAppleMacWebKit()) { - return runMacWebKitApp(safariPath()); - } - - if (isAppleWinWebKit()) { - my $result; - my $productDir = productDir(); - my $webKitLauncherPath = File::Spec->catfile(productDir(), "WinLauncher.exe"); - return system { $webKitLauncherPath } $webKitLauncherPath, @ARGV; - } - - return 1; # Unsupported platform; can't run Safari on this platform. -} - -sub runMiniBrowser -{ - if (isAppleMacWebKit()) { - return runMacWebKitApp(File::Spec->catfile(productDir(), "MiniBrowser.app", "Contents", "MacOS", "MiniBrowser")); - } - - return 1; -} - -sub debugMiniBrowser -{ - if (isAppleMacWebKit()) { - execMacWebKitAppForDebugging(File::Spec->catfile(productDir(), "MiniBrowser.app", "Contents", "MacOS", "MiniBrowser")); - } - - return 1; -} - -sub runWebKitTestRunner -{ - if (isAppleMacWebKit()) { - return runMacWebKitApp(File::Spec->catfile(productDir(), "WebKitTestRunner")); - } - - return 1; -} - -sub debugWebKitTestRunner -{ - if (isAppleMacWebKit()) { - execMacWebKitAppForDebugging(File::Spec->catfile(productDir(), "WebKitTestRunner")); - } - - return 1; -} - -sub readRegistryString -{ - my ($valueName) = @_; - chomp(my $string = `regtool --wow32 get "$valueName"`); - return $string; -} - -sub writeRegistryString -{ - my ($valueName, $string) = @_; - - my $error = system "regtool", "--wow32", "set", "-s", $valueName, $string; - - # On Windows Vista/7 with UAC enabled, regtool will fail to modify the registry, but will still - # return a successful exit code. So we double-check here that the value we tried to write to the - # registry was really written. - return !$error && readRegistryString($valueName) eq $string; -} - -sub formatBuildTime($) -{ - my ($buildTime) = @_; - - my $buildHours = int($buildTime / 3600); - my $buildMins = int(($buildTime - $buildHours * 3600) / 60); - my $buildSecs = $buildTime - $buildHours * 3600 - $buildMins * 60; - - if ($buildHours) { - return sprintf("%dh:%02dm:%02ds", $buildHours, $buildMins, $buildSecs); - } - return sprintf("%02dm:%02ds", $buildMins, $buildSecs); -} - -sub runSvnUpdateAndResolveChangeLogs(@) -{ - my @svnOptions = @_; - my $openCommand = "svn update " . join(" ", @svnOptions); - open my $update, "$openCommand |" or die "cannot execute command $openCommand"; - my @conflictedChangeLogs; - while (my $line = <$update>) { - print $line; - $line =~ m/^C\s+(.+?)[\r\n]*$/; - if ($1) { - my $filename = normalizePath($1); - push @conflictedChangeLogs, $filename if basename($filename) eq "ChangeLog"; - } - } - close $update or die; - - if (@conflictedChangeLogs) { - print "Attempting to merge conflicted ChangeLogs.\n"; - my $resolveChangeLogsPath = File::Spec->catfile(sourceDir(), "Tools", "Scripts", "resolve-ChangeLogs"); - (system($resolveChangeLogsPath, "--no-warnings", @conflictedChangeLogs) == 0) - or die "Could not open resolve-ChangeLogs script: $!.\n"; - } -} - -sub runGitUpdate() -{ - # Doing a git fetch first allows setups with svn-remote.svn.fetch = trunk:refs/remotes/origin/master - # to perform the rebase much much faster. - system("git", "fetch"); - if (isGitSVNDirectory(".")) { - system("git", "svn", "rebase") == 0 or die; - } else { - # This will die if branch.$BRANCHNAME.merge isn't set, which is - # almost certainly what we want. - system("git", "pull") == 0 or die; - } -} - -1; |