webkitdirs.pm 84 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633
  1. # Copyright (C) 2005, 2006, 2007, 2010, 2011, 2012 Apple Inc. All rights reserved.
  2. # Copyright (C) 2009 Google Inc. All rights reserved.
  3. # Copyright (C) 2011 Research In Motion Limited. All rights reserved.
  4. #
  5. # Redistribution and use in source and binary forms, with or without
  6. # modification, are permitted provided that the following conditions
  7. # are met:
  8. #
  9. # 1. Redistributions of source code must retain the above copyright
  10. # notice, this list of conditions and the following disclaimer.
  11. # 2. Redistributions in binary form must reproduce the above copyright
  12. # notice, this list of conditions and the following disclaimer in the
  13. # documentation and/or other materials provided with the distribution.
  14. # 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
  15. # its contributors may be used to endorse or promote products derived
  16. # from this software without specific prior written permission.
  17. #
  18. # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
  19. # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. # DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
  22. # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23. # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24. # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  25. # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  27. # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. # Module to share code to get to WebKit directories.
  29. use strict;
  30. use version;
  31. use warnings;
  32. use Config;
  33. use Digest::MD5 qw(md5_hex);
  34. use FindBin;
  35. use File::Basename;
  36. use File::Path qw(mkpath rmtree);
  37. use File::Spec;
  38. use File::stat;
  39. use POSIX;
  40. use VCSUtils;
  41. use sony::playstation;
  42. BEGIN {
  43. use Exporter ();
  44. our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
  45. $VERSION = 1.00;
  46. @ISA = qw(Exporter);
  47. @EXPORT = qw(
  48. &XcodeOptionString
  49. &XcodeOptionStringNoConfig
  50. &XcodeOptions
  51. &baseProductDir
  52. &chdirWebKit
  53. &checkFrameworks
  54. &cmakeBasedPortArguments
  55. &cmakeBasedPortName
  56. &currentSVNRevision
  57. &debugSafari
  58. &nmPath
  59. &passedConfiguration
  60. &printHelpAndExitForRunAndDebugWebKitAppIfNeeded
  61. &productDir
  62. &runMacWebKitApp
  63. &safariPath
  64. &setConfiguration
  65. USE_OPEN_COMMAND
  66. );
  67. %EXPORT_TAGS = ( );
  68. @EXPORT_OK = ();
  69. }
  70. use constant USE_OPEN_COMMAND => 1; # Used in runMacWebKitApp().
  71. use constant INCLUDE_OPTIONS_FOR_DEBUGGING => 1;
  72. our @EXPORT_OK;
  73. my $architecture;
  74. my $numberOfCPUs;
  75. my $baseProductDir;
  76. my @baseProductDirOption;
  77. my $configuration;
  78. my $xcodeSDK;
  79. my $configurationForVisualStudio;
  80. my $configurationProductDir;
  81. my $sourceDir;
  82. my $currentSVNRevision;
  83. my $debugger;
  84. my $nmPath;
  85. my $osXVersion;
  86. my $generateDsym;
  87. my $isQt;
  88. my $qmakebin = "qmake"; # Allow override of the qmake binary from $PATH
  89. my $isGtk;
  90. my $isWinCE;
  91. my $isWinCairo;
  92. my $isEfl;
  93. my $isBlackBerry;
  94. my $isInspectorFrontend;
  95. my $isWK2;
  96. my $shouldTargetWebProcess;
  97. my $shouldUseXPCServiceForWebProcess;
  98. my $shouldUseGuardMalloc;
  99. my $xcodeVersion;
  100. # Variables for Win32 support
  101. my $programFilesPath;
  102. my $vcBuildPath;
  103. my $vsInstallDir;
  104. my $vsVersion;
  105. my $windowsSourceDir;
  106. my $winVersion;
  107. my $willUseVCExpressWhenBuilding = 0;
  108. # Defined in VCSUtils.
  109. sub exitStatus($);
  110. sub determineSourceDir
  111. {
  112. return if $sourceDir;
  113. $sourceDir = $FindBin::Bin;
  114. $sourceDir =~ s|/+$||; # Remove trailing '/' as we would die later
  115. # walks up path checking each directory to see if it is the main WebKit project dir,
  116. # defined by containing Sources, WebCore, and WebKit
  117. until ((-d "$sourceDir/Source" && -d "$sourceDir/Source/WebCore" && -d "$sourceDir/Source/WebKit") || (-d "$sourceDir/Internal" && -d "$sourceDir/OpenSource"))
  118. {
  119. if ($sourceDir !~ s|/[^/]+$||) {
  120. die "Could not find top level webkit directory above source directory using FindBin.\n";
  121. }
  122. }
  123. $sourceDir = "$sourceDir/OpenSource" if -d "$sourceDir/OpenSource";
  124. }
  125. sub currentPerlPath()
  126. {
  127. my $thisPerl = $^X;
  128. if ($^O ne 'VMS') {
  129. $thisPerl .= $Config{_exe} unless $thisPerl =~ m/$Config{_exe}$/i;
  130. }
  131. return $thisPerl;
  132. }
  133. sub setQmakeBinaryPath($)
  134. {
  135. ($qmakebin) = @_;
  136. }
  137. # used for scripts which are stored in a non-standard location
  138. sub setSourceDir($)
  139. {
  140. ($sourceDir) = @_;
  141. }
  142. sub determineXcodeVersion
  143. {
  144. return if defined $xcodeVersion;
  145. my $xcodebuildVersionOutput = `xcodebuild -version`;
  146. $xcodeVersion = ($xcodebuildVersionOutput =~ /Xcode ([0-9](\.[0-9]+)*)/) ? $1 : "3.0";
  147. }
  148. sub readXcodeUserDefault($)
  149. {
  150. my ($unprefixedKey) = @_;
  151. determineXcodeVersion();
  152. my $xcodeDefaultsDomain = (eval "v$xcodeVersion" lt v4) ? "com.apple.Xcode" : "com.apple.dt.Xcode";
  153. my $xcodeDefaultsPrefix = (eval "v$xcodeVersion" lt v4) ? "PBX" : "IDE";
  154. my $devnull = File::Spec->devnull();
  155. my $value = `defaults read $xcodeDefaultsDomain ${xcodeDefaultsPrefix}${unprefixedKey} 2> ${devnull}`;
  156. return if $?;
  157. chomp $value;
  158. return $value;
  159. }
  160. sub determineBaseProductDir
  161. {
  162. return if defined $baseProductDir;
  163. determineSourceDir();
  164. my $setSharedPrecompsDir;
  165. # FIXME: See https://bugs.webkit.org/show_bug.cgi?id=117249.
  166. # Once all ports have migrated to WEBKIT_OUTPUTDIR, we can stop
  167. # reading the WEBKITOUTPUTDIR environment variable.
  168. $baseProductDir = $ENV{"WEBKIT_OUTPUTDIR"};
  169. $baseProductDir = $ENV{"WEBKITOUTPUTDIR"} if not $baseProductDir;
  170. if (!defined($baseProductDir) and isAppleMacWebKit()) {
  171. # Silently remove ~/Library/Preferences/xcodebuild.plist which can
  172. # cause build failure. The presence of
  173. # ~/Library/Preferences/xcodebuild.plist can prevent xcodebuild from
  174. # respecting global settings such as a custom build products directory
  175. # (<rdar://problem/5585899>).
  176. my $personalPlistFile = $ENV{HOME} . "/Library/Preferences/xcodebuild.plist";
  177. if (-e $personalPlistFile) {
  178. unlink($personalPlistFile) || die "Could not delete $personalPlistFile: $!";
  179. }
  180. determineXcodeVersion();
  181. if (eval "v$xcodeVersion" ge v4) {
  182. my $buildLocationStyle = join '', readXcodeUserDefault("BuildLocationStyle");
  183. if ($buildLocationStyle eq "Custom") {
  184. my $buildLocationType = join '', readXcodeUserDefault("CustomBuildLocationType");
  185. # FIXME: Read CustomBuildIntermediatesPath and set OBJROOT accordingly.
  186. $baseProductDir = readXcodeUserDefault("CustomBuildProductsPath") if $buildLocationType eq "Absolute";
  187. }
  188. # DeterminedByTargets corresponds to a setting of "Legacy" in Xcode.
  189. # It is the only build location style for which SHARED_PRECOMPS_DIR is not
  190. # overridden when building from within Xcode.
  191. $setSharedPrecompsDir = 1 if $buildLocationStyle ne "DeterminedByTargets";
  192. }
  193. if (!defined($baseProductDir)) {
  194. $baseProductDir = join '', readXcodeUserDefault("ApplicationwideBuildSettings");
  195. $baseProductDir = $1 if $baseProductDir =~ /SYMROOT\s*=\s*\"(.*?)\";/s;
  196. }
  197. undef $baseProductDir unless $baseProductDir =~ /^\//;
  198. } elsif (isPS3()) {
  199. $baseProductDir = "$sourceDir/Source/out";
  200. } elsif (isPSVita()) {
  201. $baseProductDir = "$sourceDir/../dist";
  202. }
  203. if (!defined($baseProductDir)) { # Port-specific checks failed, use default
  204. $baseProductDir = "$sourceDir/WebKitBuild";
  205. }
  206. if (isBlackBerry()) {
  207. my %archInfo = blackberryTargetArchitecture();
  208. $baseProductDir = "$baseProductDir/" . $archInfo{"cpuDir"};
  209. }
  210. if (isGit() && isGitBranchBuild()) {
  211. my $branch = gitBranch();
  212. $baseProductDir = "$baseProductDir/$branch";
  213. }
  214. if (isAppleMacWebKit()) {
  215. $baseProductDir =~ s|^\Q$(SRCROOT)/..\E$|$sourceDir|;
  216. $baseProductDir =~ s|^\Q$(SRCROOT)/../|$sourceDir/|;
  217. $baseProductDir =~ s|^~/|$ENV{HOME}/|;
  218. die "Can't handle Xcode product directory with a ~ in it.\n" if $baseProductDir =~ /~/;
  219. die "Can't handle Xcode product directory with a variable in it.\n" if $baseProductDir =~ /\$/;
  220. @baseProductDirOption = ("SYMROOT=$baseProductDir", "OBJROOT=$baseProductDir");
  221. push(@baseProductDirOption, "SHARED_PRECOMPS_DIR=${baseProductDir}/PrecompiledHeaders") if $setSharedPrecompsDir;
  222. }
  223. if (isCygwin()) {
  224. my $dosBuildPath = `cygpath --windows \"$baseProductDir\"`;
  225. chomp $dosBuildPath;
  226. $ENV{"WEBKIT_OUTPUTDIR"} = $dosBuildPath;
  227. my $unixBuildPath = `cygpath --unix \"$baseProductDir\"`;
  228. chomp $unixBuildPath;
  229. $baseProductDir = $unixBuildPath;
  230. }
  231. }
  232. sub setBaseProductDir($)
  233. {
  234. ($baseProductDir) = @_;
  235. }
  236. sub determineConfiguration
  237. {
  238. return if defined $configuration;
  239. determineBaseProductDir();
  240. if (open CONFIGURATION, "$baseProductDir/Configuration") {
  241. $configuration = <CONFIGURATION>;
  242. close CONFIGURATION;
  243. }
  244. if ($configuration) {
  245. chomp $configuration;
  246. # compatibility for people who have old Configuration files
  247. $configuration = "Release" if $configuration eq "Deployment";
  248. $configuration = "Debug" if $configuration eq "Development";
  249. } else {
  250. $configuration = "Release";
  251. }
  252. if ($configuration && isWinCairo()) {
  253. unless ($configuration =~ /_WinCairo$/) {
  254. $configuration .= "_WinCairo";
  255. }
  256. }
  257. if (isPS3()) {
  258. $configuration = "";
  259. if (open(CONFIGURATION, "$baseProductDir/Production")) {
  260. $configuration = <CONFIGURATION>;
  261. close CONFIGURATION;
  262. }
  263. if (!$configuration && open(CONFIGURATION, "$baseProductDir/Debug")) {
  264. $configuration = <CONFIGURATION>;
  265. close CONFIGURATION;
  266. }
  267. if (!$configuration) {
  268. $configuration = "Production";
  269. }
  270. }
  271. }
  272. sub determineArchitecture
  273. {
  274. return if defined $architecture;
  275. # make sure $architecture is defined in all cases
  276. $architecture = "";
  277. determineBaseProductDir();
  278. determineXcodeSDK();
  279. if (isGtk()) {
  280. determineConfigurationProductDir();
  281. my $host_triple = `grep -E '^host = ' $configurationProductDir/GNUmakefile`;
  282. if ($host_triple =~ m/^host = ([^-]+)-/) {
  283. # We have a configured build tree; use it.
  284. $architecture = $1;
  285. }
  286. } elsif (isAppleMacWebKit()) {
  287. if (open ARCHITECTURE, "$baseProductDir/Architecture") {
  288. $architecture = <ARCHITECTURE>;
  289. close ARCHITECTURE;
  290. }
  291. if ($architecture) {
  292. chomp $architecture;
  293. } else {
  294. if (not defined $xcodeSDK or $xcodeSDK =~ /^(\/$|macosx)/) {
  295. my $supports64Bit = `sysctl -n hw.optional.x86_64`;
  296. chomp $supports64Bit;
  297. $architecture = 'x86_64' if $supports64Bit;
  298. } elsif ($xcodeSDK =~ /^iphonesimulator/) {
  299. $architecture = 'i386';
  300. } elsif ($xcodeSDK =~ /^iphoneos/) {
  301. $architecture = 'armv7';
  302. }
  303. }
  304. } elsif (isEfl()) {
  305. my $host_processor = "";
  306. $host_processor = `cmake --system-information | grep CMAKE_SYSTEM_PROCESSOR`;
  307. if ($host_processor =~ m/^CMAKE_SYSTEM_PROCESSOR \"([^"]+)\"/) {
  308. # We have a configured build tree; use it.
  309. $architecture = $1;
  310. $architecture = 'x86_64' if $architecture eq 'amd64';
  311. }
  312. }
  313. if (!$architecture && (isGtk() || isAppleMacWebKit() || isEfl())) {
  314. # Fall back to output of `arch', if it is present.
  315. $architecture = `arch`;
  316. chomp $architecture;
  317. }
  318. if (!$architecture && (isGtk() || isAppleMacWebKit() || isEfl())) {
  319. # Fall back to output of `uname -m', if it is present.
  320. $architecture = `uname -m`;
  321. chomp $architecture;
  322. }
  323. }
  324. sub determineNumberOfCPUs
  325. {
  326. return if defined $numberOfCPUs;
  327. if (defined($ENV{NUMBER_OF_PROCESSORS})) {
  328. $numberOfCPUs = $ENV{NUMBER_OF_PROCESSORS};
  329. } elsif (isLinux()) {
  330. # First try the nproc utility, if it exists. If we get no
  331. # results fall back to just interpretting /proc directly.
  332. chomp($numberOfCPUs = `nproc --all 2> /dev/null`);
  333. if ($numberOfCPUs eq "") {
  334. $numberOfCPUs = (grep /processor/, `cat /proc/cpuinfo`);
  335. }
  336. } elsif (isWindows() || isCygwin()) {
  337. # Assumes cygwin
  338. $numberOfCPUs = `ls /proc/registry/HKEY_LOCAL_MACHINE/HARDWARE/DESCRIPTION/System/CentralProcessor | wc -w`;
  339. } elsif (isDarwin() || isFreeBSD()) {
  340. chomp($numberOfCPUs = `sysctl -n hw.ncpu`);
  341. }
  342. }
  343. sub jscPath($)
  344. {
  345. my ($productDir) = @_;
  346. my $jscName = "jsc";
  347. $jscName .= "_debug" if configurationForVisualStudio() eq "Debug_All";
  348. $jscName .= ".exe" if (isWindows() || isCygwin());
  349. $jscName .= ".self" if isPS3();
  350. return "$productDir/psp2run-jsc.sh" if isPSVita();
  351. return "$productDir/orbisrun-jsc.sh" if isPSOrbis();
  352. return "$productDir/$jscName" if -e "$productDir/$jscName";
  353. return "$productDir/JavaScriptCore.framework/Resources/$jscName";
  354. }
  355. sub argumentsForConfiguration()
  356. {
  357. determineConfiguration();
  358. determineArchitecture();
  359. my @args = ();
  360. push(@args, '--debug') if $configuration eq "Debug";
  361. push(@args, '--release') if $configuration eq "Release";
  362. push(@args, '--32-bit') if $architecture ne "x86_64";
  363. push(@args, '--qt') if isQt();
  364. push(@args, '--gtk') if isGtk();
  365. push(@args, '--efl') if isEfl();
  366. push(@args, '--wincairo') if isWinCairo();
  367. push(@args, '--wince') if isWinCE();
  368. push(@args, '--blackberry') if isBlackBerry();
  369. push(@args, '--inspector-frontend') if isInspectorFrontend();
  370. return @args;
  371. }
  372. sub determineXcodeSDK
  373. {
  374. return if defined $xcodeSDK;
  375. for (my $i = 0; $i <= $#ARGV; $i++) {
  376. my $opt = $ARGV[$i];
  377. if ($opt =~ /^--sdk$/i) {
  378. splice(@ARGV, $i, 1);
  379. $xcodeSDK = splice(@ARGV, $i, 1);
  380. } elsif ($opt =~ /^--device$/i) {
  381. splice(@ARGV, $i, 1);
  382. $xcodeSDK = 'iphoneos.internal';
  383. } elsif ($opt =~ /^--sim(ulator)?/i) {
  384. splice(@ARGV, $i, 1);
  385. $xcodeSDK = 'iphonesimulator';
  386. }
  387. }
  388. }
  389. sub xcodeSDK
  390. {
  391. determineXcodeSDK();
  392. return $xcodeSDK;
  393. }
  394. sub programFilesPath
  395. {
  396. return $programFilesPath if defined $programFilesPath;
  397. $programFilesPath = $ENV{'PROGRAMFILES(X86)'} || $ENV{'PROGRAMFILES'} || "C:\\Program Files";
  398. return $programFilesPath;
  399. }
  400. sub visualStudioInstallDir
  401. {
  402. return $vsInstallDir if defined $vsInstallDir;
  403. if ($ENV{'VSINSTALLDIR'}) {
  404. $vsInstallDir = $ENV{'VSINSTALLDIR'};
  405. $vsInstallDir =~ s|[\\/]$||;
  406. } else {
  407. $vsInstallDir = File::Spec->catdir(programFilesPath(), "Microsoft Visual Studio 10.0");
  408. }
  409. chomp($vsInstallDir = `cygpath "$vsInstallDir"`) if isCygwin();
  410. return $vsInstallDir;
  411. }
  412. sub visualStudioVersion
  413. {
  414. return $vsVersion if defined $vsVersion;
  415. my $installDir = visualStudioInstallDir();
  416. $vsVersion = ($installDir =~ /Microsoft Visual Studio ([0-9]+\.[0-9]*)/) ? $1 : "8";
  417. return $vsVersion;
  418. }
  419. sub determineConfigurationForVisualStudio
  420. {
  421. return if defined $configurationForVisualStudio;
  422. determineConfiguration();
  423. # FIXME: We should detect when Debug_All or Production has been chosen.
  424. $configurationForVisualStudio = $configuration;
  425. }
  426. sub usesPerConfigurationBuildDirectory
  427. {
  428. # [Gtk] We don't have Release/Debug configurations in straight
  429. # autotool builds (non build-webkit). In this case and if
  430. # WEBKITOUTPUTDIR exist, use that as our configuration dir. This will
  431. # allows us to run run-webkit-tests without using build-webkit.
  432. return ($ENV{"WEBKITOUTPUTDIR"} && isGtk()) || isAppleWinWebKit();
  433. }
  434. sub determineConfigurationProductDir
  435. {
  436. return if defined $configurationProductDir;
  437. determineBaseProductDir();
  438. determineConfiguration();
  439. if (isAppleWinWebKit()) {
  440. my $binDir = "bin32";
  441. $configurationProductDir = File::Spec->catdir($baseProductDir, configurationForVisualStudio(), $binDir);
  442. } elsif (isPSVita()) {
  443. $configurationProductDir = "$baseProductDir/lib/$configuration";
  444. } else {
  445. if (usesPerConfigurationBuildDirectory()) {
  446. $configurationProductDir = "$baseProductDir";
  447. } else {
  448. $configurationProductDir = "$baseProductDir/$configuration";
  449. }
  450. }
  451. }
  452. sub setConfigurationProductDir($)
  453. {
  454. ($configurationProductDir) = @_;
  455. }
  456. sub determineCurrentSVNRevision
  457. {
  458. # We always update the current SVN revision here, and leave the caching
  459. # to currentSVNRevision(), so that changes to the SVN revision while the
  460. # script is running can be picked up by calling this function again.
  461. determineSourceDir();
  462. $currentSVNRevision = svnRevisionForDirectory($sourceDir);
  463. return $currentSVNRevision;
  464. }
  465. sub chdirWebKit
  466. {
  467. determineSourceDir();
  468. chdir $sourceDir or die;
  469. }
  470. sub baseProductDir
  471. {
  472. determineBaseProductDir();
  473. return $baseProductDir;
  474. }
  475. sub sourceDir
  476. {
  477. determineSourceDir();
  478. return $sourceDir;
  479. }
  480. sub productDir
  481. {
  482. determineConfigurationProductDir();
  483. return $configurationProductDir;
  484. }
  485. sub jscProductDir
  486. {
  487. my $productDir = productDir();
  488. $productDir .= "/bin" if (isQt() || isEfl());
  489. $productDir .= "/Programs" if isGtk();
  490. return $productDir;
  491. }
  492. sub configuration()
  493. {
  494. determineConfiguration();
  495. return $configuration;
  496. }
  497. sub configurationForVisualStudio()
  498. {
  499. determineConfigurationForVisualStudio();
  500. return $configurationForVisualStudio;
  501. }
  502. sub currentSVNRevision
  503. {
  504. determineCurrentSVNRevision() if not defined $currentSVNRevision;
  505. return $currentSVNRevision;
  506. }
  507. sub generateDsym()
  508. {
  509. determineGenerateDsym();
  510. return $generateDsym;
  511. }
  512. sub determineGenerateDsym()
  513. {
  514. return if defined($generateDsym);
  515. $generateDsym = checkForArgumentAndRemoveFromARGV("--dsym");
  516. }
  517. sub argumentsForXcode()
  518. {
  519. my @args = ();
  520. push @args, "DEBUG_INFORMATION_FORMAT=dwarf-with-dsym" if generateDsym();
  521. return @args;
  522. }
  523. sub XcodeOptions
  524. {
  525. determineBaseProductDir();
  526. determineConfiguration();
  527. determineArchitecture();
  528. determineXcodeSDK();
  529. my @sdkOption = ($xcodeSDK ? "SDKROOT=$xcodeSDK" : ());
  530. my @architectureOption = ($architecture ? "ARCHS=$architecture" : ());
  531. return (@baseProductDirOption, "-configuration", $configuration, @architectureOption, @sdkOption, argumentsForXcode());
  532. }
  533. sub XcodeOptionString
  534. {
  535. return join " ", XcodeOptions();
  536. }
  537. sub XcodeOptionStringNoConfig
  538. {
  539. return join " ", @baseProductDirOption;
  540. }
  541. sub XcodeCoverageSupportOptions()
  542. {
  543. my @coverageSupportOptions = ();
  544. push @coverageSupportOptions, "GCC_GENERATE_TEST_COVERAGE_FILES=YES";
  545. push @coverageSupportOptions, "GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES";
  546. return @coverageSupportOptions;
  547. }
  548. my $passedConfiguration;
  549. my $searchedForPassedConfiguration;
  550. sub determinePassedConfiguration
  551. {
  552. return if $searchedForPassedConfiguration;
  553. $searchedForPassedConfiguration = 1;
  554. for my $i (0 .. $#ARGV) {
  555. my $opt = $ARGV[$i];
  556. if ($opt =~ /^--debug$/i) {
  557. splice(@ARGV, $i, 1);
  558. $passedConfiguration = "Debug";
  559. $passedConfiguration .= "_WinCairo" if (isWinCairo() && isCygwin());
  560. return;
  561. }
  562. if ($opt =~ /^--release$/i) {
  563. splice(@ARGV, $i, 1);
  564. $passedConfiguration = "Release";
  565. $passedConfiguration .= "_WinCairo" if (isWinCairo() && isCygwin());
  566. return;
  567. }
  568. if ($opt =~ /^--profil(e|ing)$/i) {
  569. splice(@ARGV, $i, 1);
  570. $passedConfiguration = "Profiling";
  571. $passedConfiguration .= "_WinCairo" if (isWinCairo() && isCygwin());
  572. return;
  573. }
  574. }
  575. $passedConfiguration = undef;
  576. }
  577. sub passedConfiguration
  578. {
  579. determinePassedConfiguration();
  580. return $passedConfiguration;
  581. }
  582. sub setConfiguration
  583. {
  584. setArchitecture();
  585. if (my $config = shift @_) {
  586. $configuration = $config;
  587. return;
  588. }
  589. determinePassedConfiguration();
  590. $configuration = $passedConfiguration if $passedConfiguration;
  591. }
  592. my $passedArchitecture;
  593. my $searchedForPassedArchitecture;
  594. sub determinePassedArchitecture
  595. {
  596. return if $searchedForPassedArchitecture;
  597. $searchedForPassedArchitecture = 1;
  598. for my $i (0 .. $#ARGV) {
  599. my $opt = $ARGV[$i];
  600. if ($opt =~ /^--32-bit$/i) {
  601. splice(@ARGV, $i, 1);
  602. if (isAppleMacWebKit()) {
  603. $passedArchitecture = `arch`;
  604. chomp $passedArchitecture;
  605. }
  606. return;
  607. }
  608. }
  609. $passedArchitecture = undef;
  610. }
  611. sub passedArchitecture
  612. {
  613. determinePassedArchitecture();
  614. return $passedArchitecture;
  615. }
  616. sub architecture()
  617. {
  618. determineArchitecture();
  619. return $architecture;
  620. }
  621. sub numberOfCPUs()
  622. {
  623. determineNumberOfCPUs();
  624. return $numberOfCPUs;
  625. }
  626. sub setArchitecture
  627. {
  628. if (my $arch = shift @_) {
  629. $architecture = $arch;
  630. return;
  631. }
  632. determinePassedArchitecture();
  633. $architecture = $passedArchitecture if $passedArchitecture;
  634. }
  635. sub skipSafariExecutableEntitlementChecks
  636. {
  637. return `defaults read /Library/Preferences/org.webkit.BuildConfiguration SkipSafariExecutableEntitlementChecks 2>/dev/null` eq "1\n";
  638. }
  639. sub executableHasEntitlements
  640. {
  641. my $executablePath = shift;
  642. return (`codesign -d --entitlements - $executablePath 2>&1` =~ /<key>/);
  643. }
  644. sub safariPathFromSafariBundle
  645. {
  646. my ($safariBundle) = @_;
  647. if (isAppleMacWebKit()) {
  648. my $safariPath = "$safariBundle/Contents/MacOS/Safari";
  649. return $safariPath if skipSafariExecutableEntitlementChecks();
  650. my $safariForWebKitDevelopmentPath = "$safariBundle/Contents/MacOS/SafariForWebKitDevelopment";
  651. return $safariForWebKitDevelopmentPath if -f $safariForWebKitDevelopmentPath && executableHasEntitlements($safariPath);
  652. return $safariPath;
  653. }
  654. return $safariBundle if isAppleWinWebKit();
  655. }
  656. sub installedSafariPath
  657. {
  658. my $safariBundle;
  659. if (isAppleMacWebKit()) {
  660. $safariBundle = "/Applications/Safari.app";
  661. } elsif (isAppleWinWebKit()) {
  662. $safariBundle = readRegistryString("/HKLM/SOFTWARE/Apple Computer, Inc./Safari/InstallDir");
  663. $safariBundle =~ s/[\r\n]+$//;
  664. $safariBundle = `cygpath -u '$safariBundle'` if isCygwin();
  665. $safariBundle =~ s/[\r\n]+$//;
  666. $safariBundle .= "Safari.exe";
  667. }
  668. return safariPathFromSafariBundle($safariBundle);
  669. }
  670. # Locate Safari.
  671. sub safariPath
  672. {
  673. # Use WEBKIT_SAFARI environment variable if present.
  674. my $safariBundle = $ENV{WEBKIT_SAFARI};
  675. if (!$safariBundle) {
  676. determineConfigurationProductDir();
  677. # Use Safari.app in product directory if present (good for Safari development team).
  678. if (isAppleMacWebKit() && -d "$configurationProductDir/Safari.app") {
  679. $safariBundle = "$configurationProductDir/Safari.app";
  680. } elsif (isAppleWinWebKit()) {
  681. my $path = "$configurationProductDir/Safari.exe";
  682. my $debugPath = "$configurationProductDir/Safari_debug.exe";
  683. if (configurationForVisualStudio() eq "Debug_All" && -x $debugPath) {
  684. $safariBundle = $debugPath;
  685. } elsif (-x $path) {
  686. $safariBundle = $path;
  687. }
  688. }
  689. if (!$safariBundle) {
  690. return installedSafariPath();
  691. }
  692. }
  693. my $safariPath = safariPathFromSafariBundle($safariBundle);
  694. die "Can't find executable at $safariPath.\n" if isAppleMacWebKit() && !-x $safariPath;
  695. return $safariPath;
  696. }
  697. sub builtDylibPathForName
  698. {
  699. my $libraryName = shift;
  700. determineConfigurationProductDir();
  701. if (isBlackBerry()) {
  702. my $libraryExtension = $libraryName =~ /^WebKit$/i ? ".so" : ".a";
  703. return "$configurationProductDir/$libraryName/lib" . lc($libraryName) . $libraryExtension;
  704. }
  705. if (isQt()) {
  706. my $isSearchingForWebCore = $libraryName =~ "WebCore";
  707. if (isDarwin()) {
  708. $libraryName = "QtWebKitWidgets";
  709. } else {
  710. $libraryName = "Qt5WebKitWidgets";
  711. }
  712. my $result;
  713. if (isDarwin() and -d "$configurationProductDir/lib/$libraryName.framework") {
  714. $result = "$configurationProductDir/lib/$libraryName.framework/$libraryName";
  715. } elsif (isDarwin() and -d "$configurationProductDir/lib") {
  716. $result = "$configurationProductDir/lib/lib$libraryName.dylib";
  717. } elsif (isWindows()) {
  718. if (configuration() eq "Debug") {
  719. # On Windows, there is a "d" suffix to the library name. See <http://trac.webkit.org/changeset/53924/>.
  720. $libraryName .= "d";
  721. }
  722. chomp(my $mkspec = `$qmakebin -query QT_HOST_DATA`);
  723. $mkspec .= "/mkspecs";
  724. my $qtMajorVersion = retrieveQMakespecVar("$mkspec/qconfig.pri", "QT_MAJOR_VERSION");
  725. if (not $qtMajorVersion) {
  726. $qtMajorVersion = "";
  727. }
  728. $result = "$configurationProductDir/lib/$libraryName$qtMajorVersion.dll";
  729. } else {
  730. $result = "$configurationProductDir/lib/lib$libraryName.so";
  731. }
  732. if ($isSearchingForWebCore) {
  733. # With CONFIG+=force_static_libs_as_shared we have a shared library for each subdir.
  734. # For feature detection to work it is necessary to return the path of the WebCore library here.
  735. my $replacedWithWebCore = $result;
  736. $replacedWithWebCore =~ s/$libraryName/WebCore/g;
  737. if (-e $replacedWithWebCore) {
  738. return $replacedWithWebCore;
  739. }
  740. }
  741. return $result;
  742. }
  743. if (isGtk()) {
  744. # WebKitGTK+ for GTK2, WebKitGTK+ for GTK3, and WebKit2 respectively.
  745. my @libraries = ("libwebkitgtk-1.0", "libwebkitgtk-3.0", "libwebkit2gtk-3.0");
  746. my $extension = isDarwin() ? ".dylib" : ".so";
  747. foreach $libraryName (@libraries) {
  748. my $libraryPath = "$configurationProductDir/.libs/" . $libraryName . $extension;
  749. return $libraryPath if -e $libraryPath;
  750. }
  751. return "NotFound";
  752. }
  753. if (isEfl()) {
  754. if (isWK2()) {
  755. return "$configurationProductDir/lib/libewebkit2.so";
  756. }
  757. return "$configurationProductDir/lib/libewebkit.so";
  758. }
  759. if (isWinCE()) {
  760. return "$configurationProductDir/$libraryName";
  761. }
  762. if (isAppleMacWebKit()) {
  763. return "$configurationProductDir/$libraryName.framework/Versions/A/$libraryName";
  764. }
  765. if (isAppleWinWebKit()) {
  766. if ($libraryName eq "JavaScriptCore") {
  767. return "$baseProductDir/lib/$libraryName.lib";
  768. } else {
  769. return "$baseProductDir/$libraryName.intermediate/$configuration/$libraryName.intermediate/$libraryName.lib";
  770. }
  771. }
  772. if (isPS3()) {
  773. # TODO fix me
  774. # PS3 uses gyp to build webcore. unfortunately, gyp doesn't handle large projects well
  775. # (i.e. the length of the arguments passed to ppu-lv2-ar exceeded the shell's limit because
  776. # of the extra nested directories it uses to store object files)
  777. # so for now, let's return something totally bogus here (i.e. foofoo.a) so that we can easily
  778. # catch this error in the future
  779. return "$baseProductDir/$libraryName/foofoo.a";
  780. }
  781. if (isPSVita()) {
  782. return "$configurationProductDir/$libraryName";
  783. }
  784. die "Unsupported platform, can't determine built library locations.\nTry `build-webkit --help` for more information.\n";
  785. }
  786. # Check to see that all the frameworks are built.
  787. sub checkFrameworks # FIXME: This is a poor name since only the Mac calls built WebCore a Framework.
  788. {
  789. return if isCygwin() || isWindows();
  790. my @frameworks = ("JavaScriptCore", "WebCore");
  791. push(@frameworks, "WebKit") if isAppleMacWebKit(); # FIXME: This seems wrong, all ports should have a WebKit these days.
  792. for my $framework (@frameworks) {
  793. my $path = builtDylibPathForName($framework);
  794. die "Can't find built framework at \"$path\".\n" unless -e $path;
  795. }
  796. }
  797. sub isInspectorFrontend()
  798. {
  799. determineIsInspectorFrontend();
  800. return $isInspectorFrontend;
  801. }
  802. sub determineIsInspectorFrontend()
  803. {
  804. return if defined($isInspectorFrontend);
  805. $isInspectorFrontend = checkForArgumentAndRemoveFromARGV("--inspector-frontend");
  806. }
  807. sub isQt()
  808. {
  809. determineIsQt();
  810. return $isQt;
  811. }
  812. sub getQtVersion()
  813. {
  814. my $qtVersion = `$qmakebin --version`;
  815. $qtVersion =~ s/^(.*)Qt version (\d\.\d)(.*)/$2/s ;
  816. return $qtVersion;
  817. }
  818. sub qtFeatureDefaults
  819. {
  820. die "ERROR: qmake missing but required to build WebKit.\n" if not commandExists($qmakebin);
  821. my $oldQmakeEval = $ENV{QMAKE_CACHE_EVAL};
  822. $ENV{QMAKE_CACHE_EVAL} = "CONFIG+=print_defaults";
  823. my $originalCwd = getcwd();
  824. my $qmakepath = File::Spec->catfile(sourceDir(), "Tools", "qmake");
  825. chdir $qmakepath or die "Failed to cd into " . $qmakepath . "\n";
  826. my $file = File::Spec->catfile(sourceDir(), "WebKit.pro");
  827. my @buildArgs;
  828. @buildArgs = (@buildArgs, @{$_[0]}) if (@_);
  829. my @defaults = `$qmakebin @buildArgs $file 2>&1`;
  830. my %qtFeatureDefaults;
  831. for (@defaults) {
  832. if (/DEFINES: /) {
  833. while (/(\S+?)=(\S+?)/gi) {
  834. $qtFeatureDefaults{$1}=$2;
  835. }
  836. } elsif (/Done computing defaults/) {
  837. last;
  838. } elsif (@_) {
  839. print $_;
  840. }
  841. }
  842. chdir $originalCwd;
  843. $ENV{QMAKE_CACHE_EVAL} = $oldQmakeEval;
  844. return %qtFeatureDefaults;
  845. }
  846. sub commandExists($)
  847. {
  848. my $command = shift;
  849. my $devnull = File::Spec->devnull();
  850. return `$command --version 2> $devnull`;
  851. }
  852. sub checkForArgumentAndRemoveFromARGV
  853. {
  854. my $argToCheck = shift;
  855. return checkForArgumentAndRemoveFromArrayRef($argToCheck, \@ARGV);
  856. }
  857. sub checkForArgumentAndRemoveFromArrayRef
  858. {
  859. my ($argToCheck, $arrayRef) = @_;
  860. my @indicesToRemove;
  861. foreach my $index (0 .. $#$arrayRef) {
  862. my $opt = $$arrayRef[$index];
  863. if ($opt =~ /^$argToCheck$/i ) {
  864. push(@indicesToRemove, $index);
  865. }
  866. }
  867. foreach my $index (@indicesToRemove) {
  868. splice(@$arrayRef, $index, 1);
  869. }
  870. return $#indicesToRemove > -1;
  871. }
  872. sub isWK2()
  873. {
  874. if (defined($isWK2)) {
  875. return $isWK2;
  876. }
  877. if (checkForArgumentAndRemoveFromARGV("-2")) {
  878. $isWK2 = 1;
  879. } else {
  880. $isWK2 = 0;
  881. }
  882. return $isWK2;
  883. }
  884. sub determineIsQt()
  885. {
  886. return if defined($isQt);
  887. # Allow override in case QTDIR is not set.
  888. if (checkForArgumentAndRemoveFromARGV("--qt")) {
  889. $isQt = 1;
  890. return;
  891. }
  892. # The presence of QTDIR only means Qt if --gtk or --efl or --blackberry or --wincairo are not on the command-line
  893. if (isGtk() || isEfl() || isBlackBerry() || isWinCairo()) {
  894. $isQt = 0;
  895. return;
  896. }
  897. $isQt = defined($ENV{'QTDIR'});
  898. }
  899. sub isBlackBerry()
  900. {
  901. determineIsBlackBerry();
  902. return $isBlackBerry;
  903. }
  904. sub determineIsBlackBerry()
  905. {
  906. return if defined($isBlackBerry);
  907. $isBlackBerry = checkForArgumentAndRemoveFromARGV("--blackberry");
  908. }
  909. sub blackberryTargetArchitecture()
  910. {
  911. my $arch = $ENV{"BLACKBERRY_ARCH_TYPE"} ? $ENV{"BLACKBERRY_ARCH_TYPE"} : "arm";
  912. my $cpu = $ENV{"BLACKBERRY_ARCH_CPU"} ? $ENV{"BLACKBERRY_ARCH_CPU"} : "";
  913. my $cpuDir;
  914. my $buSuffix;
  915. if (($cpu eq "v7le") || ($cpu eq "a9")) {
  916. $cpuDir = $arch . "le-v7";
  917. $buSuffix = $arch . "v7";
  918. } else {
  919. $cpu = $arch;
  920. $cpuDir = $arch;
  921. $buSuffix = $arch;
  922. }
  923. return ("arch" => $arch,
  924. "cpu" => $cpu,
  925. "cpuDir" => $cpuDir,
  926. "buSuffix" => $buSuffix);
  927. }
  928. sub blackberryCMakeArguments()
  929. {
  930. my %archInfo = blackberryTargetArchitecture();
  931. my $arch = $archInfo{"arch"};
  932. my $cpu = $archInfo{"cpu"};
  933. my $cpuDir = $archInfo{"cpuDir"};
  934. my $buSuffix = $archInfo{"buSuffix"};
  935. my @cmakeExtraOptions;
  936. if ($cpu eq "a9") {
  937. $cpu = $arch . "v7le";
  938. push @cmakeExtraOptions, '-DTARGETING_PLAYBOOK=1';
  939. }
  940. my $stageDir = $ENV{"STAGE_DIR"};
  941. my $stageLib = File::Spec->catdir($stageDir, $cpuDir, "lib");
  942. my $stageUsrLib = File::Spec->catdir($stageDir, $cpuDir, "usr", "lib");
  943. my $stageInc = File::Spec->catdir($stageDir, "usr", "include");
  944. my $qnxHost = $ENV{"QNX_HOST"};
  945. my $ccCommand;
  946. my $cxxCommand;
  947. if ($ENV{"USE_ICECC"}) {
  948. chomp($ccCommand = `which icecc`);
  949. $cxxCommand = $ccCommand;
  950. } else {
  951. $ccCommand = File::Spec->catfile($qnxHost, "usr", "bin", "qcc");
  952. $cxxCommand = $ccCommand;
  953. }
  954. if ($ENV{"CCWRAP"}) {
  955. $ccCommand = $ENV{"CCWRAP"};
  956. push @cmakeExtraOptions, "-DCMAKE_C_COMPILER_ARG1=qcc";
  957. push @cmakeExtraOptions, "-DCMAKE_CXX_COMPILER_ARG1=qcc";
  958. }
  959. push @cmakeExtraOptions, "-DCMAKE_SKIP_RPATH='ON'" if isDarwin();
  960. push @cmakeExtraOptions, "-DPUBLIC_BUILD=1" if $ENV{"PUBLIC_BUILD"};
  961. push @cmakeExtraOptions, "-DENABLE_GLES2=1" unless $ENV{"DISABLE_GLES2"};
  962. my @includeSystemDirectories;
  963. push @includeSystemDirectories, File::Spec->catdir($stageInc, "harfbuzzng");
  964. push @includeSystemDirectories, File::Spec->catdir($stageInc, "imf");
  965. # We only use jpeg-turbo for device build
  966. push @includeSystemDirectories, File::Spec->catdir($stageInc, "jpeg-turbo") if $arch=~/arm/;
  967. push @includeSystemDirectories, $stageInc;
  968. push @includeSystemDirectories, File::Spec->catdir($stageInc, "browser", "platform");
  969. push @includeSystemDirectories, File::Spec->catdir($stageInc, "browser", "platform", "graphics");
  970. push @includeSystemDirectories, File::Spec->catdir($stageInc, "browser", "qsk");
  971. push @includeSystemDirectories, File::Spec->catdir($stageInc, "ots");
  972. push @includeSystemDirectories, File::Spec->catdir($stageInc, "iType", "common");
  973. push @includeSystemDirectories, File::Spec->catdir($stageInc, "iType", "port", "nto");
  974. my @cxxFlags;
  975. push @cxxFlags, "-Wl,-rpath-link,$stageLib";
  976. push @cxxFlags, "-Wl,-rpath-link," . File::Spec->catfile($stageUsrLib, "torch-webkit");
  977. push @cxxFlags, "-Wl,-rpath-link,$stageUsrLib";
  978. push @cxxFlags, "-L$stageLib";
  979. push @cxxFlags, "-L$stageUsrLib";
  980. if ($ENV{"PROFILE"}) {
  981. push @cmakeExtraOptions, "-DPROFILING=1";
  982. push @cxxFlags, "-p";
  983. }
  984. my @cmakeArgs;
  985. push @cmakeArgs, '-DCMAKE_SYSTEM_NAME="QNX"';
  986. push @cmakeArgs, "-DCMAKE_SYSTEM_PROCESSOR=\"$cpuDir\"";
  987. push @cmakeArgs, '-DCMAKE_SYSTEM_VERSION="1"';
  988. push @cmakeArgs, "-DCMAKE_C_COMPILER=\"$ccCommand\"";
  989. push @cmakeArgs, "-DCMAKE_CXX_COMPILER=\"$cxxCommand\"";
  990. push @cmakeArgs, "-DCMAKE_C_FLAGS=\"-Vgcc_nto${cpu} -g @cxxFlags\"";
  991. push @cmakeArgs, "-DCMAKE_CXX_FLAGS=\"-Vgcc_nto${cpu}_cpp-ne -g -lang-c++ @cxxFlags\"";
  992. # We cannot use CMAKE_INCLUDE_PATH since this describes the search path for header files in user directories.
  993. # And the QNX system headers are in user directories on the host OS (i.e. they aren't installed in the host OS's
  994. # system header search path). So, we need to inform g++ that these user directories (@includeSystemDirectories)
  995. # are to be taken as the host OS's system header directories when building our port.
  996. #
  997. # Also, we cannot use CMAKE_SYSTEM_INCLUDE_PATH since that will override the entire system header path.
  998. # So, we define the additional system include paths in ADDITIONAL_SYSTEM_INCLUDE_PATH. This list will
  999. # be processed in OptionsBlackBerry.cmake.
  1000. push @cmakeArgs, '-DADDITIONAL_SYSTEM_INCLUDE_PATH="' . join(';', @includeSystemDirectories) . '"';
  1001. # FIXME: Make this more general purpose such that we can pass a list of directories and files.
  1002. push @cmakeArgs, '-DTHIRD_PARTY_ICU_DIR="' . File::Spec->catdir($stageInc, "unicode") . '"';
  1003. push @cmakeArgs, '-DTHIRD_PARTY_UNICODE_FILE="' . File::Spec->catfile($stageInc, "unicode.h") . '"';
  1004. push @cmakeArgs, "-DCMAKE_LIBRARY_PATH=\"$stageLib;$stageUsrLib\"";
  1005. push @cmakeArgs, '-DCMAKE_AR="' . File::Spec->catfile($qnxHost, "usr", "bin", "nto${buSuffix}-ar") . '"';
  1006. push @cmakeArgs, '-DCMAKE_RANLIB="' . File::Spec->catfile($qnxHost, "usr", "bin", "nto${buSuffix}-ranlib") . '"';
  1007. push @cmakeArgs, '-DCMAKE_LD="'. File::Spec->catfile($qnxHost, "usr", "bin", "nto${buSuffix}-ld") . '"';
  1008. push @cmakeArgs, '-DCMAKE_LINKER="' . File::Spec->catfile($qnxHost, "usr", "bin", "nto${buSuffix}-ld") . '"';
  1009. push @cmakeArgs, "-DECLIPSE_CDT4_GENERATE_SOURCE_PROJECT=TRUE";
  1010. push @cmakeArgs, '-G"Eclipse CDT4 - Unix Makefiles"';
  1011. push @cmakeArgs, @cmakeExtraOptions;
  1012. return @cmakeArgs;
  1013. }
  1014. sub determineIsEfl()
  1015. {
  1016. return if defined($isEfl);
  1017. $isEfl = checkForArgumentAndRemoveFromARGV("--efl");
  1018. }
  1019. sub isEfl()
  1020. {
  1021. determineIsEfl();
  1022. return $isEfl;
  1023. }
  1024. sub isGtk()
  1025. {
  1026. determineIsGtk();
  1027. return $isGtk;
  1028. }
  1029. sub determineIsGtk()
  1030. {
  1031. return if defined($isGtk);
  1032. $isGtk = checkForArgumentAndRemoveFromARGV("--gtk");
  1033. }
  1034. sub isWinCE()
  1035. {
  1036. determineIsWinCE();
  1037. return $isWinCE;
  1038. }
  1039. sub determineIsWinCE()
  1040. {
  1041. return if defined($isWinCE);
  1042. $isWinCE = checkForArgumentAndRemoveFromARGV("--wince");
  1043. }
  1044. # Determine if this is debian, ubuntu, linspire, or something similar.
  1045. sub isDebianBased()
  1046. {
  1047. return -e "/etc/debian_version";
  1048. }
  1049. sub isFedoraBased()
  1050. {
  1051. return -e "/etc/fedora-release";
  1052. }
  1053. sub isWinCairo()
  1054. {
  1055. determineIsWinCairo();
  1056. return $isWinCairo;
  1057. }
  1058. sub determineIsWinCairo()
  1059. {
  1060. return if defined($isWinCairo);
  1061. $isWinCairo = checkForArgumentAndRemoveFromARGV("--wincairo");
  1062. }
  1063. sub isCygwin()
  1064. {
  1065. return ($^O eq "cygwin") || 0;
  1066. }
  1067. sub isAnyWindows()
  1068. {
  1069. return isWindows() || isCygwin();
  1070. }
  1071. sub determineWinVersion()
  1072. {
  1073. return if $winVersion;
  1074. if (!isAnyWindows()) {
  1075. $winVersion = -1;
  1076. return;
  1077. }
  1078. my $versionString = `cmd /c ver`;
  1079. $versionString =~ /(\d)\.(\d)\.(\d+)/;
  1080. $winVersion = {
  1081. major => $1,
  1082. minor => $2,
  1083. build => $3,
  1084. };
  1085. }
  1086. sub winVersion()
  1087. {
  1088. determineWinVersion();
  1089. return $winVersion;
  1090. }
  1091. sub isWindows7SP0()
  1092. {
  1093. return isAnyWindows() && winVersion()->{major} == 6 && winVersion()->{minor} == 1 && winVersion()->{build} == 7600;
  1094. }
  1095. sub isWindowsVista()
  1096. {
  1097. return isAnyWindows() && winVersion()->{major} == 6 && winVersion()->{minor} == 0;
  1098. }
  1099. sub isWindowsXP()
  1100. {
  1101. return isAnyWindows() && winVersion()->{major} == 5 && winVersion()->{minor} == 1;
  1102. }
  1103. sub isDarwin()
  1104. {
  1105. return ($^O eq "darwin") || 0;
  1106. }
  1107. sub isWindows()
  1108. {
  1109. return ($^O eq "MSWin32") || 0;
  1110. }
  1111. sub isLinux()
  1112. {
  1113. return ($^O eq "linux") || 0;
  1114. }
  1115. sub isFreeBSD()
  1116. {
  1117. return ($^O eq "freebsd") || 0;
  1118. }
  1119. sub isARM()
  1120. {
  1121. return $Config{archname} =~ /^arm[v\-]/;
  1122. }
  1123. sub isCrossCompilation()
  1124. {
  1125. my $compiler = "";
  1126. $compiler = $ENV{'CC'} if (defined($ENV{'CC'}));
  1127. if ($compiler =~ /gcc/) {
  1128. my $compiler_options = `$compiler -v 2>&1`;
  1129. my @host = $compiler_options =~ m/--host=(.*?)\s/;
  1130. my @target = $compiler_options =~ m/--target=(.*?)\s/;
  1131. return ($host[0] ne "" && $target[0] ne "" && $host[0] ne $target[0]);
  1132. }
  1133. return 0;
  1134. }
  1135. sub isAppleWebKit()
  1136. {
  1137. return !(isQt() or isGtk() or isEfl() or isWinCE() or isBlackBerry() or isPSVita() or isPSOrbis());
  1138. }
  1139. sub isAppleMacWebKit()
  1140. {
  1141. return isAppleWebKit() && isDarwin();
  1142. }
  1143. sub isAppleWinWebKit()
  1144. {
  1145. return isAppleWebKit() && (isCygwin() || isWindows());
  1146. }
  1147. sub isPerianInstalled()
  1148. {
  1149. if (!isAppleWebKit()) {
  1150. return 0;
  1151. }
  1152. if (-d "/Library/QuickTime/Perian.component") {
  1153. return 1;
  1154. }
  1155. if (-d "$ENV{HOME}/Library/QuickTime/Perian.component") {
  1156. return 1;
  1157. }
  1158. return 0;
  1159. }
  1160. sub determineNmPath()
  1161. {
  1162. return if $nmPath;
  1163. if (isAppleMacWebKit()) {
  1164. $nmPath = `xcrun -find nm`;
  1165. chomp $nmPath;
  1166. }
  1167. $nmPath = "nm" if !$nmPath;
  1168. }
  1169. sub nmPath()
  1170. {
  1171. determineNmPath();
  1172. return $nmPath;
  1173. }
  1174. sub determineOSXVersion()
  1175. {
  1176. return if $osXVersion;
  1177. if (!isDarwin()) {
  1178. $osXVersion = -1;
  1179. return;
  1180. }
  1181. my $version = `sw_vers -productVersion`;
  1182. my @splitVersion = split(/\./, $version);
  1183. @splitVersion >= 2 or die "Invalid version $version";
  1184. $osXVersion = {
  1185. "major" => $splitVersion[0],
  1186. "minor" => $splitVersion[1],
  1187. "subminor" => (defined($splitVersion[2]) ? $splitVersion[2] : 0),
  1188. };
  1189. }
  1190. sub osXVersion()
  1191. {
  1192. determineOSXVersion();
  1193. return $osXVersion;
  1194. }
  1195. sub isSnowLeopard()
  1196. {
  1197. return isDarwin() && osXVersion()->{"minor"} == 6;
  1198. }
  1199. sub isLion()
  1200. {
  1201. return isDarwin() && osXVersion()->{"minor"} == 7;
  1202. }
  1203. sub isWindowsNT()
  1204. {
  1205. return $ENV{'OS'} eq 'Windows_NT';
  1206. }
  1207. sub shouldTargetWebProcess
  1208. {
  1209. determineShouldTargetWebProcess();
  1210. return $shouldTargetWebProcess;
  1211. }
  1212. sub determineShouldTargetWebProcess
  1213. {
  1214. return if defined($shouldTargetWebProcess);
  1215. $shouldTargetWebProcess = checkForArgumentAndRemoveFromARGV("--target-web-process");
  1216. }
  1217. sub shouldUseXPCServiceForWebProcess
  1218. {
  1219. determineShouldUseXPCServiceForWebProcess();
  1220. return $shouldUseXPCServiceForWebProcess;
  1221. }
  1222. sub determineShouldUseXPCServiceForWebProcess
  1223. {
  1224. return if defined($shouldUseXPCServiceForWebProcess);
  1225. $shouldUseXPCServiceForWebProcess = checkForArgumentAndRemoveFromARGV("--use-web-process-xpc-service");
  1226. }
  1227. sub debugger
  1228. {
  1229. determineDebugger();
  1230. return $debugger;
  1231. }
  1232. sub determineDebugger
  1233. {
  1234. return if defined($debugger);
  1235. determineXcodeVersion();
  1236. if (eval "v$xcodeVersion" ge v4.5) {
  1237. $debugger = "lldb";
  1238. } else {
  1239. $debugger = "gdb";
  1240. }
  1241. if (checkForArgumentAndRemoveFromARGV("--use-lldb")) {
  1242. $debugger = "lldb";
  1243. }
  1244. if (checkForArgumentAndRemoveFromARGV("--use-gdb")) {
  1245. $debugger = "gdb";
  1246. }
  1247. }
  1248. sub appendToEnvironmentVariableList
  1249. {
  1250. my ($environmentVariableName, $value) = @_;
  1251. if (defined($ENV{$environmentVariableName})) {
  1252. $ENV{$environmentVariableName} .= ":" . $value;
  1253. } else {
  1254. $ENV{$environmentVariableName} = $value;
  1255. }
  1256. }
  1257. sub setUpGuardMallocIfNeeded
  1258. {
  1259. if (!isDarwin()) {
  1260. return;
  1261. }
  1262. if (!defined($shouldUseGuardMalloc)) {
  1263. $shouldUseGuardMalloc = checkForArgumentAndRemoveFromARGV("--guard-malloc");
  1264. }
  1265. if ($shouldUseGuardMalloc) {
  1266. appendToEnvironmentVariableList("DYLD_INSERT_LIBRARIES", "/usr/lib/libgmalloc.dylib");
  1267. }
  1268. }
  1269. sub relativeScriptsDir()
  1270. {
  1271. my $scriptDir = File::Spec->catpath("", File::Spec->abs2rel($FindBin::Bin, getcwd()), "");
  1272. if ($scriptDir eq "") {
  1273. $scriptDir = ".";
  1274. }
  1275. return $scriptDir;
  1276. }
  1277. sub launcherPath()
  1278. {
  1279. my $relativeScriptsPath = relativeScriptsDir();
  1280. if (isGtk() || isQt() || isEfl() || isWinCE()) {
  1281. return "$relativeScriptsPath/run-launcher";
  1282. } elsif (isAppleWebKit()) {
  1283. return "$relativeScriptsPath/run-safari";
  1284. }
  1285. }
  1286. sub launcherName()
  1287. {
  1288. if (isGtk()) {
  1289. return "GtkLauncher";
  1290. } elsif (isQt()) {
  1291. return "QtTestBrowser";
  1292. } elsif (isAppleWebKit()) {
  1293. return "Safari";
  1294. } elsif (isEfl()) {
  1295. return "EWebLauncher/MiniBrowser";
  1296. } elsif (isWinCE()) {
  1297. return "WinCELauncher";
  1298. }
  1299. }
  1300. sub checkRequiredSystemConfig
  1301. {
  1302. if (isDarwin()) {
  1303. chomp(my $productVersion = `sw_vers -productVersion`);
  1304. if (eval "v$productVersion" lt v10.4) {
  1305. print "*************************************************************\n";
  1306. print "Mac OS X Version 10.4.0 or later is required to build WebKit.\n";
  1307. print "You have " . $productVersion . ", thus the build will most likely fail.\n";
  1308. print "*************************************************************\n";
  1309. }
  1310. my $xcodebuildVersionOutput = `xcodebuild -version`;
  1311. my $devToolsCoreVersion = ($xcodebuildVersionOutput =~ /DevToolsCore-(\d+)/) ? $1 : undef;
  1312. my $xcodeVersion = ($xcodebuildVersionOutput =~ /Xcode ([0-9](\.[0-9]+)*)/) ? $1 : undef;
  1313. if (!$devToolsCoreVersion && !$xcodeVersion
  1314. || $devToolsCoreVersion && $devToolsCoreVersion < 747
  1315. || $xcodeVersion && eval "v$xcodeVersion" lt v2.3) {
  1316. print "*************************************************************\n";
  1317. print "Xcode Version 2.3 or later is required to build WebKit.\n";
  1318. print "You have an earlier version of Xcode, thus the build will\n";
  1319. print "most likely fail. The latest Xcode is available from the web:\n";
  1320. print "http://developer.apple.com/tools/xcode\n";
  1321. print "*************************************************************\n";
  1322. }
  1323. } elsif (isGtk() or isQt() or isEfl()) {
  1324. my @cmds = qw(bison gperf);
  1325. if (isQt() and isWindows()) {
  1326. push @cmds, "win_flex";
  1327. } else {
  1328. push @cmds, "flex";
  1329. }
  1330. my @missing = ();
  1331. my $oldPath = $ENV{PATH};
  1332. if (isQt() and isWindows()) {
  1333. chomp(my $gnuWin32Dir = `$qmakebin -query QT_HOST_DATA`);
  1334. $gnuWin32Dir = File::Spec->catfile($gnuWin32Dir, "..", "gnuwin32", "bin");
  1335. if (-d "$gnuWin32Dir") {
  1336. $ENV{PATH} = $gnuWin32Dir . ";" . $ENV{PATH};
  1337. }
  1338. }
  1339. foreach my $cmd (@cmds) {
  1340. push @missing, $cmd if not commandExists($cmd);
  1341. }
  1342. if (@missing) {
  1343. my $list = join ", ", @missing;
  1344. die "ERROR: $list missing but required to build WebKit.\n";
  1345. }
  1346. if (isQt() and isWindows()) {
  1347. $ENV{PATH} = $oldPath;
  1348. }
  1349. }
  1350. # Win32 and other platforms may want to check for minimum config
  1351. }
  1352. sub determineWindowsSourceDir()
  1353. {
  1354. return if $windowsSourceDir;
  1355. $windowsSourceDir = sourceDir();
  1356. chomp($windowsSourceDir = `cygpath -w '$windowsSourceDir'`) if isCygwin();
  1357. }
  1358. sub windowsSourceDir()
  1359. {
  1360. determineWindowsSourceDir();
  1361. return $windowsSourceDir;
  1362. }
  1363. sub windowsSourceSourceDir()
  1364. {
  1365. return windowsSourceDir() . "\\Source";
  1366. }
  1367. sub windowsLibrariesDir()
  1368. {
  1369. return windowsSourceDir() . "\\WebKitLibraries\\win";
  1370. }
  1371. sub windowsOutputDir()
  1372. {
  1373. return windowsSourceDir() . "\\WebKitBuild";
  1374. }
  1375. sub setupAppleWinEnv()
  1376. {
  1377. return unless isAppleWinWebKit();
  1378. if (isWindowsNT()) {
  1379. my $restartNeeded = 0;
  1380. my %variablesToSet = ();
  1381. # FIXME: We should remove this explicit version check for cygwin once we stop supporting Cygwin 1.7.9 or older versions.
  1382. # https://bugs.webkit.org/show_bug.cgi?id=85791
  1383. my $uname_version = (POSIX::uname())[2];
  1384. $uname_version =~ s/\(.*\)//; # Remove the trailing cygwin version, if any.
  1385. if (version->parse($uname_version) < version->parse("1.7.10")) {
  1386. # Setting the environment variable 'CYGWIN' to 'tty' makes cygwin enable extra support (i.e., termios)
  1387. # for UNIX-like ttys in the Windows console
  1388. $variablesToSet{CYGWIN} = "tty" unless $ENV{CYGWIN};
  1389. }
  1390. # Those environment variables must be set to be able to build inside Visual Studio.
  1391. $variablesToSet{WEBKIT_LIBRARIES} = windowsLibrariesDir() unless $ENV{WEBKIT_LIBRARIES};
  1392. $variablesToSet{WEBKIT_OUTPUTDIR} = windowsOutputDir() unless $ENV{WEBKIT_OUTPUTDIR};
  1393. foreach my $variable (keys %variablesToSet) {
  1394. print "Setting the Environment Variable '" . $variable . "' to '" . $variablesToSet{$variable} . "'\n\n";
  1395. system qw(regtool -s set), '\\HKEY_CURRENT_USER\\Environment\\' . $variable, $variablesToSet{$variable};
  1396. $restartNeeded ||= $variable eq "WEBKIT_LIBRARIES" || $variable eq "WEBKIT_OUTPUTDIR";
  1397. }
  1398. if ($restartNeeded) {
  1399. print "Please restart your computer before attempting to build inside Visual Studio.\n\n";
  1400. }
  1401. } else {
  1402. if (!$ENV{'WEBKIT_LIBRARIES'}) {
  1403. # VS2010 (and newer) version. This will replace the VS2005 version as part of
  1404. # https://bugs.webkit.org/show_bug.cgi?id=109472.
  1405. print "Warning: You must set the 'WebKit_Libraries' environment variable\n";
  1406. print " to be able build WebKit from within Visual Studio 2010 and newer.\n";
  1407. print " Make sure that 'WebKit_Libraries' points to the\n";
  1408. print " 'WebKitLibraries/win' directory, not the 'WebKitLibraries/' directory.\n\n";
  1409. }
  1410. if (!$ENV{'WEBKIT_OUTPUTDIR'}) {
  1411. # VS2010 (and newer) version. This will replace the VS2005 version as part of
  1412. # https://bugs.webkit.org/show_bug.cgi?id=109472.
  1413. print "Warning: You must set the 'WebKit_OutputDir' environment variable\n";
  1414. print " to be able build WebKit from within Visual Studio 2010 and newer.\n\n";
  1415. }
  1416. }
  1417. }
  1418. sub setupCygwinEnv()
  1419. {
  1420. return if !isCygwin() && !isWindows();
  1421. return if $vcBuildPath;
  1422. my $programFilesPath = programFilesPath();
  1423. $vcBuildPath = File::Spec->catfile(visualStudioInstallDir(), qw(Common7 IDE devenv.com));
  1424. if (-e $vcBuildPath) {
  1425. # Visual Studio is installed;
  1426. if (visualStudioVersion() eq "10") {
  1427. $vcBuildPath = File::Spec->catfile(visualStudioInstallDir(), qw(Common7 IDE devenv.exe));
  1428. }
  1429. } else {
  1430. # Visual Studio not found, try VC++ Express
  1431. $vcBuildPath = File::Spec->catfile(visualStudioInstallDir(), qw(Common7 IDE VCExpress.exe));
  1432. if (! -e $vcBuildPath) {
  1433. print "*************************************************************\n";
  1434. print "Cannot find '$vcBuildPath'\n";
  1435. print "Please execute the file 'vcvars32.bat' from\n";
  1436. print "'$programFilesPath\\Microsoft Visual Studio 8\\VC\\bin\\'\n";
  1437. print "to setup the necessary environment variables.\n";
  1438. print "*************************************************************\n";
  1439. die;
  1440. }
  1441. $willUseVCExpressWhenBuilding = 1;
  1442. }
  1443. my $qtSDKPath = File::Spec->catdir($programFilesPath, "QuickTime SDK");
  1444. if (0 && ! -e $qtSDKPath) {
  1445. print "*************************************************************\n";
  1446. print "Cannot find '$qtSDKPath'\n";
  1447. print "Please download the QuickTime SDK for Windows from\n";
  1448. print "http://developer.apple.com/quicktime/download/\n";
  1449. print "*************************************************************\n";
  1450. die;
  1451. }
  1452. print "Building results into: ", baseProductDir(), "\n";
  1453. print "WEBKIT_OUTPUTDIR is set to: ", $ENV{"WEBKIT_OUTPUTDIR"}, "\n";
  1454. print "WEBKIT_LIBRARIES is set to: ", $ENV{"WEBKIT_LIBRARIES"}, "\n";
  1455. }
  1456. sub dieIfWindowsPlatformSDKNotInstalled
  1457. {
  1458. my $registry32Path = "/proc/registry/";
  1459. my $registry64Path = "/proc/registry64/";
  1460. my @windowsPlatformSDKRegistryEntries = (
  1461. "HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Microsoft SDKs/Windows/v8.0A",
  1462. "HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Microsoft SDKs/Windows/v8.0",
  1463. "HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Microsoft SDKs/Windows/v7.1A",
  1464. "HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Microsoft SDKs/Windows/v7.0A",
  1465. "HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/MicrosoftSDK/InstalledSDKs/D2FF9F89-8AA2-4373-8A31-C838BF4DBBE1",
  1466. );
  1467. # FIXME: It would be better to detect whether we are using 32- or 64-bit Windows
  1468. # and only check the appropriate entry. But for now we just blindly check both.
  1469. my $recommendedPlatformSDK = $windowsPlatformSDKRegistryEntries[0];
  1470. while (@windowsPlatformSDKRegistryEntries) {
  1471. my $windowsPlatformSDKRegistryEntry = shift @windowsPlatformSDKRegistryEntries;
  1472. return if (-e $registry32Path . $windowsPlatformSDKRegistryEntry) || (-e $registry64Path . $windowsPlatformSDKRegistryEntry);
  1473. }
  1474. print "*************************************************************\n";
  1475. print "Cannot find registry entry '$recommendedPlatformSDK'.\n";
  1476. print "Please download and install the Microsoft Windows SDK\n";
  1477. print "from <http://www.microsoft.com/en-us/download/details.aspx?id=8279>.\n\n";
  1478. print "Then follow step 2 in the Windows section of the \"Installing Developer\n";
  1479. print "Tools\" instructions at <http://www.webkit.org/building/tools.html>.\n";
  1480. print "*************************************************************\n";
  1481. die;
  1482. }
  1483. sub copyInspectorFrontendFiles
  1484. {
  1485. my $productDir = productDir();
  1486. my $sourceInspectorPath = sourceDir() . "/Source/WebCore/inspector/front-end/";
  1487. my $inspectorResourcesDirPath = $ENV{"WEBKITINSPECTORRESOURCESDIR"};
  1488. if (!defined($inspectorResourcesDirPath)) {
  1489. $inspectorResourcesDirPath = "";
  1490. }
  1491. if (isAppleMacWebKit()) {
  1492. $inspectorResourcesDirPath = $productDir . "/WebCore.framework/Resources/inspector";
  1493. } elsif (isAppleWinWebKit()) {
  1494. $inspectorResourcesDirPath = $productDir . "/WebKit.resources/inspector";
  1495. } elsif (isQt() || isGtk()) {
  1496. my $prefix = $ENV{"WebKitInstallationPrefix"};
  1497. $inspectorResourcesDirPath = (defined($prefix) ? $prefix : "/usr/share") . "/webkit-1.0/webinspector";
  1498. } elsif (isEfl()) {
  1499. my $prefix = $ENV{"WebKitInstallationPrefix"};
  1500. $inspectorResourcesDirPath = (defined($prefix) ? $prefix : "/usr/share") . "/ewebkit/webinspector";
  1501. }
  1502. if (! -d $inspectorResourcesDirPath) {
  1503. print "*************************************************************\n";
  1504. print "Cannot find '$inspectorResourcesDirPath'.\n" if (defined($inspectorResourcesDirPath));
  1505. print "Make sure that you have built WebKit first.\n" if (! -d $productDir || defined($inspectorResourcesDirPath));
  1506. print "Optionally, set the environment variable 'WebKitInspectorResourcesDir'\n";
  1507. print "to point to the directory that contains the WebKit Inspector front-end\n";
  1508. print "files for the built WebCore framework.\n";
  1509. print "*************************************************************\n";
  1510. die;
  1511. }
  1512. if (isAppleMacWebKit()) {
  1513. my $sourceLocalizedStrings = sourceDir() . "/Source/WebCore/English.lproj/localizedStrings.js";
  1514. my $destinationLocalizedStrings = $productDir . "/WebCore.framework/Resources/English.lproj/localizedStrings.js";
  1515. system "ditto", $sourceLocalizedStrings, $destinationLocalizedStrings;
  1516. }
  1517. return system "rsync", "-aut", "--exclude=/.DS_Store", "--exclude=*.re2js", "--exclude=.svn/", !isQt() ? "--exclude=/WebKit.qrc" : "", $sourceInspectorPath, $inspectorResourcesDirPath;
  1518. }
  1519. sub buildXCodeProject($$@)
  1520. {
  1521. my ($project, $clean, @extraOptions) = @_;
  1522. if ($clean) {
  1523. push(@extraOptions, "-alltargets");
  1524. push(@extraOptions, "clean");
  1525. }
  1526. return system "xcodebuild", "-project", "$project.xcodeproj", @extraOptions;
  1527. }
  1528. sub usingVisualStudioExpress()
  1529. {
  1530. setupCygwinEnv();
  1531. return $willUseVCExpressWhenBuilding;
  1532. }
  1533. sub buildVisualStudioProject
  1534. {
  1535. my ($project, $clean) = @_;
  1536. setupCygwinEnv();
  1537. my $config = configurationForVisualStudio();
  1538. dieIfWindowsPlatformSDKNotInstalled() if $willUseVCExpressWhenBuilding;
  1539. chomp($project = `cygpath -w "$project"`) if isCygwin();
  1540. my $action = "/build";
  1541. if ($clean) {
  1542. $action = "/clean";
  1543. }
  1544. my @command = ($vcBuildPath, $project, $action, $config);
  1545. print join(" ", @command), "\n";
  1546. return system @command;
  1547. }
  1548. sub retrieveQMakespecVar
  1549. {
  1550. my $mkspec = $_[0];
  1551. my $varname = $_[1];
  1552. my $varvalue = undef;
  1553. #print "retrieveMakespecVar " . $mkspec . ", " . $varname . "\n";
  1554. local *SPEC;
  1555. open SPEC, "<$mkspec" or return $varvalue;
  1556. while (<SPEC>) {
  1557. if ($_ =~ /\s*include\((.+)\)/) {
  1558. # open the included mkspec
  1559. my $oldcwd = getcwd();
  1560. (my $volume, my $directories, my $file) = File::Spec->splitpath($mkspec);
  1561. my $newcwd = "$volume$directories";
  1562. chdir $newcwd if $newcwd;
  1563. $varvalue = retrieveQMakespecVar($1, $varname);
  1564. chdir $oldcwd;
  1565. } elsif ($_ =~ /$varname\s*=\s*([^\s]+)/) {
  1566. $varvalue = $1;
  1567. last;
  1568. }
  1569. }
  1570. close SPEC;
  1571. return $varvalue;
  1572. }
  1573. sub qtMakeCommand($)
  1574. {
  1575. my ($qmakebin) = @_;
  1576. chomp(my $hostDataPath = `$qmakebin -query QT_HOST_DATA`);
  1577. my $mkspecPath = $hostDataPath . "/mkspecs/default/qmake.conf";
  1578. if (! -e $mkspecPath) {
  1579. chomp(my $mkspec= `$qmakebin -query QMAKE_XSPEC`);
  1580. $mkspecPath = $hostDataPath . "/mkspecs/" . $mkspec . "/qmake.conf";
  1581. }
  1582. my $compiler = retrieveQMakespecVar($mkspecPath, "QMAKE_CC");
  1583. #print "default spec: " . $mkspec . "\n";
  1584. #print "compiler found: " . $compiler . "\n";
  1585. if ($compiler && $compiler eq "cl") {
  1586. return "nmake";
  1587. }
  1588. return "make";
  1589. }
  1590. sub autotoolsFlag($$)
  1591. {
  1592. my ($flag, $feature) = @_;
  1593. my $prefix = $flag ? "--enable" : "--disable";
  1594. return $prefix . '-' . $feature;
  1595. }
  1596. sub runAutogenForAutotoolsProjectIfNecessary($@)
  1597. {
  1598. my ($dir, $prefix, $sourceDir, $project, $joinedOverridableFeatures, @buildArgs) = @_;
  1599. # Always enable introspection when building WebKitGTK+.
  1600. unshift(@buildArgs, "--enable-introspection");
  1601. my $joinedBuildArgs = join(" ", @buildArgs);
  1602. if (-e "GNUmakefile") {
  1603. # Just assume that build-jsc will never be used to reconfigure JSC. Later
  1604. # we can go back and make this more complicated if the demand is there.
  1605. if ($project ne "WebKit") {
  1606. return;
  1607. }
  1608. # Run autogen.sh again if either the features overrided by build-webkit or build arguments have changed.
  1609. if (!mustReRunAutogen($sourceDir, "WebKitFeatureOverrides.txt", $joinedOverridableFeatures)
  1610. && !mustReRunAutogen($sourceDir, "previous-autogen-arguments.txt", $joinedBuildArgs)) {
  1611. return;
  1612. }
  1613. }
  1614. print "Calling autogen.sh in " . $dir . "\n\n";
  1615. print "Installation prefix directory: $prefix\n" if(defined($prefix));
  1616. # Only for WebKit, write the autogen.sh arguments to a file so that we can detect
  1617. # when they change and automatically re-run it.
  1618. if ($project eq 'WebKit') {
  1619. open(OVERRIDABLE_FEATURES, ">WebKitFeatureOverrides.txt");
  1620. print OVERRIDABLE_FEATURES $joinedOverridableFeatures;
  1621. close(OVERRIDABLE_FEATURES);
  1622. open(AUTOTOOLS_ARGUMENTS, ">previous-autogen-arguments.txt");
  1623. print AUTOTOOLS_ARGUMENTS $joinedBuildArgs;
  1624. close(AUTOTOOLS_ARGUMENTS);
  1625. }
  1626. # Make the path relative since it will appear in all -I compiler flags.
  1627. # Long argument lists cause bizarre slowdowns in libtool.
  1628. my $relSourceDir = File::Spec->abs2rel($sourceDir) || ".";
  1629. # Compiler options to keep floating point values consistent
  1630. # between 32-bit and 64-bit architectures. The options are also
  1631. # used on Chromium build.
  1632. determineArchitecture();
  1633. if ($architecture ne "x86_64" && !isARM()) {
  1634. $ENV{'CXXFLAGS'} = "-march=pentium4 -msse2 -mfpmath=sse " . ($ENV{'CXXFLAGS'} || "");
  1635. }
  1636. # Prefix the command with jhbuild run.
  1637. unshift(@buildArgs, "$relSourceDir/autogen.sh");
  1638. unshift(@buildArgs, jhbuildWrapperPrefixIfNeeded());
  1639. if (system(@buildArgs) ne 0) {
  1640. die "Calling autogen.sh failed!\n";
  1641. }
  1642. }
  1643. sub getJhbuildPath()
  1644. {
  1645. return join('/', baseProductDir(), "Dependencies");
  1646. }
  1647. sub mustReRunAutogen($@)
  1648. {
  1649. my ($sourceDir, $filename, $currentContents) = @_;
  1650. if (! -e $filename) {
  1651. return 1;
  1652. }
  1653. open(CONTENTS_FILE, $filename);
  1654. chomp(my $previousContents = <CONTENTS_FILE>);
  1655. close(CONTENTS_FILE);
  1656. # We only care about the WebKit2 argument when we are building WebKit itself.
  1657. # build-jsc never passes --enable-webkit2, so if we didn't do this, autogen.sh
  1658. # would run for every single build on the bots, since it runs both build-webkit
  1659. # and build-jsc.
  1660. if ($previousContents ne $currentContents) {
  1661. print "Contents for file $filename have changed.\n";
  1662. print "Previous contents were: $previousContents\n\n";
  1663. print "New contents are: $currentContents\n";
  1664. return 1;
  1665. }
  1666. return 0;
  1667. }
  1668. sub buildAutotoolsProject($@)
  1669. {
  1670. my ($project, $clean, $prefix, $makeArgs, $noWebKit1, $noWebKit2, @features) = @_;
  1671. my $make = 'make';
  1672. my $dir = productDir();
  1673. my $config = passedConfiguration() || configuration();
  1674. # Use rm to clean the build directory since distclean may miss files
  1675. if ($clean && -d $dir) {
  1676. system "rm", "-rf", "$dir";
  1677. }
  1678. if (! -d $dir) {
  1679. File::Path::mkpath($dir) or die "Failed to create build directory " . $dir
  1680. }
  1681. chdir $dir or die "Failed to cd into " . $dir . "\n";
  1682. if ($clean) {
  1683. return 0;
  1684. }
  1685. my @buildArgs = @ARGV;
  1686. if ($noWebKit1) {
  1687. unshift(@buildArgs, "--disable-webkit1");
  1688. }
  1689. if ($noWebKit2) {
  1690. unshift(@buildArgs, "--disable-webkit2");
  1691. }
  1692. # Configurable features listed here should be kept in sync with the
  1693. # features for which there exists a configuration option in configure.ac.
  1694. my %configurableFeatures = (
  1695. "battery-status" => 1,
  1696. "gamepad" => 1,
  1697. "geolocation" => 1,
  1698. "svg" => 1,
  1699. "svg-fonts" => 1,
  1700. "video" => 1,
  1701. "webgl" => 1,
  1702. "web-audio" => 1,
  1703. );
  1704. # These features are ones which build-webkit cannot control, typically because
  1705. # they can only be active when we have the proper dependencies.
  1706. my %unsetFeatures = (
  1707. "accelerated-2d-canvas" => 1,
  1708. );
  1709. my @overridableFeatures = ();
  1710. foreach (@features) {
  1711. if ($configurableFeatures{$_->{option}}) {
  1712. push @buildArgs, autotoolsFlag(${$_->{value}}, $_->{option});;
  1713. } elsif (!$unsetFeatures{$_->{option}}) {
  1714. push @overridableFeatures, $_->{define} . "=" . (${$_->{value}} ? "1" : "0");
  1715. }
  1716. }
  1717. $makeArgs = $makeArgs || "";
  1718. $makeArgs = $makeArgs . " " . $ENV{"WebKitMakeArguments"} if $ENV{"WebKitMakeArguments"};
  1719. # Automatically determine the number of CPUs for make only
  1720. # if make arguments haven't already been specified.
  1721. if ($makeArgs eq "") {
  1722. $makeArgs = "-j" . numberOfCPUs();
  1723. }
  1724. # WebKit is the default target, so we don't need to specify anything.
  1725. if ($project eq "JavaScriptCore") {
  1726. $makeArgs .= " jsc";
  1727. } elsif ($project eq "WTF") {
  1728. $makeArgs .= " libWTF.la";
  1729. }
  1730. $prefix = $ENV{"WebKitInstallationPrefix"} if !defined($prefix);
  1731. push @buildArgs, "--prefix=" . $prefix if defined($prefix);
  1732. # Check if configuration is Debug.
  1733. my $debug = $config =~ m/debug/i;
  1734. if ($debug) {
  1735. push @buildArgs, "--enable-debug";
  1736. } else {
  1737. push @buildArgs, "--disable-debug";
  1738. }
  1739. if (checkForArgumentAndRemoveFromArrayRef("--update-gtk", \@buildArgs)) {
  1740. # Force autogen to run, to catch the possibly updated libraries.
  1741. system("rm -f previous-autogen-arguments.txt");
  1742. system("perl", "$sourceDir/Tools/Scripts/update-webkitgtk-libs") == 0 or die $!;
  1743. }
  1744. # If GNUmakefile exists, don't run autogen.sh unless its arguments
  1745. # have changed. The makefile should be smart enough to track autotools
  1746. # dependencies and re-run autogen.sh when build files change.
  1747. my $joinedOverridableFeatures = join(" ", @overridableFeatures);
  1748. runAutogenForAutotoolsProjectIfNecessary($dir, $prefix, $sourceDir, $project, $joinedOverridableFeatures, @buildArgs);
  1749. my $runWithJhbuild = join(" ", jhbuildWrapperPrefixIfNeeded());
  1750. if (system("$runWithJhbuild $make $makeArgs") ne 0) {
  1751. die "\nFailed to build WebKit using '$make'!\n";
  1752. }
  1753. chdir ".." or die;
  1754. if ($project eq 'WebKit' && !isCrossCompilation() && !($noWebKit1 && $noWebKit2)) {
  1755. my @docGenerationOptions = ("$sourceDir/Tools/gtk/generate-gtkdoc", "--skip-html");
  1756. push(@docGenerationOptions, productDir());
  1757. unshift(@docGenerationOptions, jhbuildWrapperPrefixIfNeeded());
  1758. if (system(@docGenerationOptions)) {
  1759. die "\n gtkdoc did not build without warnings\n";
  1760. }
  1761. }
  1762. return 0;
  1763. }
  1764. sub jhbuildWrapperPrefixIfNeeded()
  1765. {
  1766. if (-e getJhbuildPath()) {
  1767. my @prefix = (File::Spec->catfile(sourceDir(), "Tools", "jhbuild", "jhbuild-wrapper"));
  1768. if (isEfl()) {
  1769. push(@prefix, "--efl");
  1770. } elsif (isGtk()) {
  1771. push(@prefix, "--gtk");
  1772. }
  1773. push(@prefix, "run");
  1774. return @prefix;
  1775. }
  1776. return ();
  1777. }
  1778. sub removeCMakeCache()
  1779. {
  1780. my $cacheFilePath = File::Spec->catdir(baseProductDir(), configuration(), "CMakeCache.txt");
  1781. unlink($cacheFilePath) if -e $cacheFilePath;
  1782. }
  1783. sub generateBuildSystemFromCMakeProject
  1784. {
  1785. my ($port, $prefixPath, @cmakeArgs, $additionalCMakeArgs) = @_;
  1786. my $config = configuration();
  1787. my $buildPath = File::Spec->catdir(baseProductDir(), $config);
  1788. File::Path::mkpath($buildPath) unless -d $buildPath;
  1789. my $originalWorkingDirectory = getcwd();
  1790. chdir($buildPath) or die;
  1791. my @args;
  1792. push @args, "-DPORT=\"$port\"";
  1793. push @args, "-DCMAKE_INSTALL_PREFIX=\"$prefixPath\"" if $prefixPath;
  1794. push @args, "-DSHARED_CORE=ON" if isEfl() && $ENV{"ENABLE_DRT"};
  1795. if ($config =~ /release/i) {
  1796. push @args, "-DCMAKE_BUILD_TYPE=Release";
  1797. } elsif ($config =~ /debug/i) {
  1798. push @args, "-DCMAKE_BUILD_TYPE=Debug";
  1799. }
  1800. # Don't warn variables which aren't used by cmake ports.
  1801. push @args, "--no-warn-unused-cli";
  1802. push @args, @cmakeArgs if @cmakeArgs;
  1803. push @args, $additionalCMakeArgs if $additionalCMakeArgs;
  1804. push @args, '"' . sourceDir() . '"';
  1805. # Compiler options to keep floating point values consistent
  1806. # between 32-bit and 64-bit architectures.
  1807. determineArchitecture();
  1808. if ($architecture ne "x86_64" && !isARM()) {
  1809. $ENV{'CXXFLAGS'} = "-march=pentium4 -msse2 -mfpmath=sse " . ($ENV{'CXXFLAGS'} || "");
  1810. }
  1811. # We call system("cmake @args") instead of system("cmake", @args) so that @args is
  1812. # parsed for shell metacharacters.
  1813. my $wrapper = join(" ", jhbuildWrapperPrefixIfNeeded()) . " ";
  1814. my $returnCode = system($wrapper . "cmake @args");
  1815. chdir($originalWorkingDirectory);
  1816. return $returnCode;
  1817. }
  1818. sub buildCMakeGeneratedProject($)
  1819. {
  1820. my ($makeArgs) = @_;
  1821. my $config = configuration();
  1822. my $buildPath = File::Spec->catdir(baseProductDir(), $config);
  1823. if (! -d $buildPath) {
  1824. die "Must call generateBuildSystemFromCMakeProject() before building CMake project.";
  1825. }
  1826. my @args = ("--build", $buildPath, "--config", $config);
  1827. push @args, ("--", $makeArgs) if $makeArgs;
  1828. # We call system("cmake @args") instead of system("cmake", @args) so that @args is
  1829. # parsed for shell metacharacters. In particular, $makeArgs may contain such metacharacters.
  1830. my $wrapper = join(" ", jhbuildWrapperPrefixIfNeeded()) . " ";
  1831. return system($wrapper . "cmake @args");
  1832. }
  1833. sub cleanCMakeGeneratedProject()
  1834. {
  1835. my $config = configuration();
  1836. my $buildPath = File::Spec->catdir(baseProductDir(), $config);
  1837. if (-d $buildPath) {
  1838. return system("cmake", "--build", $buildPath, "--config", $config, "--target", "clean");
  1839. }
  1840. return 0;
  1841. }
  1842. sub buildCMakeProjectOrExit($$$$@)
  1843. {
  1844. my ($clean, $port, $prefixPath, $makeArgs, @cmakeArgs) = @_;
  1845. my $returnCode;
  1846. exit(exitStatus(cleanCMakeGeneratedProject())) if $clean;
  1847. if (isEfl() && checkForArgumentAndRemoveFromARGV("--update-efl")) {
  1848. system("perl", "$sourceDir/Tools/Scripts/update-webkitefl-libs") == 0 or die $!;
  1849. }
  1850. $returnCode = exitStatus(generateBuildSystemFromCMakeProject($port, $prefixPath, @cmakeArgs));
  1851. exit($returnCode) if $returnCode;
  1852. if (isBlackBerry()) {
  1853. return 0 if (defined($ENV{"GENERATE_CMAKE_PROJECT_ONLY"}) eq '1');
  1854. }
  1855. $returnCode = exitStatus(buildCMakeGeneratedProject($makeArgs));
  1856. exit($returnCode) if $returnCode;
  1857. return 0;
  1858. }
  1859. sub cmakeBasedPortArguments()
  1860. {
  1861. return blackberryCMakeArguments() if isBlackBerry();
  1862. return ('-G "Visual Studio 8 2005 STANDARDSDK_500 (ARMV4I)"') if isWinCE();
  1863. return ();
  1864. }
  1865. sub cmakeBasedPortName()
  1866. {
  1867. return "BlackBerry" if isBlackBerry();
  1868. return "Efl" if isEfl();
  1869. return "WinCE" if isWinCE();
  1870. return "";
  1871. }
  1872. sub promptUser
  1873. {
  1874. my ($prompt, $default) = @_;
  1875. my $defaultValue = $default ? "[$default]" : "";
  1876. print "$prompt $defaultValue: ";
  1877. chomp(my $input = <STDIN>);
  1878. return $input ? $input : $default;
  1879. }
  1880. sub buildQMakeProjects
  1881. {
  1882. my ($projects, $clean, @buildParams) = @_;
  1883. my @buildArgs = ();
  1884. my $qconfigs = "";
  1885. my $make = qtMakeCommand($qmakebin);
  1886. my $makeargs = "";
  1887. my $command;
  1888. my $installHeaders;
  1889. my $installLibs;
  1890. for my $i (0 .. $#buildParams) {
  1891. my $opt = $buildParams[$i];
  1892. if ($opt =~ /^--qmake=(.*)/i ) {
  1893. $qmakebin = $1;
  1894. } elsif ($opt =~ /^--qmakearg=(.*)/i ) {
  1895. push @buildArgs, $1;
  1896. } elsif ($opt =~ /^--makeargs=(.*)/i ) {
  1897. $makeargs = $1;
  1898. } elsif ($opt =~ /^--install-headers=(.*)/i ) {
  1899. $installHeaders = $1;
  1900. } elsif ($opt =~ /^--install-libs=(.*)/i ) {
  1901. $installLibs = $1;
  1902. } else {
  1903. push @buildArgs, $opt;
  1904. }
  1905. }
  1906. # Automatically determine the number of CPUs for make only if this make argument haven't already been specified.
  1907. if ($make eq "make" && $makeargs !~ /-j\s*\d+/i && (!defined $ENV{"MAKEFLAGS"} || ($ENV{"MAKEFLAGS"} !~ /-j\s*\d+/i ))) {
  1908. $makeargs .= " -j" . numberOfCPUs();
  1909. }
  1910. $make = "$make $makeargs";
  1911. $make =~ s/\s+$//;
  1912. my $originalCwd = getcwd();
  1913. my $dir = File::Spec->canonpath(productDir());
  1914. File::Path::mkpath($dir);
  1915. chdir $dir or die "Failed to cd into " . $dir . "\n";
  1916. if ($clean) {
  1917. $command = "$make distclean";
  1918. print "\nCalling '$command' in " . $dir . "\n\n";
  1919. return system $command;
  1920. }
  1921. my $qmakepath = File::Spec->catfile(sourceDir(), "Tools", "qmake");
  1922. my $qmakecommand = $qmakebin;
  1923. my $config = configuration();
  1924. push @buildArgs, "INSTALL_HEADERS=" . $installHeaders if defined($installHeaders);
  1925. push @buildArgs, "INSTALL_LIBS=" . $installLibs if defined($installLibs);
  1926. my $passedConfig = passedConfiguration() || "";
  1927. if ($passedConfig =~ m/debug/i) {
  1928. push @buildArgs, "CONFIG-=release";
  1929. push @buildArgs, "CONFIG+=debug";
  1930. } elsif ($passedConfig =~ m/release/i) {
  1931. push @buildArgs, "CONFIG+=release";
  1932. push @buildArgs, "CONFIG-=debug";
  1933. } elsif ($passedConfig) {
  1934. die "Build type $passedConfig is not supported with --qt.\n";
  1935. }
  1936. # Using build-webkit to build assumes you want a developer-build
  1937. push @buildArgs, "CONFIG-=production_build";
  1938. my $svnRevision = currentSVNRevision();
  1939. my $previousSvnRevision = "unknown";
  1940. my $buildHint = "";
  1941. my $pathToBuiltRevisions = File::Spec->catfile($dir, ".builtRevisions.cache");
  1942. if (-e $pathToBuiltRevisions && open(BUILTREVISIONS, $pathToBuiltRevisions)) {
  1943. while (<BUILTREVISIONS>) {
  1944. if ($_ =~ m/^SVN_REVISION\s=\s(\d+)$/) {
  1945. $previousSvnRevision = $1;
  1946. }
  1947. }
  1948. close(BUILTREVISIONS);
  1949. }
  1950. my $result = 0;
  1951. # Run qmake, regadless of having a makefile or not, so that qmake can
  1952. # detect changes to the configuration.
  1953. push @buildArgs, "-after OVERRIDE_SUBDIRS=\"@{$projects}\"" if @{$projects};
  1954. unshift @buildArgs, File::Spec->catfile(sourceDir(), "WebKit.pro");
  1955. $command = "$qmakecommand @buildArgs";
  1956. print "Calling '$command' in " . $dir . "\n\n";
  1957. print "Installation headers directory: $installHeaders\n" if(defined($installHeaders));
  1958. print "Installation libraries directory: $installLibs\n" if(defined($installLibs));
  1959. my $configChanged = 0;
  1960. open(QMAKE, "$command 2>&1 |") || die "Could not execute qmake";
  1961. while (<QMAKE>) {
  1962. $configChanged = 1 if $_ =~ m/The configuration was changed since the last build/;
  1963. print $_;
  1964. }
  1965. close(QMAKE);
  1966. $result = $?;
  1967. if ($result ne 0) {
  1968. die "\nFailed to set up build environment using $qmakebin!\n";
  1969. }
  1970. my $maybeNeedsCleanBuild = 0;
  1971. my $needsIncrementalBuild = 0;
  1972. # Full incremental build (run qmake) needed on buildbots and EWS bots always.
  1973. if (grep(/CONFIG\+=buildbot/,@buildParams)) {
  1974. $needsIncrementalBuild = 1;
  1975. }
  1976. if ($svnRevision ne $previousSvnRevision) {
  1977. print "Last built revision was " . $previousSvnRevision .
  1978. ", now at revision $svnRevision. Full incremental build needed.\n";
  1979. $needsIncrementalBuild = 1;
  1980. my @fileList = listOfChangedFilesBetweenRevisions(sourceDir(), $previousSvnRevision, $svnRevision);
  1981. foreach (@fileList) {
  1982. if (m/\.pr[oif]$/ or
  1983. m/\.qmake.conf$/ or
  1984. m/^Tools\/qmake\//
  1985. ) {
  1986. print "Change to $_ detected, clean build may be needed.\n";
  1987. $maybeNeedsCleanBuild = 1;
  1988. last;
  1989. }
  1990. }
  1991. }
  1992. if ($configChanged) {
  1993. print "Calling '$make wipeclean' in " . $dir . "\n\n";
  1994. $result = system "$make wipeclean";
  1995. }
  1996. $command = "$make";
  1997. if ($needsIncrementalBuild) {
  1998. $command .= " incremental";
  1999. }
  2000. print "\nCalling '$command' in " . $dir . "\n\n";
  2001. $result = system $command;
  2002. chdir ".." or die;
  2003. if ($result eq 0) {
  2004. # Now that the build completed successfully we can save the SVN revision
  2005. open(BUILTREVISIONS, ">>$pathToBuiltRevisions");
  2006. print BUILTREVISIONS "SVN_REVISION = $svnRevision\n";
  2007. close(BUILTREVISIONS);
  2008. } elsif (!$command =~ /incremental/ && exitStatus($result)) {
  2009. my $exitCode = exitStatus($result);
  2010. my $failMessage = <<EOF;
  2011. ===== BUILD FAILED ======
  2012. The build failed with exit code $exitCode. This may have been because you
  2013. - added an #include to a source/header
  2014. - added a Q_OBJECT macro to a class
  2015. - added a new resource to a qrc file
  2016. as dependencies are not automatically re-computed for local developer builds.
  2017. You may try computing dependencies manually by running 'make qmake_all' in:
  2018. $dir
  2019. or passing --makeargs="qmake_all" to build-webkit.
  2020. =========================
  2021. EOF
  2022. print "$failMessage";
  2023. } elsif ($maybeNeedsCleanBuild) {
  2024. print "\nIncremental build failed, clean build needed. \n";
  2025. print "Calling '$make wipeclean' in " . $dir . "\n\n";
  2026. chdir $dir or die;
  2027. system "$make wipeclean";
  2028. print "\nCalling '$make' in " . $dir . "\n\n";
  2029. $result = system $make;
  2030. }
  2031. return $result;
  2032. }
  2033. sub buildGtkProject
  2034. {
  2035. my ($project, $clean, $prefix, $makeArgs, $noWebKit1, $noWebKit2, @features) = @_;
  2036. if ($project ne "WebKit" and $project ne "JavaScriptCore" and $project ne "WTF") {
  2037. die "Unsupported project: $project. Supported projects: WebKit, JavaScriptCore, WTF\n";
  2038. }
  2039. return buildAutotoolsProject($project, $clean, $prefix, $makeArgs, $noWebKit1, $noWebKit2, @features);
  2040. }
  2041. sub appleApplicationSupportPath
  2042. {
  2043. open INSTALL_DIR, "</proc/registry/HKEY_LOCAL_MACHINE/SOFTWARE/Apple\ Inc./Apple\ Application\ Support/InstallDir";
  2044. my $path = <INSTALL_DIR>;
  2045. $path =~ s/[\r\n\x00].*//;
  2046. close INSTALL_DIR;
  2047. my $unixPath = `cygpath -u '$path'`;
  2048. chomp $unixPath;
  2049. return $unixPath;
  2050. }
  2051. sub setPathForRunningWebKitApp
  2052. {
  2053. my ($env) = @_;
  2054. if (isAppleWinWebKit()) {
  2055. $env->{PATH} = join(':', productDir(), dirname(installedSafariPath()), appleApplicationSupportPath(), $env->{PATH} || "");
  2056. } elsif (isQt()) {
  2057. my $qtLibs = `$qmakebin -query QT_INSTALL_LIBS`;
  2058. $qtLibs =~ s/[\n|\r]$//g;
  2059. $env->{PATH} = join(';', $qtLibs, productDir() . "/lib", $env->{PATH} || "");
  2060. }
  2061. }
  2062. sub printHelpAndExitForRunAndDebugWebKitAppIfNeeded
  2063. {
  2064. return unless checkForArgumentAndRemoveFromARGV("--help");
  2065. my ($includeOptionsForDebugging) = @_;
  2066. print STDERR <<EOF;
  2067. Usage: @{[basename($0)]} [options] [args ...]
  2068. --help Show this help message
  2069. --no-saved-state Launch the application without state restoration (OS X 10.7 and later)
  2070. --guard-malloc Enable Guard Malloc (OS X only)
  2071. --use-web-process-xpc-service Launch the Web Process as an XPC Service (OS X only)
  2072. EOF
  2073. if ($includeOptionsForDebugging) {
  2074. print STDERR <<EOF;
  2075. --target-web-process Debug the web process
  2076. --use-gdb Use GDB (this is the default when using Xcode 4.4 or earlier)
  2077. --use-lldb Use LLDB (this is the default when using Xcode 4.5 or later)
  2078. EOF
  2079. }
  2080. exit(1);
  2081. }
  2082. sub argumentsForRunAndDebugMacWebKitApp()
  2083. {
  2084. my @args = ();
  2085. push @args, ("-ApplePersistenceIgnoreState", "YES") if !isSnowLeopard() && checkForArgumentAndRemoveFromArrayRef("--no-saved-state", \@args);
  2086. push @args, ("-WebKit2UseXPCServiceForWebProcess", "YES") if shouldUseXPCServiceForWebProcess();
  2087. unshift @args, @ARGV;
  2088. return @args;
  2089. }
  2090. sub runMacWebKitApp($;$)
  2091. {
  2092. my ($appPath, $useOpenCommand) = @_;
  2093. my $productDir = productDir();
  2094. print "Starting @{[basename($appPath)]} with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
  2095. $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
  2096. $ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES";
  2097. setUpGuardMallocIfNeeded();
  2098. if (defined($useOpenCommand) && $useOpenCommand == USE_OPEN_COMMAND) {
  2099. return system("open", "-W", "-a", $appPath, "--args", argumentsForRunAndDebugMacWebKitApp());
  2100. }
  2101. if (architecture()) {
  2102. return system "arch", "-" . architecture(), $appPath, argumentsForRunAndDebugMacWebKitApp();
  2103. }
  2104. return system { $appPath } $appPath, argumentsForRunAndDebugMacWebKitApp();
  2105. }
  2106. sub execMacWebKitAppForDebugging($)
  2107. {
  2108. my ($appPath) = @_;
  2109. my $architectureSwitch;
  2110. my $argumentsSeparator;
  2111. if (debugger() eq "lldb") {
  2112. $architectureSwitch = "--arch";
  2113. $argumentsSeparator = "--";
  2114. } elsif (debugger() eq "gdb") {
  2115. $architectureSwitch = "-arch";
  2116. $argumentsSeparator = "--args";
  2117. } else {
  2118. die "Unknown debugger $debugger.\n";
  2119. }
  2120. my $debuggerPath = `xcrun -find $debugger`;
  2121. chomp $debuggerPath;
  2122. die "Can't find the $debugger executable.\n" unless -x $debuggerPath;
  2123. my $productDir = productDir();
  2124. $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
  2125. $ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES";
  2126. setUpGuardMallocIfNeeded();
  2127. my @architectureFlags = ($architectureSwitch, architecture());
  2128. if (!shouldTargetWebProcess()) {
  2129. print "Starting @{[basename($appPath)]} under $debugger with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
  2130. exec { $debuggerPath } $debuggerPath, @architectureFlags, $argumentsSeparator, $appPath, argumentsForRunAndDebugMacWebKitApp() or die;
  2131. } else {
  2132. if (shouldUseXPCServiceForWebProcess()) {
  2133. die "Targetting the Web Process is not compatible with using an XPC Service for the Web Process at this time.";
  2134. }
  2135. my $webProcessShimPath = File::Spec->catfile($productDir, "SecItemShim.dylib");
  2136. my $webProcessPath = File::Spec->catdir($productDir, "WebProcess.app");
  2137. my $webKit2ExecutablePath = File::Spec->catfile($productDir, "WebKit2.framework", "WebKit2");
  2138. appendToEnvironmentVariableList("DYLD_INSERT_LIBRARIES", $webProcessShimPath);
  2139. print "Starting WebProcess under $debugger with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
  2140. exec { $debuggerPath } $debuggerPath, @architectureFlags, $argumentsSeparator, $webProcessPath, $webKit2ExecutablePath, "-type", "webprocess", "-client-executable", $appPath or die;
  2141. }
  2142. }
  2143. sub debugSafari
  2144. {
  2145. if (isAppleMacWebKit()) {
  2146. checkFrameworks();
  2147. execMacWebKitAppForDebugging(safariPath());
  2148. }
  2149. return 1; # Unsupported platform; can't debug Safari on this platform.
  2150. }
  2151. sub runSafari
  2152. {
  2153. if (isAppleMacWebKit()) {
  2154. return runMacWebKitApp(safariPath());
  2155. }
  2156. if (isAppleWinWebKit()) {
  2157. my $result;
  2158. my $productDir = productDir();
  2159. my $webKitLauncherPath = File::Spec->catfile(productDir(), "WinLauncher.exe");
  2160. return system { $webKitLauncherPath } $webKitLauncherPath, @ARGV;
  2161. }
  2162. return 1; # Unsupported platform; can't run Safari on this platform.
  2163. }
  2164. sub runMiniBrowser
  2165. {
  2166. if (isAppleMacWebKit()) {
  2167. return runMacWebKitApp(File::Spec->catfile(productDir(), "MiniBrowser.app", "Contents", "MacOS", "MiniBrowser"));
  2168. }
  2169. return 1;
  2170. }
  2171. sub debugMiniBrowser
  2172. {
  2173. if (isAppleMacWebKit()) {
  2174. execMacWebKitAppForDebugging(File::Spec->catfile(productDir(), "MiniBrowser.app", "Contents", "MacOS", "MiniBrowser"));
  2175. }
  2176. return 1;
  2177. }
  2178. sub runWebKitTestRunner
  2179. {
  2180. if (isAppleMacWebKit()) {
  2181. return runMacWebKitApp(File::Spec->catfile(productDir(), "WebKitTestRunner"));
  2182. } elsif (isGtk()) {
  2183. my $productDir = productDir();
  2184. my $injectedBundlePath = "$productDir/Libraries/.libs/libTestRunnerInjectedBundle";
  2185. print "Starting WebKitTestRunner with TEST_RUNNER_INJECTED_BUNDLE_FILENAME set to point to $injectedBundlePath.\n";
  2186. $ENV{TEST_RUNNER_INJECTED_BUNDLE_FILENAME} = $injectedBundlePath;
  2187. my @args = ("$productDir/Programs/WebKitTestRunner", @ARGV);
  2188. return system {$args[0] } @args;
  2189. }
  2190. return 1;
  2191. }
  2192. sub debugWebKitTestRunner
  2193. {
  2194. if (isAppleMacWebKit()) {
  2195. execMacWebKitAppForDebugging(File::Spec->catfile(productDir(), "WebKitTestRunner"));
  2196. }
  2197. return 1;
  2198. }
  2199. sub runTestWebKitAPI
  2200. {
  2201. if (isAppleMacWebKit()) {
  2202. return runMacWebKitApp(File::Spec->catfile(productDir(), "TestWebKitAPI"));
  2203. }
  2204. return 1;
  2205. }
  2206. sub readRegistryString
  2207. {
  2208. my ($valueName) = @_;
  2209. chomp(my $string = `regtool --wow32 get "$valueName"`);
  2210. return $string;
  2211. }
  2212. sub writeRegistryString
  2213. {
  2214. my ($valueName, $string) = @_;
  2215. my $error = system "regtool", "--wow32", "set", "-s", $valueName, $string;
  2216. # On Windows Vista/7 with UAC enabled, regtool will fail to modify the registry, but will still
  2217. # return a successful exit code. So we double-check here that the value we tried to write to the
  2218. # registry was really written.
  2219. return !$error && readRegistryString($valueName) eq $string;
  2220. }
  2221. 1;