Лучшие практики с CMake, `CMAKE_CXX_STANDARD` и кешем? - PullRequest
0 голосов
/ 20 июня 2020

Я работаю над большой библиотекой C ++ с таргетингом CMake GNU make и встраиванием в каталог _build/. На верхнем уровне CMakeLists.txt используется list(APPEND as_subproject ...) для добавления ряда сторонних проектов. Простой Makefile на верхнем уровне делает запуск сборки проще и согласованнее. Makefile имеет две цели:

  • make clean: запускает make -C _build clean, а затем удаляет каталог _build
  • make all: удаляет _build/CMakeCache.txt, запускает CMake для создания файлов Makefile в каталоге _build, а затем запускает make -C _build all, чтобы выполнить фактическую сборку.

Это работало довольно хорошо, пока обновление одного из сторонних проектов не добавило следующая строка в их CMakeLists.txt:

set(CMAKE_CXX_STANDARD 11 CACHE STRING "Default value for CXX_STANDARD property of targets")

Это нарушило нашу сборку, потому что каждый Makefile сгенерировал после этот подмодуль теперь ограничивает компиляцию C ++ 11. Я понимаю намерение авторов: если родительский проект не устанавливает кэшированное значение CMAKE_CXX_STANDARD, тогда библиотека устанавливает его на «11», но в остальном его оставляют в покое. Но теперь у нас есть компоненты моей библиотеки, которые строятся по-разному, в зависимости от того, были ли они созданы до или после этого проекта, что слишком странно для удобства. * поведение? Некоторые варианты, каждый из которых дает мне хиб ie -джиби:

  • Продолжать удалять _build/CMakeCache.txt в начале каждого make all, поэтому я буду получать одну и ту же сборку каждый раз . Проблема: применяемые стандарты C ++ будут отличаться в зависимости от порядка генерации Makefile s.
  • Не удаляйте _build/CMakeCache.txt в начале make all. Проблема: первая сборка после очистки будет отличаться от всех последующих сборок.
  • У моего верхнего уровня CMakeLists.txt установлен CMAKE_CXX_STANDARD в кеше, что сделает мои сборки согласованными. Проблема 1. Я перекладываю ответственность на тех, кто пользуется моей библиотекой. Проблема 2: когда-нибудь какой-нибудь подмодуль установит какое-то другое значение в кеше, снова начав гонку вооружений.

Как правильно с этим справиться?

Ответы [ 2 ]

2 голосов
/ 23 июня 2020

CMakeLists.txt верхнего уровня использует список (APPEND as_subproject ...) для добавления ряда сторонних проектов.

На самом деле не рекомендуется полагаться на исходники и билд-система сторонних проектов. Убедитесь, что эти проекты устанавливаются с помощью файлов конфигурации CMake, затем используйте команду find_package(), чтобы найти их (и ограничить их версию тем, что вы знаете, совместимым). В качестве альтернативы, если эти проекты не поддерживают CMake, используйте функцию IMPORTED target .

Это может (или не может) помочь вам обойти проблемы со стандартной версией CMake C ++, но это считается идиоматией c.

0 голосов
/ 23 июня 2020

После долгих исследований я обнаружил, что то, что я описываю, НЕ должно происходить. В CMake переменные устанавливаются на этапе обработки, но не используются до этапа генерации. Итак, в настройке переменных не должно быть зависимостей порядка.

Тот факт, что есть зависимости порядка, указывает на что-то странное в этой системе сборки, что выходит за рамки этого вопроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...