Удаление `CMakeCache.txt` приводит к тому, что`OPTIONAL` цели установки больше не создаются
Я вижу странную проблему со сборкой, которую может быть довольно сложно воспроизвести. Я использую CMake с Ninja для создания проекта C++, который использует Qt 5.5. Я думаю, что единственной важной частью этой смеси является сам CMake, но Qt определенно добавляет некоторые морщины в систему сборки, так что это также является возможным виновником.
Вот цепочка событий, которые привели к моей проблеме:
- Я добавил объявление виртуального метода в базовый класс, но забыл сделать его чисто виртуальным (
=0
). Я реализовал метод в производных классах, но получилundefined reference to vtable
ошибка связи из-за отсутствия реализации базового класса.- Один из производных классов также наследует от
QObject
и поэтому подлежитautomoc
, Я не верю, что это связано с проблемой сборки.
- Один из производных классов также наследует от
- В какой-то момент, когда я пытался выяснить, почему я получаю ошибку ссылки, я удалил свой
CMakeCache.txt
файл.- Я также удалил весь родительский каталог из каталога сборки, содержащего рассматриваемые виртуальные и производные классы. Я не уверен, является ли это частью проблемы или нет.
- Я понял, что должен сделать метод базового класса чисто виртуальным, и успешно завершил сборку.
- ПРОБЛЕМА:
ninja install
больше не устанавливает ни одну из моих двоичных целей (все из которых объявленыOPTIONAL
разрешить частичную сборку / установку проекта для быстрой итерации), даже после повторного запускаCMake
несколько раз.
Я повторно удалил CMakeCache.txt
и перезапустил CMake и ninja
, но я не смог переустановить цели, пока полностью не удалил каталог сборки.
Один из моих коллег также столкнулся с этой проблемой, хотя я не знаю как (возможно, он удалил или иным образом испортил его CMakeCache.txt
файл, но он на самом деле не помнит, что он делал непосредственно до того, как увидел проблему).
РЕДАКТИРОВАТЬ: у меня снова возникает эта проблема, и кажется, что когда я ставлю цели неOPTIONAL
CMake ожидает найти их в различных подкаталогах CMakeFiles
каталоги (в дереве build-artifacts), называемые CMakeRelink.dir
, Этот каталог, очевидно, никогда не существует. Даже настройка CMAKE_SKIP_INSTALL_ALL_DEPENDENCY
в false
и повторный запуск CMake, кажется, не решает проблему, которая не имеет смысла для меня.
РЕДАКТИРОВАТЬ 2: Я думаю, что это та же ошибка, и есть несколько обходных путей: https://cmake.org/Bug/view.php?id=13934
1 ответ
Похоже, это связано с ошибкой в том, как CMake обрабатывает свою пост-обработку для двоичных файлов. По умолчанию install
Команды удаляют встроенные пути к библиотекам из двоичных файлов перед их установкой. Для двоичных файлов ELF в CMake есть какой-то встроенный инструмент для удаления пути, который фактически читает файл ELF и создает новый файл без встроенного пути; для файла не-ELF используется другая схема. Примечательно, что CMake использует разные файлы для разархивированных двоичных файлов в зависимости от того, какая схема будет использоваться для их удаления. Я понятия не имею, почему это так, но это основная причина ошибки сборки.
Без CMakeCache.txt
Похоже, что CMake "забывает", какая схема использовалась (или должна использоваться) для удаления файлов. Таким образом, он ищет несвязанные двоичные файлы в неправильном каталоге артефактов.
Это известная (хотя и не совсем понятная) ошибка CMake; самый простой обходной путь - явно указать (когда это уместно), что целевые двоичные файлы имеют формат ELF, установив CMAKE_EXECUTABLE_FORMAT
переменная.