Skip to content

Commit 64c9586

Browse files
authored
Strip binary symbols command (#47)
1 parent d09485a commit 64c9586

File tree

3 files changed

+174
-0
lines changed

3 files changed

+174
-0
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
require 'dry/cli'
2+
require 'xcodeproj'
3+
4+
module EmergeCLI
5+
module Commands
6+
module Autofixes
7+
class StripBinarySymbols < EmergeCLI::Commands::GlobalOptions
8+
desc 'Strip binary symbols from the app'
9+
10+
option :path, type: :string, required: true, desc: 'Path to the xcarchive'
11+
12+
# Constants
13+
SCRIPT_NAME = 'EmergeTools Strip Binary Symbols'.freeze
14+
ENABLE_USER_SCRIPT_SANDBOXING = 'ENABLE_USER_SCRIPT_SANDBOXING'.freeze
15+
INPUT_FILE = '${DWARF_DSYM_FOLDER_PATH}/${EXECUTABLE_NAME}.app.dSYM/' \
16+
'Contents/Resources/DWARF/${EXECUTABLE_NAME}'.freeze
17+
SCRIPT_CONTENT = %{#!/bin/bash
18+
set -e
19+
20+
echo "Starting the symbol stripping process..."
21+
22+
if [ "Release" = "$\{CONFIGURATION\}" ]; then
23+
echo "Configuration is Release."
24+
25+
# Path to the app directory
26+
APP_DIR_PATH="$\{BUILT_PRODUCTS_DIR\}/$\{EXECUTABLE_FOLDER_PATH\}"
27+
echo "App directory path: $\{APP_DIR_PATH\}"
28+
29+
# Strip main binary
30+
echo "Stripping main binary: $\{APP_DIR_PATH\}/$\{EXECUTABLE_NAME\}"
31+
strip -rSTx "$\{APP_DIR_PATH\}/$\{EXECUTABLE_NAME\}"
32+
if [ $? -eq 0 ]; then
33+
echo "Successfully stripped main binary."
34+
else
35+
echo "Failed to strip main binary." >&2
36+
fi
37+
38+
# Path to the Frameworks directory
39+
APP_FRAMEWORKS_DIR="$\{APP_DIR_PATH\}/Frameworks"
40+
echo "Frameworks directory path: $\{APP_FRAMEWORKS_DIR\}"
41+
42+
# Strip symbols from frameworks, if Frameworks/ exists at all
43+
# ... as long as the framework is NOT signed by Apple
44+
if [ -d "$\{APP_FRAMEWORKS_DIR\}" ]; then
45+
echo "Frameworks directory exists. Proceeding to strip symbols from frameworks."
46+
find "$\{APP_FRAMEWORKS_DIR\}" -type f -perm +111 -maxdepth 2 -mindepth 2 -exec bash -c '
47+
codesign -v -R="anchor apple" "\{\}" &> /dev/null ||
48+
(
49+
echo "Stripping \{\}" &&
50+
if [ -w "\{\}" ]; then
51+
strip -rSTx "\{\}"
52+
if [ $? -eq 0 ]; then
53+
echo "Successfully stripped \{\}"
54+
else
55+
echo "Failed to strip \{\}" >&2
56+
fi
57+
else
58+
echo "Warning: No write permission for \{\}"
59+
fi
60+
)
61+
' \\;
62+
if [ $? -eq 0 ]; then
63+
echo "Successfully stripped symbols from frameworks."
64+
else
65+
echo "Failed to strip symbols from some frameworks." >&2
66+
fi
67+
else
68+
echo "Frameworks directory does not exist. Skipping framework stripping."
69+
fi
70+
else
71+
echo "Configuration is not Release. Skipping symbol stripping."
72+
fi
73+
74+
echo "Symbol stripping process completed."}.freeze
75+
76+
def call(**options)
77+
@options = options
78+
before(options)
79+
80+
raise 'Path must be an xcodeproj' unless @options[:path].end_with?('.xcodeproj')
81+
raise 'Path does not exist' unless File.exist?(@options[:path])
82+
83+
Sync do
84+
project = Xcodeproj::Project.open(@options[:path])
85+
86+
project.targets.each do |target|
87+
target.build_configurations.each do |config|
88+
enable_user_script_sandboxing(config)
89+
end
90+
91+
add_run_script(target)
92+
end
93+
94+
project.save
95+
end
96+
end
97+
98+
private
99+
100+
def enable_user_script_sandboxing(config)
101+
Logger.info "Enabling user script sandboxing for #{config.name}"
102+
config.build_settings[ENABLE_USER_SCRIPT_SANDBOXING] = 'NO'
103+
end
104+
105+
def add_run_script(target)
106+
phase = target.shell_script_build_phases.find { |item| item.name == SCRIPT_NAME }
107+
return unless phase.nil?
108+
Logger.info "Creating script '#{SCRIPT_NAME}'"
109+
phase = target.new_shell_script_build_phase(SCRIPT_NAME)
110+
phase.shell_script = SCRIPT_CONTENT
111+
phase.input_paths = [INPUT_FILE]
112+
end
113+
end
114+
end
115+
end
116+
end

lib/emerge_cli.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
require_relative 'commands/build_distribution/validate_app'
1919
require_relative 'commands/build_distribution/download_and_install'
2020
require_relative 'commands/autofixes/minify_strings'
21+
require_relative 'commands/autofixes/strip_binary_symbols'
2122
require_relative 'commands/autofixes/exported_symbols'
2223

2324
require_relative 'reaper/ast_parser'
@@ -73,6 +74,7 @@ module EmergeCLI
7374

7475
register 'autofix' do |prefix|
7576
prefix.register 'minify-strings', Commands::Autofixes::MinifyStrings
77+
prefix.register 'strip-binary-symbols', Commands::Autofixes::StripBinarySymbols
7678
prefix.register 'exported-symbols', Commands::Autofixes::ExportedSymbols
7779
end
7880
end
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
require 'test_helper'
2+
3+
module EmergeCLI
4+
module Commands
5+
module Autofixes
6+
class StripBinarySymbolsTest < Minitest::Test
7+
SCRIPT_NAME = 'EmergeTools Strip Binary Symbols'.freeze
8+
ENABLE_USER_SCRIPT_SANDBOXING = 'ENABLE_USER_SCRIPT_SANDBOXING'.freeze
9+
INPUT_FILE = '${DWARF_DSYM_FOLDER_PATH}/${EXECUTABLE_NAME}.app.dSYM/' \
10+
'Contents/Resources/DWARF/${EXECUTABLE_NAME}'.freeze
11+
12+
def setup
13+
@command = EmergeCLI::Commands::Autofixes::StripBinarySymbols.new
14+
15+
FileUtils.mkdir_p('tmp/test_autofix_strip_binary_symbols')
16+
FileUtils.cp_r('test/test_files/ExampleApp.xcodeproj',
17+
'tmp/test_autofix_strip_binary_symbols/ExampleApp.xcodeproj')
18+
end
19+
20+
def teardown
21+
FileUtils.rm_rf('tmp/test_autofix_strip_binary_symbols')
22+
end
23+
24+
def test_script_is_created
25+
options = {
26+
path: 'tmp/test_autofix_strip_binary_symbols/ExampleApp.xcodeproj'
27+
}
28+
29+
@command.call(**options)
30+
31+
project = Xcodeproj::Project.open('tmp/test_autofix_strip_binary_symbols/ExampleApp.xcodeproj')
32+
33+
phase = project.targets[0].shell_script_build_phases.find do |item|
34+
item.name == SCRIPT_NAME
35+
end
36+
assert_equal SCRIPT_NAME, phase.name
37+
assert_equal INPUT_FILE, phase.input_paths[0]
38+
end
39+
40+
def test_user_script_sandboxing_is_disabled
41+
options = {
42+
path: 'tmp/test_autofix_strip_binary_symbols/ExampleApp.xcodeproj'
43+
}
44+
45+
@command.call(**options)
46+
47+
project = Xcodeproj::Project.open('tmp/test_autofix_strip_binary_symbols/ExampleApp.xcodeproj')
48+
49+
project.targets[0].build_configurations.each do |config|
50+
assert_equal 'NO', config.build_settings[ENABLE_USER_SCRIPT_SANDBOXING]
51+
end
52+
end
53+
end
54+
end
55+
end
56+
end

0 commit comments

Comments
 (0)