Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions lib/commands/autofixes/strip_binary_symbols.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
require 'dry/cli'
require 'xcodeproj'

module EmergeCLI
module Commands
module Autofixes
class StripBinarySymbols < EmergeCLI::Commands::GlobalOptions
desc 'Strip binary symbols from the app'

option :path, type: :string, required: true, desc: 'Path to the xcarchive'

# Constants
SCRIPT_NAME = 'EmergeTools Strip Binary Symbols'.freeze
ENABLE_USER_SCRIPT_SANDBOXING = 'ENABLE_USER_SCRIPT_SANDBOXING'.freeze
INPUT_FILE = '${DWARF_DSYM_FOLDER_PATH}/${EXECUTABLE_NAME}.app.dSYM/' \
'Contents/Resources/DWARF/${EXECUTABLE_NAME}'.freeze
SCRIPT_CONTENT = %{#!/bin/bash
set -e

echo "Starting the symbol stripping process..."

if [ "Release" = "$\{CONFIGURATION\}" ]; then
echo "Configuration is Release."

# Path to the app directory
APP_DIR_PATH="$\{BUILT_PRODUCTS_DIR\}/$\{EXECUTABLE_FOLDER_PATH\}"
echo "App directory path: $\{APP_DIR_PATH\}"

# Strip main binary
echo "Stripping main binary: $\{APP_DIR_PATH\}/$\{EXECUTABLE_NAME\}"
strip -rSTx "$\{APP_DIR_PATH\}/$\{EXECUTABLE_NAME\}"
if [ $? -eq 0 ]; then
echo "Successfully stripped main binary."
else
echo "Failed to strip main binary." >&2
fi

# Path to the Frameworks directory
APP_FRAMEWORKS_DIR="$\{APP_DIR_PATH\}/Frameworks"
echo "Frameworks directory path: $\{APP_FRAMEWORKS_DIR\}"

# Strip symbols from frameworks, if Frameworks/ exists at all
# ... as long as the framework is NOT signed by Apple
if [ -d "$\{APP_FRAMEWORKS_DIR\}" ]; then
echo "Frameworks directory exists. Proceeding to strip symbols from frameworks."
find "$\{APP_FRAMEWORKS_DIR\}" -type f -perm +111 -maxdepth 2 -mindepth 2 -exec bash -c '
codesign -v -R="anchor apple" "\{\}" &> /dev/null ||
(
echo "Stripping \{\}" &&
if [ -w "\{\}" ]; then
strip -rSTx "\{\}"
if [ $? -eq 0 ]; then
echo "Successfully stripped \{\}"
else
echo "Failed to strip \{\}" >&2
fi
else
echo "Warning: No write permission for \{\}"
fi
)
' \\;
if [ $? -eq 0 ]; then
echo "Successfully stripped symbols from frameworks."
else
echo "Failed to strip symbols from some frameworks." >&2
fi
else
echo "Frameworks directory does not exist. Skipping framework stripping."
fi
else
echo "Configuration is not Release. Skipping symbol stripping."
fi

echo "Symbol stripping process completed."}.freeze

def call(**options)
@options = options
before(options)

raise 'Path must be an xcodeproj' unless @options[:path].end_with?('.xcodeproj')
raise 'Path does not exist' unless File.exist?(@options[:path])

Sync do
project = Xcodeproj::Project.open(@options[:path])

project.targets.each do |target|
target.build_configurations.each do |config|
enable_user_script_sandboxing(config)
end

add_run_script(target)
end

project.save
end
end

private

def enable_user_script_sandboxing(config)
Logger.info "Enabling user script sandboxing for #{config.name}"
config.build_settings[ENABLE_USER_SCRIPT_SANDBOXING] = 'NO'
end

def add_run_script(target)
phase = target.shell_script_build_phases.find { |item| item.name == SCRIPT_NAME }
return unless phase.nil?
Logger.info "Creating script '#{SCRIPT_NAME}'"
phase = target.new_shell_script_build_phase(SCRIPT_NAME)
phase.shell_script = SCRIPT_CONTENT
phase.input_paths = [INPUT_FILE]
end
end
end
end
end
2 changes: 2 additions & 0 deletions lib/emerge_cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
require_relative 'commands/build_distribution/validate_app'
require_relative 'commands/build_distribution/download_and_install'
require_relative 'commands/autofixes/minify_strings'
require_relative 'commands/autofixes/strip_binary_symbols'

require_relative 'reaper/ast_parser'
require_relative 'reaper/code_deleter'
Expand Down Expand Up @@ -72,6 +73,7 @@ module EmergeCLI

register 'autofix' do |prefix|
prefix.register 'minify-strings', Commands::Autofixes::MinifyStrings
prefix.register 'strip-binary-symbols', Commands::Autofixes::StripBinarySymbols
end
end

Expand Down
56 changes: 56 additions & 0 deletions test/commands/autofixes/strip_binary_symbols_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
require 'test_helper'

module EmergeCLI
module Commands
module Autofixes
class StripBinarySymbolsTest < Minitest::Test
SCRIPT_NAME = 'EmergeTools Strip Binary Symbols'.freeze
ENABLE_USER_SCRIPT_SANDBOXING = 'ENABLE_USER_SCRIPT_SANDBOXING'.freeze
INPUT_FILE = '${DWARF_DSYM_FOLDER_PATH}/${EXECUTABLE_NAME}.app.dSYM/' \
'Contents/Resources/DWARF/${EXECUTABLE_NAME}'.freeze

def setup
@command = EmergeCLI::Commands::Autofixes::StripBinarySymbols.new

FileUtils.mkdir_p('tmp/test_autofix_strip_binary_symbols')
FileUtils.cp_r('test/test_files/ExampleApp.xcodeproj',
'tmp/test_autofix_strip_binary_symbols/ExampleApp.xcodeproj')
end

def teardown
FileUtils.rm_rf('tmp/test_autofix_strip_binary_symbols')
end

def test_script_is_created
options = {
path: 'tmp/test_autofix_strip_binary_symbols/ExampleApp.xcodeproj'
}

@command.call(**options)

project = Xcodeproj::Project.open('tmp/test_autofix_strip_binary_symbols/ExampleApp.xcodeproj')

phase = project.targets[0].shell_script_build_phases.find do |item|
item.name == SCRIPT_NAME
end
assert_equal SCRIPT_NAME, phase.name
assert_equal INPUT_FILE, phase.input_paths[0]
end

def test_user_script_sandboxing_is_disabled
options = {
path: 'tmp/test_autofix_strip_binary_symbols/ExampleApp.xcodeproj'
}

@command.call(**options)

project = Xcodeproj::Project.open('tmp/test_autofix_strip_binary_symbols/ExampleApp.xcodeproj')

project.targets[0].build_configurations.each do |config|
assert_equal 'NO', config.build_settings[ENABLE_USER_SCRIPT_SANDBOXING]
end
end
end
end
end
end
Loading