Установка только одной цели (и ее зависимостей) из сложного проекта с помощью cmake (открытой для лучших решений)

Позволять'скажем, у меня есть проект, состоящий из нескольких подпроектов A, B, C, D ...Все подпроекты зависят от, который меняется довольно часто. Кроме того, могут быть некоторые дополнительные зависимости: в этом примереD зависит от B.

Сейчас: многие люди работают над этими проектами. Основной файл CMakeLists.txt должен включать в себя все каталоги, чтобы сборка собирала все. Но люди хотели бы также иметь возможность работать только над одним из этих проектов, и при этом не нужно каждый раз собирать / устанавливать все.

Если я работаю над D, я могу легко построитьтолько" Буду звонить

cmake --build . --target D -- -j7

или же

ninja -j7 D

Это также создаст A и B, если что-то для них изменилось. Отлично.

Но как я могу вызвать install только для D, не вызывая build all? Я хотел бы, чтобы я позвонил:

ninja -j7 D install

он только построил D (и зависимости), а затем установил только Dи его зависимости (A и B). Вместо этого он создает цель all и устанавливает все.

Я хотел бы, чтобы цель все продолжала строить все. Так что EXCLUDE_FROM_ALL не будетэто не вариант. Но идти в этом направлении я не могне могу найти никакого решения.

Поэтому я думаю о следующей стратегии:

За исключением подпроекта A, все остальные цели устанавливаются в EXCLUDE_FROM_ALL и OPTIONAL при установке.Я добавляю один дополнительный подпроект, который просто зависит от всех других подпроектов (возможно, я заставляю каждую цель публиковать свое имя, используя некоторую переменную, установленную в PARENT_SCOPE), и людям придется вызывать это, когда они хотят собрать и установить все.

Это сработает? Есть ли лучшее решение?

Мы хотели бы избежать того, что каждый должен редактировать основной файл CMakeLists.txt, чтобы исключить проекты, которые ему не интересны. Решение должно быть переносимым на разные ОС.

Редактировать:

Я попробовал стратегию, которую я предложил, но она неt работать: в моем случае, установка оператора для цели (даже если она указана как OPTIONAL) приведет к неэффективности EXCLUDE_FROM_ALL. Чтение лучше вдокументация Я узнал что:

Installing a target with EXCLUDE_FROM_ALL set to true has undefined behavior.

Я также получаю это предупреждение:

Target  has EXCLUDE_FROM_ALL set and will not be built by default but an install rule has been provided for it.  CMake does not define behavior for this case.

Изменить 2:

Я попытался поместить EXCLUDE_FROM_ALL в качестве опции add_subdirectory (вместо add_library / add_executable), но тогда все операторы установки в этих подкаталогах, похоже, игнорируются: будут устанавливаться только операторы установки в подкаталогах не исключенных из всех.

Изменить 3:

Даже если я активируюCMAKE_SKIP_INSTALL_ALL_DEPENDENCY:

set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY true)

в основном файле CMakeLists.txt, и я опускаю все EXCLUDE_FROM_ALL, помещаю установку столько целей, сколько я хочу, необязательно (в моем случае, все, кроме A), и если сборка конкретных целей предшествует установке, все же команда:

ninja -j7 D && ninja install

по какой-то причине произойдет сбой, заявив, что C (чья установка была установлена на OPTIONAL) не существует (он не был создан, потому что D зависел только от A и B) ...

file INSTALL cannot find ""

Изменить 4:

Это похоже на ошибку cmake для меня. (Я использую 2.8.11 под Windows, также протестирован 2.8.10) Эта команда INSTALL

install(TARGETS ${targetname} RUNTIME DESTINATION . LIBRARY DESTINATION . OPTIONAL)

преобразуется в cmake_install.cmake как:

IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified")   

ФАЙЛ (УСТАНОВИТЬ МАРШРУТ "$ {CMAKE_INSTALL_PREFIX} / «. TYPE SHARED_LIBRARY FILES * path_to_dll *)

ЕСЛИ (СУЩЕСТВУЕТ "$ ENV {DESTDIR} $ {} CMAKE_INSTALL_PREFIX /./» И НЕ IS_SYMLINK "$ ENV {DESTDIR} $ {CMAKE_INSTALL_PREFIX} /./* dll_name * ")

IF(CMAKE_INSTALL_DO_STRIP)

  EXECUTE_PROCESS(COMMAND "C:/Programs/MinGW/bin/strip.exe" "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/./*dll_name*")

ENDIF(CMAKE_INSTALL_DO_STRIP)   ENDIF() ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified")

с командой FILE отсутствует ДОПОЛНИТЕЛЬНО! Если я добавлю ДОПОЛНИТЕЛЬНО вручную, это работает! (примечание: я отредактировал здесь, чтобы поместить * dll_name * и * path_to_dll * заполнители)

Изменить 5:

Я подтверждаю этоs ошибка в cmake или, по крайней мере, неправильная документация. Я сообщу об этом. Ситуация решена либо выкладываю более простую

install(TARGETS ${targetname} DESTINATION . OPTIONAL)

(но это в моем случае также установит .lib.a файлы, которые я нене хочу)

или передвигая ФАКУЛЬТАТИВНЫЙ флаг:

install(TARGETS ${targetname} OPTIONAL RUNTIME DESTINATION . LIBRARY DESTINATION .)

Что можно понять изcmake документация это то, что ДОПОЛНИТЕЛЬНО должно быть поставлено как последний вариант.

Ответы на вопрос(4)

Ваш ответ на вопрос