Если вы запустили команду otool -L и получили ошибку «command not found», причина почти всегда одна: набор cctools либо не установлен, либо его утилиты не прописаны в переменной PATH. Этот пакет включает инструменты для просмотра, анализа и модификации объектных и исполняемых файлов формата Mach-O, которые используются в macOS и iOS, а также существуют в портированных версиях для Linux.
В этом материале разберём, что входит в состав cctools, как установить набор на разные системы и как применять основные утилиты на практике: от просмотра зависимостей библиотеки до исправления путей загрузки динамических библиотек.
Что такое cctools и что входит в набор
Cctools — это коллекция консольных утилит для работы с машинным кодом и объектными файлами. Изначально набор разрабатывался Apple как часть инструментария разработчика, а позже появились порты для Linux (например, cctools-port), которые часто используются при кросс-компиляции.
В состав типичной сборки входят следующие инструменты:
- 🔍 otool — просмотр содержимого объектных файлов: зависимостей, сегментов, секций, таблиц символов;
- 📦 lipo — создание и разборка «толстых» (universal) бинарников с кодом под несколько архитектур;
- 🔤 nm — вывод таблицы символов объектного файла или библиотеки;
- 🔧 install_name_tool — изменение путей к динамическим библиотекам внутри исполняемого файла;
- 📚 libtool, ranlib, ar — создание и индексация статических библиотек.
На macOS часть этих утилит поставляется вместе с Xcode Command Line Tools, и их поведение может отличаться от портированных версий. Перед тем как следовать чужой инструкции из интернета, сверьтесь со справкой конкретной утилиты на вашей системе через man otool или флаг --help.
Установка cctools на macOS и Linux
На macOS самый простой путь — установить инструменты командной строки Xcode. Для этого выполните в терминале:
xcode-select --install
После завершения установки утилиты otool, lipo и остальные станут доступны без дополнительной настройки. Проверить готовность можно командой which otool — она должна вывести путь к исполняемому файлу.
На Linux ситуация зависит от дистрибутива. В некоторых репозиториях пакет доступен под именем cctools, но его содержимое может отличаться: иногда под этим именем распространяется совершенно другой проект (Cooperative Computing Tools от университета Нотр-Дам), не имеющий отношения к утилитам Apple. Перед установкой проверьте описание пакета через менеджер пакетов вашей системы.
⚠️ Внимание: не путайте Apple cctools и Cooperative Computing Tools — это разные проекты с одинаковым названием. Если вам нужны утилиты для Mach-O, а установленный пакет содержит команды вроде
work_queue_worker, вы поставили не тот набор.
Анализ бинарных файлов с помощью otool
Утилита otool — основной инструмент для «заглянуть внутрь» исполняемого файла или библиотеки. Самый востребованный сценарий — посмотреть, от каких динамических библиотек зависит программа:
otool -L /путь/к/программе
В выводе вы увидите список путей к библиотекам, которые загрузчик попытается найти при запуске. Если программа не стартует с ошибкой о недоступной библиотеке, именно этот список подскажет, какой путь указан неверно или какого файла не хватает в системе.
Другие полезные режимы работы otool:
- 📄
otool -h— показать заголовок Mach-O: архитектуру, тип файла, флаги; - 🧩
otool -l— вывести все команды загрузки (load commands), включая сегменты и секции; - 🔡
otool -tV— дизассемблировать секцию кода (полезно при отладке и реверс-инжиниринге).
Набор доступных флагов может различаться между версиями otool на macOS и в портах, поэтому точный синтаксис уточняйте в man otool на вашей машине.
Работа с universal-бинарниками через lipo
Формат universal binary позволяет хранить в одном файле код для нескольких процессорных архитектур — например, x86_64 и arm64. Утилита lipo умеет такие файлы создавать, разбирать и проверять.
Чтобы узнать, под какие архитектуры собран бинарник, выполните:
lipo -info /путь/к/файлу
Если нужно извлечь только одну архитектуру (например, чтобы уменьшить размер файла или проанализировать её отдельно), используется режим -thin. А объединение двух одноархитектурных сборок в один universal-файл выполняется через -create с указанием выходного файла через -output. Точные имена архитектур, которые поддерживает ваша версия lipo, стоит уточнять в справке — набор поддерживаемых платформ меняется со временем.
Изменение путей библиотек: install_name_tool
Одна из самых частых практических задач — программа не запускается, потому что ищет динамическую библиотеку по пути, который существовал только на машине сборщика. Здесь помогает install_name_tool: она правит записи о путях прямо внутри Mach-O файла без пересборки.
Типовая команда замены пути выглядит так:
install_name_tool -change /старый/путь/libfoo.dylib /новый/путь/libfoo.dylib ./программа
Также утилита умеет менять собственный идентификатор библиотеки (-id) и добавлять пути поиска rpath (-add_rpath). Вместо абсолютных путей в macOS часто используют переменные @rpath, @executable_path и @loader_path — они делают бинарник переносимым.
⚠️ Внимание: на macOS модификация подписанного бинарного файла делает его цифровую подпись недействительной. После правки через install_name_tool программу может потребоваться подписать заново, иначе система откажется её запускать.
Что такое rpath и зачем он нужен
rpath (runpath search path) — это список каталогов, в которых загрузчик ищет динамические библиотеки, если в записи зависимости указана переменная @rpath. Добавив свой каталог через install_name_tool -add_rpath, вы позволяете программе находить библиотеки рядом с собой, а не по абсолютному пути.
Сравнение основных утилит набора
Чтобы быстрее ориентироваться, какая утилита нужна под конкретную задачу, сведём их назначение в таблицу:
| Утилита | Назначение | Типовая команда |
|---|---|---|
otool | Просмотр структуры и зависимостей Mach-O | otool -L файл |
lipo | Объединение и разделение архитектур | lipo -info файл |
nm | Вывод таблицы символов | nm файл |
install_name_tool | Правка путей динамических библиотек | install_name_tool -change ... |
strings | Извлечение текстовых строк из бинарника | strings файл |
Обратите внимание: nm и strings существуют и в GNU binutils, но версии из cctools ориентированы именно на формат Mach-O и корректнее работают с бинарниками Apple-платформ.
Типичные ошибки и их решение
При работе с cctools пользователи чаще всего сталкиваются с несколькими повторяющимися проблемами. Ниже — чек-лист первичной диагностики.
☑️ Диагностика проблем с cctools
Ошибка вида «is not an object file» означает, что вы скормили утилите файл неподходящего формата — например, ELF-бинарник Linux вместо Mach-O. Проверить тип файла можно командой file. Если утилита выдаёт «malformed object» или похожее сообщение, возможная причина — повреждённый или обрезанный файл, либо слишком старая версия cctools, не знающая новых команд загрузки.
⚠️ Внимание: не применяйте install_name_tool и lipo к системным бинарникам macOS. Изменение подписанных системных файлов может нарушить работу ОС, а защита целостности системы (SIP) всё равно заблокирует запись.
Часто задаваемые вопросы
Чем cctools отличается от GNU binutils?
Cctools ориентирован на формат Mach-O, используемый в macOS и iOS, тогда как GNU binutils работает прежде всего с ELF (Linux) и PE (Windows). Названия утилит часто совпадают (nm, ar, ranlib), но реализации и поддерживаемые форматы различаются.
Можно ли пользоваться cctools без установки Xcode?
Да. Полная среда Xcode не обязательна — достаточно пакета Command Line Tools, который ставится командой xcode-select --install. Он занимает заметно меньше места и содержит все рассмотренные утилиты.
Почему otool не находится после установки?
Возможные причины: утилиты установлены в каталог, не входящий в PATH, либо установка Command Line Tools завершилась с ошибкой. Проверьте вывод which otool и при необходимости повторите установку или добавьте нужный каталог в PATH в конфигурации вашей оболочки.
Можно ли с помощью lipo удалить ненужную архитектуру из приложения?
Технически да — режим -thin извлекает одну архитектуру в отдельный файл. Но для подписанных приложений macOS это нарушит подпись, а для программ из App Store модификация вообще не предусмотрена. Практический смысл такая операция имеет в основном для собственных сборок.
Подходят ли эти утилиты для анализа iOS-приложений?
Исполняемые файлы iOS — это тоже Mach-O, поэтому otool, nm и lipo с ними работают. Однако файлы из зашифрованных App Store-сборок сначала требуют снятия шифрования FairPlay, что выходит за рамки легитимного использования и возможностей самих утилит.