В моем случае (с CMake 3.5.2) тривиальный cd build && cmake .. && make -j5
работает просто отлично.
Но я получаю ошибку jobserver недоступен при создании пользовательских целей (как зависимостей от других целей) с помощью идиомы cmake --build . --target foo
.
Как это:
add_custom_target(buildroot
COMMAND ${CMAKE_COMMAND} --build . --target install
COMMENT "Populating buildroot..."
)
add_dependencies(deb buildroot)
add_dependencies(rpm buildroot) #... etc
- так что пользователь может make deb
, и он просто работает. CMake при необходимости восстановит make-файлы, запустит компиляцию, install
все точно так же, как с make install
, а затем запустит мои пользовательские сценарии, чтобы упаковать заполненный buildroot в любую нужную мне форму или форму.
Конечно, я бы хотел make -j15 deb
- но это не удалось.
Теперь, как объяснил в списке рассылки разработчиками CMake, основная причина, к удивлению (или нет), лежит в GNU Make; есть обходной путь.
Основная причина в том, что make
не будет передавать свою среду сервера заданий дочерним процессам, которые, по его мнению, не make
.
Для иллюстрации приведем ветку дерева процессов (ps -A f
):
…
\_ bash
\_ make -j15 deb
\_ make -f CMakeFiles/Makefile2 deb
\_ make -f CMakeFiles/buildroot.dir/build.make CMakeFiles/buildroot.dir/build
\_ /usr/bin/cmake --build . --target install ⦿
\_ /usr/bin/gmake install
…
В точке *, make
отбрасывает среду сервера заданий, в конечном итоге вызывая однопоточную компиляцию.
Обходной путь , который отлично сработал для меня, как указано в сообщении, связанном с электронной почтой, заключается в добавлении к префиксам всех пользовательских команд +env
. Как это:
add_custom_target(buildroot
#-- this ↓↓↓ here -- https://stackoverflow.com/a/41268443/531179
COMMAND +env ${CMAKE_COMMAND} --build . --target install
COMMENT "Populating buildroot..."
)
add_dependencies(deb buildroot)
add_dependencies(rpm buildroot) #... etc
В конце это появляется в правиле для buildroot
в соответствующем make-файле (CMake генерирует их несколько) и заставляет GNU Make вести себя правильно и уважать -j
.
Надеюсь, это поможет.