Home | History | Annotate | Download | only in Scripts
      1 #!/usr/bin/perl
      2 
      3 # Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. 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 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 
     29 # "check-for-weak-vtables-and-externals" script for WebKit Open Source Project
     30 
     31 # Intended to be invoked from an Xcode build step to check if there are
     32 # any weak vtables or weak externals in a target.
     33 
     34 use warnings;
     35 use strict;
     36 
     37 use File::Basename;
     38 
     39 sub touch($);
     40 
     41 my $arch = $ENV{'CURRENT_ARCH'};
     42 my $configuration = $ENV{'CONFIGURATION'};
     43 my $target = $ENV{'TARGET_NAME'};
     44 my $variant = $ENV{'CURRENT_VARIANT'};
     45 my $coverageBuild = $ENV{'WEBKIT_COVERAGE_BUILD'};
     46 my $debugRoot = $ENV{'WEBKIT_DEBUG_ROOT'};
     47 
     48 $arch = $ENV{'NATIVE_ARCH'} if !$arch; # for Xcode 2.1, which does not have CURRENT_ARCH
     49 $variant = "normal" if !$variant; # for Xcode 2.1, which does not have CURRENT_VARIANT
     50 
     51 my $executablePath = "$ENV{'TARGET_BUILD_DIR'}/$ENV{'EXECUTABLE_PATH'}";
     52 
     53 my $buildTimestampPath = $ENV{'TARGET_TEMP_DIR'} . "/" . basename($0) . ".timestamp";
     54 my $buildTimestampAge = -M $buildTimestampPath;
     55 my $executablePathAge = -M $executablePath;
     56 
     57 my $sawError = 0;
     58 
     59 if (!defined $executablePathAge || !defined $buildTimestampAge || $executablePathAge > $buildTimestampAge) {
     60     if (!open NM, "(nm -m '$executablePath' | c++filt | sed 's/^/STDOUT:/') 2>&1 |") {
     61         print "ERROR: Could not open $executablePath\n";
     62         $sawError = 1;
     63         next;
     64     }
     65     my @weakVTableClasses = ();
     66     my @weakExternalSymbols = ();
     67     while (<NM>) {
     68         if (/^STDOUT:/) {
     69             # Ignore undefined, RTTI and typeinfo symbols.
     70             next if /\bundefined\b/ or /\b__ZT[IS]/;
     71 
     72             if (/weak external vtable for (.*)$/) {
     73                 push @weakVTableClasses, $1;
     74             } elsif (/weak external (.*)$/) {
     75                 push @weakExternalSymbols, $1;
     76             }
     77         } else {
     78             print STDERR if $_ ne "nm: no name list\n";
     79         }
     80     }
     81     close NM;
     82 
     83     my $shortName = $executablePath;
     84     $shortName =~ s/.*\///;
     85 
     86     if (@weakVTableClasses) {
     87         print "ERROR: $shortName has a weak vtable in it ($executablePath)\n";
     88         print "ERROR: Fix by making sure the first virtual function in each of these classes is not an inline:\n";
     89         for my $class (sort @weakVTableClasses) {
     90             print "ERROR: class $class\n";
     91         }
     92         $sawError = 1;
     93     }
     94 
     95     if (@weakExternalSymbols) {
     96         print "ERROR: $shortName has a weak external symbol in it ($executablePath)\n";
     97         print "ERROR: A weak external symbol is generated when a symbol is defined in multiple compilation units and is also marked as being exported from the library.\n";
     98         print "ERROR: A common cause of weak external symbols is when an inline function is listed in the linker export file.\n";
     99         for my $symbol (sort @weakExternalSymbols) {
    100             print "ERROR: symbol $symbol\n";
    101         }
    102         $sawError = 1;
    103     }
    104 }
    105 
    106 if ($sawError and !$coverageBuild) {
    107     unlink $executablePath;
    108     exit 1;
    109 }
    110 
    111 touch($buildTimestampPath);
    112 
    113 exit 0;
    114 
    115 sub touch($)
    116 {
    117     my ($path) = @_;
    118     open(TOUCH, ">", $path) or die "$!";
    119     close(TOUCH);
    120 }
    121