48c45338751693d319b7a362c25b22f298e6b1b8
[WebKit-https.git] / WebKitTools / Scripts / webkitdirs.pm
1 # Copyright (C) 2005, 2006 Apple Computer, Inc.  All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions
5 # are met:
6 #
7 # 1.  Redistributions of source code must retain the above copyright
8 #     notice, this list of conditions and the following disclaimer. 
9 # 2.  Redistributions in binary form must reproduce the above copyright
10 #     notice, this list of conditions and the following disclaimer in the
11 #     documentation and/or other materials provided with the distribution. 
12 # 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
13 #     its contributors may be used to endorse or promote products derived
14 #     from this software without specific prior written permission. 
15 #
16 # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
17 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 # DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
20 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27 # Module to share code to get to WebKit directories.
28
29 use strict;
30 use warnings;
31 use FindBin;
32
33 BEGIN {
34    use Exporter   ();
35    our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
36    $VERSION     = 1.00;
37    @ISA         = qw(Exporter);
38    @EXPORT      = qw(&chdirWebKit &baseProductDir &productDir &XcodeOptions &XcodeOptionString &XcodeOptionStringNoConfig &passedConfiguration &setConfiguration &safariPath &checkFrameworks &currentSVNRevision);
39    %EXPORT_TAGS = ( );
40    @EXPORT_OK   = ();
41 }
42
43 our @EXPORT_OK;
44
45 my $baseProductDir;
46 my @baseProductDirOption;
47 my $configuration;
48 my $configurationProductDir;
49 my $sourceDir;
50 my $currentSVNRevision;
51
52
53 # Variables for Win32 support
54 my $devenvPath;
55 my $windowsTmpPath;
56
57 sub determineSourceDir
58 {
59     return if $sourceDir;
60     $sourceDir = $FindBin::Bin;
61     if ($sourceDir !~ s|/[^/]+/[^/]+$||) {
62         die "Could not find two levels above source directory using FindBin.\n";
63     }
64 }
65
66 # used for scripts which are stored in a non-standard location
67 sub setSourceDir($)
68 {
69     $sourceDir = $_;
70 }
71
72 sub determineBaseProductDir
73 {
74     return if defined $baseProductDir;
75     determineSourceDir();
76     if (isOSX()) {
77         open PRODUCT, "defaults read com.apple.Xcode PBXProductDirectory 2> /dev/null |" or die;
78         $baseProductDir = <PRODUCT>;
79         close PRODUCT;
80         if ($baseProductDir) {
81             chomp $baseProductDir;
82         }
83     } else {
84         $baseProductDir = $ENV{"WebKitOutputDir"};
85         if (isCygwin() && $baseProductDir) {
86             my $unixBuildPath = `cygpath --unix \"$baseProductDir\"`;
87             chomp $unixBuildPath;
88             $baseProductDir = $unixBuildPath;
89         }
90     }
91
92     if ($baseProductDir && isOSX()) {
93         $baseProductDir =~ s|^\Q$(SRCROOT)/..\E$|$sourceDir|;
94         $baseProductDir =~ s|^\Q$(SRCROOT)/../|$sourceDir/|;
95         $baseProductDir =~ s|^~/|$ENV{HOME}/|;
96         die "Can't handle Xcode product directory with a ~ in it.\n" if $baseProductDir =~ /~/;
97         die "Can't handle Xcode product directory with a variable in it.\n" if $baseProductDir =~ /\$/;
98         @baseProductDirOption = ();
99     }
100
101     if (!defined($baseProductDir)) {
102         $baseProductDir = "$sourceDir/WebKitBuild";
103         @baseProductDirOption = ("SYMROOT=$baseProductDir") if (isOSX());
104         if (isCygwin()) {
105             my $dosBuildPath = `cygpath --windows \"$baseProductDir\"`;
106             chomp $dosBuildPath;
107             $ENV{"WebKitOutputDir"} = $dosBuildPath;
108         }
109     }
110 }
111
112 sub determineConfiguration
113 {
114     return if defined $configuration;
115     determineBaseProductDir();
116     if (open CONFIGURATION, "$baseProductDir/Configuration") {
117         $configuration = <CONFIGURATION>;
118         close CONFIGURATION;
119     }
120     if ($configuration) {
121         chomp $configuration;
122         # compatibility for people who have old Configuration files
123         $configuration = "Release" if $configuration eq "Deployment";
124         $configuration = "Debug" if $configuration eq "Development";
125     } else {
126         $configuration = "Release";
127     }
128
129     if (isQt()) {
130         # We only support one build type for now
131         $configuration = "";
132     }
133 }
134
135 sub determineConfigurationProductDir
136 {
137     return if defined $configurationProductDir;
138     determineBaseProductDir();
139     determineConfiguration();
140     $configurationProductDir = "$baseProductDir/$configuration";
141 }
142
143 sub determineCurrentSVNRevision
144 {
145     return if defined $currentSVNRevision;
146     determineSourceDir();
147     my $svnInfo = `svn info $sourceDir | grep Revision:`;
148     ($currentSVNRevision) = ($svnInfo =~ m/Revision: (\d+).*/g);
149     die "Unable to determine current SVN revision in $sourceDir" unless (defined $currentSVNRevision);
150     return $currentSVNRevision;
151 }
152
153
154 sub chdirWebKit
155 {
156     determineSourceDir();
157     chdir $sourceDir or die;
158 }
159
160 sub baseProductDir
161 {
162     determineBaseProductDir();
163     return $baseProductDir;
164 }
165
166 sub productDir
167 {
168     determineConfigurationProductDir();
169     return $configurationProductDir;
170 }
171
172 sub configuration()
173 {
174     determineConfiguration();
175     return $configuration;
176 }
177
178 sub currentSVNRevision
179 {
180     determineCurrentSVNRevision();
181     return $currentSVNRevision;
182 }
183
184 sub XcodeOptions
185 {
186     determineBaseProductDir();
187     determineConfiguration();
188     return (@baseProductDirOption, "-configuration", $configuration);
189 }
190
191 sub XcodeOptionString
192 {
193     return join " ", XcodeOptions();
194 }
195
196 sub XcodeOptionStringNoConfig
197 {
198     return join " ", @baseProductDirOption;
199 }
200
201 my $passedConfiguration;
202 my $searchedForPassedConfiguration;
203 sub determinePassedConfiguration
204 {
205     return if $searchedForPassedConfiguration;
206     $searchedForPassedConfiguration = 1;
207     for my $i (0 .. $#ARGV) {
208         my $opt = $ARGV[$i];
209         if ($opt =~ /^--debug$/i || $opt =~ /^--devel/i) {
210             splice(@ARGV, $i, 1);
211             $passedConfiguration = "Debug";
212             return;
213         }
214         if ($opt =~ /^--release$/i || $opt =~ /^--deploy/i) {
215             splice(@ARGV, $i, 1);
216             $passedConfiguration = "Release";
217             return;
218         }
219     }
220     $passedConfiguration = undef;
221 }
222
223 sub passedConfiguration
224 {
225     determinePassedConfiguration();
226     return $passedConfiguration;
227 }
228
229 sub setConfiguration
230 {
231     determinePassedConfiguration();
232     $configuration = $passedConfiguration if $passedConfiguration;
233 }
234
235 # Locate Safari.
236 sub safariPath
237 {
238     # Use WEBKIT_SAFARI environment variable if present.
239     my $safariBundle = $ENV{WEBKIT_SAFARI};
240     if (!$safariBundle) {
241         determineConfigurationProductDir();
242         # Use Safari.app in product directory if present (good for Safari development team).
243         if (-d "$configurationProductDir/Safari.app") {
244             $safariBundle = "$configurationProductDir/Safari.app";
245         } else {
246             # Otherwise use Safari.app in Applications directory.
247             $safariBundle = "/Applications/Safari.app";
248         }
249     }
250     my $safariPath = "$safariBundle/Contents/MacOS/Safari";
251     die "Can't find executable at $safariPath.\n" unless -x $safariPath;
252     return $safariPath;
253 }
254
255 sub builtDylibPathForName
256 {
257     my $framework = shift;
258     determineConfigurationProductDir();
259     if (isOSX()) {
260         return "$configurationProductDir/$framework.framework/Versions/A/$framework";
261     }
262     if (isCygwin()) {
263         return "$baseProductDir/$framework.intermediate/$configuration/$framework.intermediate/$framework.lib";
264     }
265     if (isQt()) {
266         return "$baseProductDir/../../../$framework";
267     }
268
269     die "Unsupported platform, can't determine built library locations.";
270 }
271
272 # Check to see that all the frameworks are built.
273 sub checkFrameworks
274 {
275     my @frameworks = ("JavaScriptCore", "WebCore");
276     push(@frameworks, "WebKit") if isOSX();
277     for my $framework (@frameworks) {
278         my $path = builtDylibPathForName($framework);
279         die "Can't find built framework at \"$path\".\n" unless -x $path;
280     }
281 }
282
283 sub hasSVGSupport
284 {
285     return 0 if isCygwin();
286
287     my $path = shift;
288
289     if ((isQt()) and ($path =~ /WebCore/)) {
290         $path .= "/../lib/libWebCore-unity.so";
291     }
292
293     open NM, "-|", "nm", $path or die;
294     my $hasSVGSupport = 0;
295     while (<NM>) {
296         $hasSVGSupport = 1 if /SVGElement/;
297     }
298     close NM;
299     return $hasSVGSupport;
300 }
301
302 sub removeLibraryDependingOnSVG
303 {
304     my $frameworkName = shift;
305     my $shouldHaveSVG = shift;
306
307     my $path = builtDylibPathForName($frameworkName);
308     return unless -x $path;
309
310     my $hasSVG = hasSVGSupport($path);
311     system "rm -f $path" if ($shouldHaveSVG xor $hasSVG);
312 }
313
314 sub checkWebCoreSVGSupport
315 {
316     my $required = shift;
317     my $framework = "WebCore";
318     my $path = builtDylibPathForName($framework);
319     my $hasSVG = hasSVGSupport($path);
320     if ($required && !$hasSVG) {
321         die "$framework at \"$path\" does not include SVG Support, please run build-webkit --svg\n";
322     }
323     return $hasSVG;
324 }
325
326 sub isQt()
327 {
328     return ($^O eq "linux") and defined($ENV{'QTDIR'})
329 }
330
331 sub isCygwin()
332 {
333     return ($^O eq "cygwin");
334 }
335
336 sub isOSX()
337 {
338     return ($^O eq "darwin");
339 }
340
341 sub checkRequiredSystemConfig
342 {
343     if (isOSX()) {
344         chomp(my $productVersion = `sw_vers -productVersion`);
345         if ($productVersion lt "10.4") {
346             print "*************************************************************\n";
347             print "Mac OS X Version 10.4.0 or later is required to build WebKit.\n";
348             print "You have " . $productVersion . ", thus the build will most likely fail.\n";
349             print "*************************************************************\n";
350         }
351         my $xcodeVersion = `xcodebuild -version`;
352         if ($xcodeVersion !~ /DevToolsCore-(\d+)/ || $1 < 747) {
353             print "*************************************************************\n";
354             print "Xcode Version 2.3 or later is required to build WebKit.\n";
355             print "You have an earlier version of Xcode, thus the build will\n";
356             print "most likely fail.  The latest Xcode is available from the web:\n";
357             print "http://developer.apple.com/tools/xcode\n";
358             print "*************************************************************\n";
359         }
360     }
361     # Win32 and other platforms may want to check for minimum config
362 }
363
364 sub setupCygwinEnv()
365 {
366     return if !isCygwin();
367     return if $devenvPath;
368
369     my $programFilesPath = `cygpath "$ENV{'PROGRAMFILES'}"`;
370     chomp $programFilesPath;
371     $devenvPath = "$programFilesPath/Microsoft Visual Studio 8/Common7/IDE/devenv.com";
372     $windowsTmpPath = `cygpath -w /tmp`;
373     chomp $windowsTmpPath;
374     print "Building results into: ", baseProductDir(), "\n";
375     print "WebKitOutputDir is set to: ", $ENV{"WebKitOutputDir"}, "\n";
376 }
377
378 sub buildVisualStudioProject($)
379 {
380     my ($project) = @_;
381     setupCygwinEnv();
382
383     chdir "$project.vcproj" or die "Failed to cd into $project.vcproj\n";
384     my $config = configuration();
385
386     print "$devenvPath $project.sln /build $config";
387     my $result = system $devenvPath, "$project.sln", "/build", $config;
388     chdir ".." or die;
389     return $result;
390 }
391
392 1;