Home | History | Annotate | Download | only in Scripts
      1 #!/usr/bin/perl
      2 
      3 # Copyright (C) 2006, 2007, 2008, 2010, 2011 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 # 1. Redistributions of source code must retain the above copyright
      9 #    notice, this list of conditions and the following disclaimer.
     10 # 2. Redistributions in binary form must reproduce the above copyright
     11 #    notice, this list of conditions and the following disclaimer in the
     12 #    documentation and/or other materials provided with the distribution.
     13 #
     14 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
     15 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     16 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     17 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
     18 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     19 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     20 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     21 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     22 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     23 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     24 # THE POSSIBILITY OF SUCH DAMAGE.
     25 
     26 # "check-for-inappropriate-objc-class-names" script for WebKit Open Source Project
     27 
     28 # Intended to be invoked from an Xcode build step to check if a framework
     29 # defines any Objective-C class whose name does not have one of the prefixes
     30 # the framework is allowed to use.
     31 
     32 use warnings;
     33 use strict;
     34 
     35 use File::Basename;
     36 
     37 sub touch($);
     38 
     39 my @allowedPrefixes = @ARGV;
     40 
     41 # Xcode will automatically link ObjC binaries against libarclite in some cases, which defines a class called __ARCLite__.
     42 push(@allowedPrefixes, "__ARCLite");
     43 
     44 die "No allowed prefixes passed on the command line" if !@allowedPrefixes;
     45 
     46 my $arch = $ENV{'CURRENT_ARCH'};
     47 my $target = $ENV{'TARGET_NAME'};
     48 my $variant = $ENV{'CURRENT_VARIANT'};
     49 my $coverageBuild = $ENV{'WEBKIT_COVERAGE_BUILD'};
     50 
     51 my $executablePath = "$ENV{'TARGET_BUILD_DIR'}/$ENV{'EXECUTABLE_PATH'}";
     52 
     53 my $buildTimestampPath = $ENV{'TARGET_TEMP_DIR'} . "/" . basename($0) . join('-', @allowedPrefixes) . ".timestamp";
     54 my $buildTimestampAge = -M $buildTimestampPath;
     55 my $executablePathAge = -M $executablePath;
     56 my $scriptAge = -M $0;
     57 
     58 my $pattern = "^(" . join('|', @allowedPrefixes) . ")";
     59 
     60 my $sawError = 0;
     61 
     62 if (!defined $executablePathAge || !defined $buildTimestampAge || $executablePathAge < $buildTimestampAge || $scriptAge < $buildTimestampAge) {
     63     if (!open NM, "(nm -Ugjp '$executablePath' | sed 's/^/STDOUT:/') 2>&1 |") {
     64         print "ERROR: Could not open $executablePath\n";
     65         $sawError = 1;
     66         next;
     67     }
     68     my @badNames;
     69     while (<NM>) {
     70         if (/^STDOUT:/) {
     71             next unless /^STDOUT:_OBJC_CLASS_\$_/;
     72             chomp;
     73             my $className = substr($_, 21);
     74             push(@badNames, $className) unless $className =~ /$pattern/;
     75         } else {
     76             print STDERR if $_ ne "nm: no name list\n";
     77         }
     78     }
     79     close NM;
     80 
     81     if (@badNames) {
     82 
     83         my $shortName = $executablePath;
     84         $shortName =~ s/.*\///;
     85 
     86         print "ERROR: $shortName defines one or more Objective-C classes with inappropriate names. ($executablePath)\n";
     87         for my $className (@badNames) {
     88             print "ERROR: Inappropriate Objective-C class name: $className.\n";
     89         }
     90 
     91         if (@allowedPrefixes > 1) {
     92             print "ERROR: Objective-C class names in $target must have one of these prefixes: " . join(", ", map('"' . $_ . '"', @allowedPrefixes)) . ".\n";
     93         } else {
     94             print "ERROR: Objective-C class names in $target must have the prefix \"" . $allowedPrefixes[0] . "\".\n";
     95         }
     96 
     97         $sawError = 1;
     98     }
     99 }
    100 
    101 if ($sawError and !$coverageBuild) {
    102     unlink $executablePath;
    103     exit 1;
    104 }
    105 
    106 touch($buildTimestampPath);
    107 exit 0;
    108 
    109 sub touch($)
    110 {
    111     my ($path) = @_;
    112     open(TOUCH, ">", $path) or die "$!";
    113     close(TOUCH);
    114 }
    115