Skip to content

Commit 3114e80

Browse files
dmaclachcopybara-github
authored andcommitted
Make -c opt dead strip code for Apple builds by default.
Previously `objc_enable_binary_stripping` and `-c opt` were required to both symbol strip and dead strip code. Symbol stripping and dead code stripping are very different things. Dead code stripping is the elimination of dead code and should be done in an optimized build. Unused code can be marked as "not dead" by using `exported symbols` in the Apple build rules. Symbol stripping is the removal of symbol tables from an executable. `objc_enable_binary_stripping` now only controls symbol stripping. Eventually I hope we deprecate `objc_enable_binary_stripping` and just use `strip=`. Closes #13489. PiperOrigin-RevId: 375023891
1 parent a7e0e29 commit 3114e80

File tree

5 files changed

+202
-13
lines changed

5 files changed

+202
-13
lines changed

src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -552,10 +552,11 @@ private FeatureConfiguration getFeatureConfiguration(
552552
.addAll(OBJC_ACTIONS)
553553
.add(CppRuleClasses.LANG_OBJC);
554554

555-
if (configuration.getFragment(ObjcConfiguration.class).shouldStripBinary()) {
555+
ObjcConfiguration objcConfiguration = configuration.getFragment(ObjcConfiguration.class);
556+
if (objcConfiguration.shouldDeadCodeStripBinary()) {
556557
activatedCrosstoolSelectables.add(DEAD_STRIP_FEATURE_NAME);
557558
}
558-
if (configuration.getFragment(ObjcConfiguration.class).generateLinkmap()) {
559+
if (objcConfiguration.generateLinkmap()) {
559560
activatedCrosstoolSelectables.add(GENERATE_LINKMAP_FEATURE_NAME);
560561
}
561562
// Add a feature identifying the Xcode version so CROSSTOOL authors can enable flags for
@@ -1148,9 +1149,9 @@ private StrippingType getStrippingType(ExtraLinkArgs extraLinkArgs) {
11481149
* <p>Dsym bundle is generated if {@link ObjcConfiguration#generateDsym()} is set.
11491150
*
11501151
* <p>When Bazel flags {@code --compilation_mode=opt} and {@code --objc_enable_binary_stripping}
1151-
* are specified, additional optimizations will be performed on the linked binary: all-symbol
1152-
* stripping (using {@code /usr/bin/strip}) and dead-code stripping (using linker flags: {@code
1153-
* -dead_strip}).
1152+
* are specified, symbol stripping (using {@code /usr/bin/strip}) occurs. When Bazel {@code
1153+
* --compilation_mode=opt} is specified dead-code stripping (using linker flags: {@code
1154+
* -dead_strip}) occurs.
11541155
*
11551156
* @param objcProvider common information about this rule's attributes and its dependencies
11561157
* @param ccLinkingContexts the linking contexts from this rule's dependencies

src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,8 @@ public class ObjcCommandLineOptions extends FragmentOptions {
145145
documentationCategory = OptionDocumentationCategory.OUTPUT_PARAMETERS,
146146
effectTags = {OptionEffectTag.ACTION_COMMAND_LINES},
147147
help =
148-
"Whether to perform symbol and dead-code strippings on linked binaries. Binary "
149-
+ "strippings will be performed if both this flag and --compilation_mode=opt are "
150-
+ "specified.")
148+
"Whether to perform symbol stripping on linked binaries. Stripping will be performed if"
149+
+ " both this flag and --compilation_mode=opt are specified.")
151150
public boolean enableBinaryStripping;
152151

153152
@Option(

src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,14 +188,23 @@ public ImmutableList<String> getCopts() {
188188
}
189189

190190
/**
191-
* Returns whether to perform symbol and dead-code strippings on linked binaries. The strippings
192-
* are performed iff --compilation_mode=opt and --objc_enable_binary_stripping are specified.
191+
* Returns whether to perform symbol stripping on linked binaries. The stripping is performed iff
192+
* --compilation_mode=opt and --objc_enable_binary_stripping are specified.
193193
*/
194194
@Override
195195
public boolean shouldStripBinary() {
196196
return this.enableBinaryStripping && getCompilationMode() == CompilationMode.OPT;
197197
}
198198

199+
/**
200+
* Returns whether to perform dead code elimination on linked binaries. The elimination is
201+
* performed iff --compilation_mode=opt.
202+
*/
203+
@Override
204+
public boolean shouldDeadCodeStripBinary() {
205+
return getCompilationMode() == CompilationMode.OPT;
206+
}
207+
199208
/**
200209
* Returns the flag-supplied certificate name to be used in signing or {@code null} if no such
201210
* certificate was specified.

src/main/java/com/google/devtools/build/lib/starlarkbuildapi/apple/ObjcConfigurationApi.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,15 @@ public interface ObjcConfigurationApi<ApplePlatformTypeApiT extends ApplePlatfor
106106
@StarlarkMethod(
107107
name = "should_strip_binary",
108108
structField = true,
109-
doc = "Returns whether to perform symbol and dead-code strippings on linked binaries.")
109+
doc = "Returns whether to perform symbol stripping on linked binaries.")
110110
boolean shouldStripBinary();
111111

112+
@StarlarkMethod(
113+
name = "should_dead_code_strip_binary",
114+
structField = true,
115+
doc = "Returns whether to perform dead code elimination on linked binaries.")
116+
boolean shouldDeadCodeStripBinary();
117+
112118
@StarlarkMethod(
113119
name = "signing_certificate_name",
114120
structField = true,

src/test/shell/bazel/apple/bazel_objc_test.sh

Lines changed: 176 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ EOF
118118
fail "Timestamp of contents of archive file should be zero"
119119
}
120120

121-
function test_strip_symbols() {
121+
# Verifies that unused code is dead stripped with `-c opt`.
122+
function test_symbols_dead_stripped_opt() {
122123
setup_objc_test_support
123124

124125
rm -rf ios
@@ -131,9 +132,94 @@ int addOne(int num);
131132
int addOne(int num) {
132133
return num + 1;
133134
}
134-
int main(int argc, char *argv[]) {
135+
int main(int argc, char *argv[]) {
136+
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
137+
int retVal = UIApplicationMain(argc, argv, nil, nil);
138+
[pool release];
139+
return retVal;
140+
}
141+
EOF
142+
143+
cat >ios/BUILD <<EOF
144+
apple_binary(name = 'app',
145+
deps = [':main'],
146+
platform_type = 'ios')
147+
objc_library(name = 'main',
148+
non_arc_srcs = ['main.m'])
149+
EOF
150+
151+
bazel build --verbose_failures \
152+
--apple_platform_type=ios \
153+
--ios_sdk_version=$IOS_SDK_VERSION \
154+
--compilation_mode=opt \
155+
//ios:app >$TEST_log 2>&1 || fail "should pass"
156+
ls bazel-out/apl-ios_x86_64-opt/bin/ios/app_lipobin \
157+
|| fail "should generate lipobin (stripped binary)"
158+
! nm bazel-out/apl-ios_x86_64-opt/bin/ios/app_lipobin | grep addOne \
159+
|| fail "should fail to find symbol addOne"
160+
}
161+
162+
# Verifies that unused code is *not* dead stripped with `-c dbg`.
163+
function test_symbols_not_dead_stripped_dbg() {
164+
setup_objc_test_support
165+
166+
rm -rf ios
167+
mkdir -p ios
168+
169+
cat >ios/main.m <<EOF
170+
#import <UIKit/UIKit.h>
171+
172+
/* function declaration */
173+
int addOne(int num);
174+
int addOne(int num) {
175+
return num + 1;
176+
}
177+
int main(int argc, char *argv[]) {
178+
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
179+
int retVal = UIApplicationMain(argc, argv, nil, nil);
180+
[pool release];
181+
return retVal;
182+
}
183+
EOF
184+
185+
cat >ios/BUILD <<EOF
186+
apple_binary(name = 'app',
187+
deps = [':main'],
188+
platform_type = 'ios')
189+
objc_library(name = 'main',
190+
non_arc_srcs = ['main.m'])
191+
EOF
192+
193+
bazel build --verbose_failures \
194+
--apple_platform_type=ios \
195+
--ios_sdk_version=$IOS_SDK_VERSION \
196+
--compilation_mode=dbg \
197+
//ios:app >$TEST_log 2>&1 || fail "should pass"
198+
ls bazel-out/apl-ios_x86_64-dbg/bin/ios/app_lipobin \
199+
|| fail "should generate lipobin"
200+
nm bazel-out/apl-ios_x86_64-dbg/bin/ios/app_lipobin | grep addOne \
201+
|| fail "should find symbol addOne"
202+
}
203+
204+
# Verifies that symbols are stripped with `objc_enable_binary_stripping` and `-c opt`.
205+
function test_symbols_stripped_opt_with_objc_enable_binary_stripping() {
206+
setup_objc_test_support
207+
208+
rm -rf ios
209+
mkdir -p ios
210+
211+
cat >ios/main.m <<EOF
212+
#import <UIKit/UIKit.h>
213+
214+
/* function declaration */
215+
int addOne(int num) __attribute__((noinline));
216+
int addOne(int num) {
217+
return num + 1;
218+
}
219+
int main(int argc, char *argv[]) {
135220
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
136221
int retVal = UIApplicationMain(argc, argv, nil, nil);
222+
NSLog(@"%d", addOne(2));
137223
[pool release];
138224
return retVal;
139225
}
@@ -159,6 +245,94 @@ EOF
159245
|| fail "should fail to find symbol addOne"
160246
}
161247

248+
# Verifies that symbols are not stripped with just `-c opt`.
249+
function test_symbols_not_stripped_opt() {
250+
setup_objc_test_support
251+
252+
rm -rf ios
253+
mkdir -p ios
254+
255+
cat >ios/main.m <<EOF
256+
#import <UIKit/UIKit.h>
257+
258+
/* function declaration */
259+
int addOne(int num) __attribute__((noinline));
260+
int addOne(int num) {
261+
return num + 1;
262+
}
263+
int main(int argc, char *argv[]) {
264+
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
265+
int retVal = UIApplicationMain(argc, argv, nil, nil);
266+
NSLog(@"%d", addOne(2));
267+
[pool release];
268+
return retVal;
269+
}
270+
EOF
271+
272+
cat >ios/BUILD <<EOF
273+
apple_binary(name = 'app',
274+
deps = [':main'],
275+
platform_type = 'ios')
276+
objc_library(name = 'main',
277+
non_arc_srcs = ['main.m'])
278+
EOF
279+
280+
bazel build --verbose_failures \
281+
--apple_platform_type=ios \
282+
--ios_sdk_version=$IOS_SDK_VERSION \
283+
--compilation_mode=opt \
284+
//ios:app >$TEST_log 2>&1 || fail "should pass"
285+
ls bazel-out/apl-ios_x86_64-opt/bin/ios/app_lipobin \
286+
|| fail "should generate lipobin (stripped binary)"
287+
nm bazel-out/apl-ios_x86_64-opt/bin/ios/app_lipobin | grep addOne \
288+
|| fail "should fail to find symbol addOne"
289+
}
290+
291+
292+
# Verifies that symbols are not stripped with `objc_enable_binary_stripping` and `-c dbg`.
293+
function test_symbols_not_stripped_dbg() {
294+
setup_objc_test_support
295+
296+
rm -rf ios
297+
mkdir -p ios
298+
299+
cat >ios/main.m <<EOF
300+
#import <UIKit/UIKit.h>
301+
302+
/* function declaration */
303+
int addOne(int num) __attribute__((noinline));
304+
int addOne(int num) {
305+
return num + 1;
306+
}
307+
int main(int argc, char *argv[]) {
308+
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
309+
int retVal = UIApplicationMain(argc, argv, nil, nil);
310+
NSLog(@"%d", addOne(2));
311+
[pool release];
312+
return retVal;
313+
}
314+
EOF
315+
316+
cat >ios/BUILD <<EOF
317+
apple_binary(name = 'app',
318+
deps = [':main'],
319+
platform_type = 'ios')
320+
objc_library(name = 'main',
321+
non_arc_srcs = ['main.m'])
322+
EOF
323+
324+
bazel build --verbose_failures \
325+
--apple_platform_type=ios \
326+
--ios_sdk_version=$IOS_SDK_VERSION \
327+
--objc_enable_binary_stripping=true \
328+
--compilation_mode=dbg \
329+
//ios:app >$TEST_log 2>&1 || fail "should pass"
330+
ls bazel-out/apl-ios_x86_64-dbg/bin/ios/app_lipobin \
331+
|| fail "should generate lipobin"
332+
nm bazel-out/apl-ios_x86_64-dbg/bin/ios/app_lipobin | grep addOne \
333+
|| fail "should find symbol addOne"
334+
}
335+
162336
function test_cc_test_depending_on_objc() {
163337
setup_objc_test_support
164338

0 commit comments

Comments
 (0)