check-for-global-initializers 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #!/usr/bin/perl
  2. # Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
  3. #
  4. # Redistribution and use in source and binary forms, with or without
  5. # modification, are permitted provided that the following conditions
  6. # are met:
  7. #
  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. # 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
  14. # its contributors may be used to endorse or promote products derived
  15. # from this software without specific prior written permission.
  16. #
  17. # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
  18. # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19. # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20. # DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
  21. # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22. # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23. # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  24. # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. # "check-for-global-initializers" script for WebKit Open Source Project
  28. # Intended to be invoked from an Xcode build step to check if there are
  29. # any global initializers in a target.
  30. use warnings;
  31. use strict;
  32. use File::Basename;
  33. sub touch($);
  34. sub demangle($);
  35. my $arch = $ENV{'CURRENT_ARCH'};
  36. my $configuration = $ENV{'CONFIGURATION'};
  37. my $target = $ENV{'TARGET_NAME'};
  38. my $variant = $ENV{'CURRENT_VARIANT'};
  39. my $coverageBuild = $ENV{'WEBKIT_COVERAGE_BUILD'};
  40. my $debugRoot = $ENV{'WEBKIT_DEBUG_ROOT'};
  41. $arch = $ENV{'NATIVE_ARCH'} if !$arch; # for Xcode 2.1, which does not have CURRENT_ARCH
  42. $variant = "normal" if !$variant; # for Xcode 2.1, which does not have CURRENT_VARIANT
  43. my $executablePath = "$ENV{'TARGET_BUILD_DIR'}/$ENV{'EXECUTABLE_PATH'}";
  44. my $buildTimestampPath = $ENV{'TARGET_TEMP_DIR'} . "/" . basename($0) . ".timestamp";
  45. my $buildTimestampAge = -M $buildTimestampPath;
  46. my $scriptAge = -M $0;
  47. my $list = $ENV{"LINK_FILE_LIST_${variant}_${arch}"};
  48. if (!open LIST, $list) {
  49. print "ERROR: Could not open $list\n";
  50. exit 1;
  51. }
  52. my @files = <LIST>;
  53. chomp @files;
  54. close LIST;
  55. my $sawError = 0;
  56. for my $file (sort @files) {
  57. if (defined $buildTimestampAge && $buildTimestampAge < $scriptAge) {
  58. my $fileAge = -M $file;
  59. next if defined $fileAge && $fileAge > $buildTimestampAge;
  60. }
  61. if (!open NM, "(nm '$file' | sed 's/^/STDOUT:/') 2>&1 |") {
  62. print "ERROR: Could not open $file\n";
  63. $sawError = 1;
  64. next;
  65. }
  66. my $sawGlobal = 0;
  67. my @globals;
  68. while (<NM>) {
  69. if (/^STDOUT:/) {
  70. my $line = $_;
  71. if ($line =~ /__GLOBAL__I(.+)$/) {
  72. $sawGlobal = 1;
  73. push(@globals, demangle($1));
  74. }
  75. } else {
  76. print STDERR if $_ ne "nm: no name list\n";
  77. }
  78. }
  79. close NM;
  80. if ($sawGlobal) {
  81. my $shortName = $file;
  82. $shortName =~ s/.*\///;
  83. # Special cases for files that have initializers in debug builds.
  84. if ($configuration eq "Debug" or $variant eq "debug" or $debugRoot) {
  85. if ($target eq "JavaScriptCore") {
  86. next if $shortName eq "AllInOneFile.o";
  87. next if $shortName eq "Opcode.o";
  88. next if $shortName eq "Structure.o";
  89. next if $shortName eq "nodes.o";
  90. }
  91. if ($target eq "WebCore") {
  92. next if $shortName eq "BidiRun.o";
  93. next if $shortName eq "CachedPage.o";
  94. next if $shortName eq "CachedResource.o";
  95. next if $shortName eq "FEGaussianBlur.o";
  96. next if $shortName eq "Frame.o";
  97. next if $shortName eq "JSCustomSQLTransactionCallback.o";
  98. next if $shortName eq "JSLazyEventListener.o";
  99. next if $shortName eq "Node.o";
  100. next if $shortName eq "Page.o";
  101. next if $shortName eq "Range.o";
  102. next if $shortName eq "RenderObject.o";
  103. next if $shortName eq "SVGElementInstance.o";
  104. next if $shortName eq "SubresourceLoader.o";
  105. next if $shortName eq "XMLHttpRequest.o";
  106. }
  107. if ($target eq "WebKit") {
  108. next if $shortName eq "HostedNetscapePluginStream.o";
  109. next if $shortName eq "NetscapePluginInstanceProxy.o";
  110. }
  111. if ($target eq "WebKit2") {
  112. next if $shortName eq "WebContext.o";
  113. next if $shortName eq "WebFrame.o";
  114. next if $shortName eq "WebPage.o";
  115. next if $shortName eq "WebPageProxy.o";
  116. }
  117. }
  118. print "ERROR: $shortName has one or more global initializers in it! ($file), near @globals\n";
  119. $sawError = 1;
  120. }
  121. }
  122. if ($sawError and !$coverageBuild) {
  123. unlink $executablePath;
  124. exit 1;
  125. }
  126. touch($buildTimestampPath);
  127. exit 0;
  128. sub touch($)
  129. {
  130. my ($path) = @_;
  131. open(TOUCH, ">", $path) or die "$!";
  132. close(TOUCH);
  133. }
  134. sub demangle($)
  135. {
  136. my ($symbol) = @_;
  137. if (!open FILT, "c++filt $symbol |") {
  138. print "ERROR: Could not open c++filt\n";
  139. return;
  140. }
  141. my $result = <FILT>;
  142. close FILT;
  143. chomp $result;
  144. return $result;
  145. }