#!/usr/bin/env perl # Copyright (C) 2005, 2013 Apple Inc. All rights reserved. # Copyright (C) 2007 Eric Seidel # # 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. use strict; use warnings; use FindBin; use Getopt::Long qw(:config pass_through); use lib $FindBin::Bin; use webkitdirs; use webkitperl::FeatureList qw(getFeatureOptionList); use POSIX; use Text::ParseWords; sub writeCongrats(); prohibitUnknownPort(); if (shouldUseFlatpak()) { print "Building flatpak based environment\n"; my @command = (File::Spec->catfile(sourceDir(), "Tools", "Scripts", "build-jsc")); runInFlatpak(@command); } my $shouldRunStaticAnalyzer = 0; my $minimal = 0; my $coverageSupport = 0; my $showHelp = 0; my $ftlJIT = int(isAppleCocoaWebKit() && !willUseIOSSimulatorSDK() || ((isARM64() || isX86_64()) && (isGtk() || isJSCOnly()))); my $forceCLoop = 0; my $cli = 0; my $makeArgs = ""; my @cmakeArgs; my $buildDir = ""; my $startTime = time(); my $useCCache = -1; my @features = getFeatureOptionList(); # Initialize values from defaults foreach (@ARGV) { if ($_ eq '--minimal') { $minimal = 1; } } # Initialize values from defaults foreach (@features) { ${$_->{value}} = ($minimal ? 0 : $_->{default}); } # Additional environment parameters push @ARGV, parse_line('\s+', 0, $ENV{'BUILD_JSC_ARGS'}) if ($ENV{'BUILD_JSC_ARGS'}); my $programName = basename($0); my $usage = < Optional Makefile flags --cmakeargs= One or more optional CMake flags (e.g. --cmakeargs="-DFOO=bar -DCMAKE_PREFIX_PATH=/usr/local") --build-dir= Build out of tree in directory at --[no-]use-ccache Enable (or disable) CCache, if available EOF my %options = ( 'analyze!' => \$shouldRunStaticAnalyzer, 'coverage!' => \$coverageSupport, 'help' => \$showHelp, 'ftl-jit!' => \$ftlJIT, 'cloop!' => \$forceCLoop, 'cli!' => \$cli, 'makeargs=s' => \$makeArgs, 'cmakeargs=s' => \@cmakeArgs, 'build-dir=s' => \$buildDir, 'use-ccache!' => \$useCCache ); foreach (@features) { if ($_->{javascript}) { my $opt = sprintf("%-35s", " --[no-]$_->{option}"); $usage .= "$opt $_->{desc} (default: $_->{default})\n"; $options{"$_->{option}!"} = $_->{value}; } } GetOptions(%options); if ($showHelp) { print STDERR $usage; exit 1; } if (isAnyWindows()) { $ftlJIT = 0; } if ($buildDir && !isCMakeBuild()) { print STDERR "--build-dir is currently only supported for cmake builds"; exit 1; } if (isWinCairo() || (isJSCOnly() && isWindows())) { (system("python Tools/Scripts/update-webkit-wincairo-libs.py") == 0) or die; } if ($useCCache == 1) { $ENV{'WK_USE_CCACHE'} = "YES"; } elsif ($useCCache == 0) { $ENV{'WK_USE_CCACHE'} = "NO"; } checkRequiredSystemConfig(); setConfiguration(); chdirWebKit(); my @options = XcodeOptions(); my @additionalSupportOptions = (); push @additionalSupportOptions, XcodeCoverageSupportOptions() if $coverageSupport; push @additionalSupportOptions, XcodeStaticAnalyzerOption() if $shouldRunStaticAnalyzer; if ($forceCLoop) { $ftlJIT = 0; } if (isCMakeBuild()) { if (scalar(@ARGV) > 0) { foreach (@ARGV) { my $arg = $_; if ($arg =~ /^-.*/) { print STDERR "Unrecognized option `$arg'\n"; } else { print STDERR "Stray anonymous argument `$arg'\n"; } } exit 2; } if ($forceCLoop) { push @cmakeArgs, " -DENABLE_JIT=OFF"; push @cmakeArgs, " -DENABLE_C_LOOP=ON"; } push @cmakeArgs, $ftlJIT ? " -DENABLE_FTL_JIT=ON" : " -DENABLE_FTL_JIT=OFF"; if ($buildDir) { push @cmakeArgs, " " . sourceDir(); setBaseProductDir($buildDir); } my @featureArgs = cmakeArgsFromFeatures(@features); my $buildTarget = ""; unless (isAnyWindows()) { # By default we build using all of the available CPUs $makeArgs .= ($makeArgs ? " " : "") . "-j" . numberOfCPUs() if $makeArgs !~ /-j\s*\d+/; $buildTarget = "jsc testb3 testair testapi testmasm testdfg $makeArgs"; } elsif (canUseNinja()) { $buildTarget .= "jsc testapi testmasm"; } # This call only returns if nothing wrong happened buildCMakeProjectOrExit(0, undef, $buildTarget, @featureArgs, @cmakeArgs); writeCongrats(); exit exitStatus(0); } if (isAppleCocoaWebKit()) { push @options, ($forceCLoop ? "ENABLE_JIT=ENABLE_JIT=0" : "ENABLE_JIT=ENABLE_JIT"); push @options, ($forceCLoop ? "ENABLE_C_LOOP=ENABLE_C_LOOP" : "ENABLE_C_LOOP=ENABLE_C_LOOP=0"); push @options, ($ftlJIT ? "ENABLE_FTL_JIT=ENABLE_FTL_JIT" : "ENABLE_FTL_JIT=ENABLE_FTL_JIT=0"); sub option($$$) { my ($feature, $isEnabled, $defaultValue) = @_; return "" if $defaultValue == $isEnabled; return $feature . "=" . ($isEnabled ? $feature : ""); } foreach (@features) { if ($_->{javascript}) { my $option = option($_->{define}, ${$_->{value}}, $_->{default}); push @options, $option unless $option eq ""; } } } sub buildMyProject { my ($projectDirectory, $projectName) = @_; my $result; chdir $projectDirectory or die "Can't find $projectName directory to build from"; if (isAppleCocoaWebKit()) { my $compilerFlags = 'GCC_PREPROCESSOR_ADDITIONS="'; if ($forceCLoop) { $compilerFlags .= "ENABLE_JIT=0 ENABLE_C_LOOP=1"; } $compilerFlags .= '"'; my $extraCommands = ""; foreach (@ARGV) { # Ensure that if somebody passes in a flag like `ARCHS="i386 x86_64"` we # maintain the quotes around "i386 x86_64". my $arg = $_; if ($arg =~ m/=/) { $arg =~ s/=/="/; $arg = $arg . "\""; } $extraCommands .= " " . $arg; } my $command = "make " . (lc configuration()) . " " . $compilerFlags . " " . $extraCommands; print "\n"; print "building ", $projectName, "\n"; print "running build command '", $command, "' in ", $projectDirectory, "\n\n"; $result = system $command; } else { die "Building not defined for this platform!\n"; } exit exitStatus($result) if exitStatus($result); chdirWebKit(); } sub writeCongrats() { my $endTime = time(); my $buildTime = formatBuildTime($endTime - $startTime); print "\n"; print "====================================================================\n"; print " JavaScriptCore is now built ($buildTime). \n"; print "====================================================================\n"; } buildMyProject("Source/bmalloc", "bmalloc"); buildMyProject("Source/WTF", "WTF"); buildMyProject("Source/JavaScriptCore", "JavaScriptCore"); if (isAppleCocoaWebKit()) { writeCongrats(); } if (isAppleCocoaWebKit() && $cli) { buildMyProject("Tools/jsc-cli", "jsc-cli"); }