Подтвердить что ты не робот

Почему CMake проводит различие между "целью" и "командой"?

В семантике CMake существует какое-то различие между "целями" и командами ", которые меня озадачивают. В Makefile нет такого различия:

targetname:dependency
    command

то есть. Цели соответствуют сгенерированному файлу с тем же именем.

В CMake у вас есть команды типа "add_custom_command" и "add_custom_target", которые имеют перекрывающиеся функциональные возможности, и даже в официальной документации семантика путается, то есть в "Освоение CMake, 5th edition", стр. 110 в разделе "Добавление настраиваемой цели":

Аргумент DEPENDS устанавливает зависимость между пользовательской целью и пользовательские команды.

Мое понимание заключается в том, что цели (сгенерированные файлы) имеют зависимости (другие файлы, сгенерированные или отсутствующие) и команду на самом деле генерировать. Бессмысленно говорить, что цель зависит от команды. Хуже того, есть два варианта "add_custom_command", которые присоединяют дополнительную команду к существующей цели или выплевывают команду в эфир.

Может кто-нибудь объяснить, почему это различие существует?

4b9b3361

Ответ 1

Цели

В общем, цели включают исполняемые файлы или библиотеки, которые определяются путем вызова add_executable или add_library и который может содержать множество properties.

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

Однако вы также можете определить "пользовательские цели" через add_custom_target. Из документов:

Добавляет цель с заданным именем, которое выполняет заданные команды. Цель не имеет выходного файла и ВСЕГДА РАССМАТРИВАЕТСЯ ОТ ДАТЫ, даже если команды пытаются создать файл с именем цели. Используйте ADD_CUSTOM_COMMAND для создания файла с зависимостями. По умолчанию ничего не зависит от пользовательской цели. Используйте ADD_DEPENDENCIES для добавления зависимостей к другим целевым объектам или из них.

Таким образом, они отличаются от "нормальных" целей тем, что они не представляют вещи, которые будут генерировать exe или lib, но они все равно извлекают выгоду из всех свойств, которые могут иметь целевые объекты, включая наличие или наличие зависимостей. Они отображаются как цель, которая может быть построена (например, make MyCustomTarget или msbuild MyCustomTarget.vcxproj). Когда вы их создаете, вы просто вызываете команды, которые были установлены для них. Если они имеют зависимости от других целей (обычных или пользовательских), то они будут построены первыми.


Пользовательские команды

Пользовательская команда, определенная с помощью add_custom_command, совершенно отличается тем, что она не является "встроенным" объектом и не имеет настраиваемых свойств в том, что делает цель - это не именованный объект, который может быть явно указан снова после его добавления в CMakeLists.txt.

Это в основном команда (или набор команд), которая будет вызываться перед созданием зависимой цели. То, что "зависит" действительно означает здесь (по крайней мере, то, как я его просматриваю) - это просто говорит, что если A зависит от B, тогда B будет построен/выполнен до того, как будет построен A.

Зависимые пользовательской команды могут быть либо явно заданы с использованием формы add_custom_command(TARGET target ..., либо неявно, создавая цели, которые включают файлы, сгенерированные с помощью формы add_custom_command(OUTPUT output1 ....

В первом случае каждый раз, когда target создается, пользовательская команда выполняется в первую очередь.

Во втором случае это немного сложнее. Если пользовательская команда имеет целевые объекты, которые зависят от ее выходного файла (а выходной файл еще не существует), он вызывается до создания этих зависимых объектов. Зависимости неявно создаются, когда вы делаете это, например. add_library(MyLib output1.h ... ) где output1.h - это файл, сгенерированный через add_custom_command(OUTPUT output1.h ... ).