Коротко — CMake сам по себе ничего «магически» не сжимает/увеличивает, но при генерации сборки он может поменять/добавить флаги компоновщика/компилятора, тип конфигурации или архитектуры, добавить rpath/символы/метки и т. п. Это и даёт разницу в размере. Ниже — список наиболее распространённых причин и конкретные способы быстро найти, в чём именно дело, и как привести размер CMake‑билда к вашему ручному билду.
Что проверить в первую очередь
- Сравните реальные команды компиляции/линковки.
- Включите экспорт команд: в CMakeLists.txt или при вызове cmake добавьте -DCMAKE_EXPORT_COMPILE_COMMANDS=ON и/или соберите с VERBOSE: cmake --build build -- VERBOSE=1 (или ninja -v). Сравните с теми командами, что использовали в build.sh.
- Проверьте режим сборки (Debug/Release).
- По умолчанию CMake может не ставить CMAKE_BUILD_TYPE=Release, и тогда не будет оптимизаций/стріпа. Запускайте cmake с -DCMAKE_BUILD_TYPE=Release или указывайте конфиг при сборке (для multi‑config генераторов).
- Проверьте, не собирается ли универсальный (fat) бинарник для нескольких архитектур.
- file libname.dylib или lipo -info libname.dylib покажут archs. Если там arm64 + x86_64 — размер заметно больше.
- Проверка отладочных символов / DWARF:
- dwarfdump lib.dylib или nm / otool. Также попробуйте strip (strip -x lib.dylib) и посмотрите, сколько уменьшится размер. Если после strip оба бинаря совпадают, причина — символы/дебаг.
- Проверка сегментов LC_RPATH / другие секции:
- otool -l lib.dylib | sed -n '1,200p' — ищите LC_RPATH и прочие заметные сегменты, которые добавляет CMake (MACOSX_RPATH).
- Проверьте число экспортируемых символов (nm -gU lib.dylib). CMake может при линковке экспортировать больше символов, если не указали скрытую видимость (-fvisibility=hidden).
Типичные причины и как их исправить
1) CMAKE_BUILD_TYPE не = Release → включите оптимизацию и выключите дебаг:
- cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
- или явно задать флаги: -DCMAKE_CXX_FLAGS_RELEASE="-O3 -DNDEBUG -g0" и/или CMAKE_SHARED_LINKER_FLAGS_RELEASE="-Wl,-S"
2) Debug symbols / dSYM: CMake может не стріпать автоматически. Используйте strip (strip -x), или добавьте опцию компоновщику (-Wl,-S) или настройте CMAKE_<LANG>_FLAGS_RELEASE.
3) Универсальный билд (несколько архитектур): задайте CMAKE_OSX_ARCHITECTURES=arm64 если нужна только arm64:
- cmake -S . -B build -DCMAKE_OSX_ARCHITECTURES=arm64
4) LC_RPATH / install_name / дополнительные сегменты: CMake часто добавляет rpath. Сравните otool -l, при необходимости отключите MACOSX_RPATH или настройте install_name:
- set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE) и явно задавайте rpath/инсталль нейм.
5) Экспорт символов и видимость: для минимизации используйте -fvisibility=hidden и экспортируйте только нужные символы через экспортный файл (version script) или __attribute__((visibility("default"))).
6) Различия в компиляторе/драйвере: проверьте, что clang++ одинаковый (which clang++, clang++ --version) и что CMake не использует другой компилятор. CMakeCache.txt содержит путь к выбранному компилятору.
7) Различия флагов линковщика: CMake может добавлять дополнительные -Wl опции. Посмотрите реальные link строки (VERBOSE) и сравните.
Полезные команды для диагностики
- Посмотреть команды: cmake --build build -- VERBOSE=1 или ninja -v
- Архитектуры: file lib.dylib ; lipo -info lib.dylib
- Сегменты: otool -l lib.dylib
- Экспорт/символы: nm -gU lib.dylib
- Debug info: dwarfdump lib.dylib
- Сравнение до/после strip: cp lib.dylib lib.orig; strip -x lib.dylib; ls -lh lib.orig lib.dylib
Если хотите — пришлите:
- вывод cmake команды компоновки (VERBOSE link line),
- вывод file/lipo и otool -l,
- размер до/после strip.
Я помогу точно указать, какие флаги убрать/добавить, чтобы получить тот же вес, что и при ручной сборке.