Найти размер, внесенный каждой внешней библиотекой в ​​iOS

Я пытаюсь уменьшить размер бинарных файлов в магазине, и у нас есть много внешних библиотек, которые могли бы внести вклад в размер финальной ipa. Есть ли способ узнать, сколько каждой внешней статической библиотеки занимает в конечном двоичном файле (кроме как удалить каждый из них?)?

Ответы

Ответ 1

Вся эта информация содержится в карте ссылок, если у вас есть терпение для просеивания через нее (для крупных приложений она может быть довольно большой). На карте ссылок есть список всех библиотек, их объектных файлов и всех символов, которые были упакованы в ваше приложение, все в тексте, удобном для чтения. Обычно проекты не настроены для их генерации по умолчанию, поэтому вам придется быстро сменить файл проекта.

Изнутри Xcode:

  • В разделе "Настройки сборки" для вашей цели найдите "карту"
  • В приведенных ниже результатах в разделе "Связывание" установите "Write Link Map File" в "Yes"
  • Обязательно обратите внимание на полный путь и имя файла, перечисленные в разделе "Путь к файлу карты ссылок"

В следующий раз, когда вы создадите приложение, вы получите карту ссылок, сбрасываемую на этот путь к файлу. Обратите внимание, что путь относится к местоположению вашего приложения в папке DerivedData (обычно ~/Library/Developer/Xcode/DerivedData/<your-app-name>-<random-string-of-letters-and-numbers>/Build/Intermediates/..., но YMMV). Поскольку это просто текстовый файл, вы можете прочитать его с помощью любого текстового редактора.

Содержимое карты ссылок разделено на 3 раздела, из которых 2 будет иметь отношение к тому, что вы ищете:

  • Объектные файлы: этот раздел содержит список всех объектных файлов, включенных в ваше окончательное приложение, включая ваш собственный код и код любых сторонних библиотек, которые вы включили. Важно отметить, что каждый объектный файл также содержит библиотеку, в которой он появился;
  • Разделы: этот раздел, не относящийся к вашему вопросу, содержит список сегментов процессора и их разделов;
  • Символы: этот раздел содержит необработанные данные, которые вас интересуют: список всех символов/методов с их абсолютным местоположением (т.е. адрес на карте памяти процессора), размер и, самое главное, ссылку на их содержащий объектный модуль (в столбце "Файл" ).

Из этих необработанных данных у вас есть все необходимое для расчета необходимого размера. Из № 1 вы видите, что для каждой библиотеки существует N возможных составных объектных модулей; из # 2 вы видите, что для каждого объектного модуля есть М возможных символов, каждый из которых занимает размер S. Для любой данной библиотеки ваш грубый порядок размера будет чем-то вроде O (N * M * S). Это только для того, чтобы дать вам представление о компонентах, которые вошли бы в ваши фактические вычисления, это не какая-то полезная формула. Для выполнения самого расчета, мне жаль говорить, что я не знаю каких-либо существующих инструментов, которые сделают необходимую обработку для вас, но учитывая, что карта ссылок - это всего лишь текстовый файл, с малой магией script и изобретательность вы можете построить script для тяжелого подъема.

Например, у меня есть небольшой примерный проект, который ссылается на следующую библиотеку: https://github.com/ColinEberhardt/LinqToObjectiveC (сам образец проекта - из хорошего учебника по ReactiveCocoa, здесь: http://www.raywenderlich.com/62699/reactivecocoa-tutorial-pt1), и я хочу знать, сколько места он занимает. Я создал карту ссылок, TwitterInstant-LinkMap-normal-x86_64.txt(она запускается в симуляторе). Чтобы найти все объектные модули, включенные библиотекой, я делаю следующее:

$ grep -i "libLinqToObjectiveC.a" TwitterInstant-LinkMap-normal-x86_64.txt

который дает мне это:

[  8] /Users/Smyrl/Library/Developer/Xcode/DerivedData/TwitterInstant-ecppmzhbawtxkwctokwryodvgkur/Build/Products/Debug-iphonesimulator/libLinqToObjectiveC.a(LinqToObjectiveC-dummy.o)
[  9] /Users/Smyrl/Library/Developer/Xcode/DerivedData/TwitterInstant-ecppmzhbawtxkwctokwryodvgkur/Build/Products/Debug-iphonesimulator/libLinqToObjectiveC.a(NSArray+LinqExtensions.o)
[ 10] /Users/Smyrl/Library/Developer/Xcode/DerivedData/TwitterInstant-ecppmzhbawtxkwctokwryodvgkur/Build/Products/Debug-iphonesimulator/libLinqToObjectiveC.a(NSDictionary+LinqExtensions.o)

Первый столбец содержит перекрестные ссылки на таблицу символов, в которой я нуждаюсь, поэтому я могу найти их:

$ cat TwitterInstant-LinkMap-normal-x86_64.txt | grep -e "\[  8\]"

который дает мне:

0x100087161 0x0000001B  [  8] literal string: PodsDummy_LinqToObjectiveC
0x1000920B8 0x00000008  [  8] anon
0x100093658 0x00000048  [  8] l_OBJC_METACLASS_RO_$_PodsDummy_LinqToObjectiveC
0x1000936A0 0x00000048  [  8] l_OBJC_CLASS_RO_$_PodsDummy_LinqToObjectiveC
0x10009F0A8 0x00000028  [  8] _OBJC_METACLASS_$_PodsDummy_LinqToObjectiveC
0x10009F0D0 0x00000028  [  8] _OBJC_CLASS_$_PodsDummy_LinqToObjectiveC

Второй столбец содержит размер рассматриваемого символа (в шестнадцатеричном виде), поэтому, если я их добавлю, я получаю 0x103 или 259 байтов.

Даже лучше, я могу немного взломать поток, чтобы уничтожить его до основных элементов и сделать дополнение для меня:

$ cat TwitterInstant-LinkMap-normal-x86_64.txt | grep -e "\[  8\]" | grep -e "0x" | awk '{print $2}' | xargs printf "%d\n" | paste -sd+ - | bc

который дает мне число прямо вверх:

259

Выполняя то же самое для "\[ 9\]" (13016 bytes) и "\[ 10\]" (5503 байта) и добавляя их к предыдущим 259 байтам, дает мне 18778 байт.

Вы, безусловно, можете улучшить хакерство потока, которое я сделал здесь, чтобы сделать его немного более надежным (в этой реализации вы должны убедиться, что вы правильно указали количество пробелов и скопировали скобки), но вы на наименьшая идея.

Ответ 2

Сделайте файл .ipa вашего приложения и сохраните его в своей системе.

Затем откройте терминал и выполните следующую команду:

unzip -lv/path/to/your/app.ipa

Он вернет таблицу данных о вашем .ipa файле. Столбец размера имеет сжатый размер каждого файла в вашем .ipa файле.

Ответ 3

создайте приложение в xcode.

затем используйте finder для изучения содержимого, это должно дать вам достаточно информации о том, что включено.

Ответ 4

Я думаю, что вы сможете извлечь нужную информацию из этого:

символы -w -noSources YourFileHere

Ссылка: https://devforums.apple.com/message/926442#926442

IIRC, он не даст вам четкой сводной информации о каждом lib, но вы должны обнаружить, что функции из каждой библиотеки должны быть сгруппированы вместе, поэтому с небольшими усилиями вы можете рассчитать приблизительный вклад от каждого lib

Ответ 5

Также убедитесь, что в настройках сборки вы устанавливаете "Генерировать символы отладки" в "НЕТ". Это может уменьшить размер вашей статической библиотеки примерно на 30%.

Если это часть вашей озабоченности, статическая библиотека - это только соответствующие файлы .o, заархивированные вместе, а также некоторые бухгалтерские операции. Таким образом, статическая библиотека размером 1,7 МБ, даже если код внутри нее - всего 1,7 Мбайт, обычно не добавляет к вашему продукту 1,7 МБ. Будут применяться обычные правила удаления дескриптора кода.

Кроме того, вы можете уменьшить встроенный размер вашего кода. Следующий, вероятно, не полный список.

В настройках вашей целевой сборки найдите "Уровень оптимизации". Переключив его на "Самый быстрый, самый маленький-O", вы разрешите компилятору пожертвовать некоторой скоростью для размера.

Убедитесь, что вы создаете для большого пальца, более компактный ARM-код. Предполагая, что вы используете LLVM, это означает, что вы не имеете -mno-thumb в любом месте своих настроек проекта.

Также рассмотрим, какие архитектуры вы хотите построить. Apple не позволяет отправлять приложения, поддерживающие как ARMv6, так и экран iPhone 5, и полностью отказались от поддержки ARMv6 от последнего Xcode. Так что, вероятно, нет смысла включать в этот момент.

Ответ 6

Существует очень простое приложение под названием OmniDiskSweeper, в основном для поиска тяжелых файлов на вашем жестком диске, но просто перейдите к своей сборке и проверьте файлы внутри. Но я не думаю, что библиотеки являются ответственными, могут быть и большие изображения. Я всегда использую инструмент ImageOptim https://imageoptim.com/, чтобы сжать все изображения в моих проектах, это так полезно, когда изображения сжимаются до 99% такое же качество. Чтобы использовать инструмент, просто загрузите и установите его и введите его с вашего терминала (в папке проекта):

open -a ImageOptim .