Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Side by Side Diff: build/mac/make_ib_classes.py

Issue 28289: Link applications with -Wl,-ObjC to keep Objective-C implementations availabl... (Closed) Base URL: svn://chrome-svn.corp.google.com/chrome/trunk/src/
Patch Set: Created 11 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « build/common.gypi ('k') | chrome/chrome.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/python
2
3 # Copyright (c) 2009 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 # Usage: make_ib_classes.py output.mm input.xib [...]
8 #
9 # Generates an Objective-C++ file at output.mm referencing each class described
10 # in input.xib.
11 #
12 # This script is useful when building an application containing .nib or .xib
13 # files that reference Objective-C classes that may not be referenced by other
14 # code in the application. The intended use case is when the .nib and .xib
15 # files refer to classes that are built into a static library that gets linked
16 # into the main executable. If nothing in the main executable references those
17 # classes, the linker will not include them in its output (without -all_load or
18 # -ObjC). Using this script, references to such classes are created, such that
Mark Mentovai 2009/02/28 00:50:12 See?
19 # if output.mm is compiled into the application itself, it will provide the
20 # class references and cause the linker to bring the required code into the
21 # executable.
22 #
23 # If your application is structured in the above way, and you're plagued with
24 # messages like:
25 # app[12345:101] Unknown class `MyApp' in nib file, using `NSObject' instead.
26 # then this script may be right for you.
27
28
29 import errno
30 import os
31 import os.path
32 import re
33 import subprocess
34 import sys
35
36
37 # Patterns used by ListIBClasses
38
39 # A pattern that matches the line preceding a class name.
40 _class_re = re.compile('<key>class</key>$')
41
42 # A pattern that matches the line with a class name; match group 1 should be
43 # the class name.
44 _class_name_re = re.compile('<string>(.*)</string>$')
45
46 # A pattern that matches class names to exclude from the output. This includes
47 # various Cocoa classes.
48 _forbidden_class_re = re.compile('^(NS|IB|FirstResponder$|WebView$)')
49
50 def ListIBClasses(ib_path, class_names=None):
51 """Returns a list of class names referenced by ib_path.
52
53 ib_path is a path to an Interface Builder document. It may be a .nib or a
54 .xib.
55
56 This function calls "ibtool --classes" to get the list of class names.
57 ibtool's output is in XML plist format. Rather than doing proper structured
58 plist scanning, this function relies on the fact that plists are serialized
59 to XML in a consistent way, and simply takes the string value names of any
60 dictionary key named "class" as class names.
61
62 class_names may be specified as an existing list to use. This is helpful
63 when this function will be called several times for multiple nib/xib files.
64 """
65 if class_names == None:
66 class_names = []
67
68 # When running within an Xcode build, use the tools from that Xcode
69 # installation.
70 developer_tools_dir = os.getenv('DEVELOPER_BIN_DIR', '/usr/bin')
71 ibtool_path = os.path.join(developer_tools_dir, 'ibtool')
72 ibtool_command = [ibtool_path, '--classes', ib_path]
73
74 ibtool = subprocess.Popen(ibtool_command, stdout=subprocess.PIPE)
75
76 ibtool_output = ibtool.communicate()[0]
77
78 ibtool_rv = ibtool.returncode
79 assert ibtool_rv == 0
80
81 # Loop through the output, looking for "class" keys. The string value on
82 # any line following a "class" key is taken as a class name.
83 is_class_name = False
84 for line in ibtool_output.splitlines():
85 if is_class_name:
86 class_name = _class_name_re.search(line).group(1)
87 is_class_name = False
88 if not class_name in class_names and \
89 not _forbidden_class_re.search(class_name):
90 class_names.append(class_name)
91 elif _class_re.search(line):
92 is_class_name = True
93
94 return class_names
95
96
97 def main(args):
98 assert len(args) > 2
99 (script_path, output_path) = args[0:2]
100 assert output_path.endswith('.mm')
101 input_paths = args[2:]
102
103 try:
104 os.unlink(output_path)
105 except OSError, e:
106 if e.errno != errno.ENOENT:
107 raise
108
109 class_names = []
110
111 # Get the class names for all desired files.
112 for input_path in input_paths:
113 ListIBClasses(input_path, class_names)
114
115 class_names.sort()
116
117 # Write the requested output file. Each class is referenced simply by
118 # calling its +class function. In order to do this, each class needs a
119 # bogus @interface to tell the compiler that it's an NSObject subclass.
120 # #import NSObject.h to get the definition of NSObject without bringing in
121 # other headers that might provide real declarations.
122
123 output_file = open(output_path, 'w')
124 print >>output_file, \
125 """// This file was generated by %s. Do not edit.
126
127 #import <Foundation/NSObject.h>
128 """ % os.path.basename(script_path)
129
130 for class_name in class_names:
131 print >>output_file, '@interface %s : NSObject\n@end' % class_name
132
133 print >>output_file, '\nnamespace {\n\nvoid IBClasses() {'
134
135 for class_name in class_names:
136 print >>output_file, ' [%s class];' % class_name
137
138 print >>output_file, '}\n\n} // namespace'
139
140 output_file.close()
141
142 return 0
143
144
145 if __name__ == '__main__':
146 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « build/common.gypi ('k') | chrome/chrome.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698