В моем случае (с 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
- но это не удается.
Теперь, как explained в списке рассылки по 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
капли jobserver окружающей среды, в конечном счете, вызывая однопоточную компиляцию.
обходной путь который работал большой для меня, как отданный в связанном электронной почты, чтобы префикс всех пользовательских команд с +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
в соответствующем Makefile (CMake генерирует кучу из них), и вызывает GNU Make, чтобы правильно вести себя и уважать -j
.
Надеюсь, это поможет.
. Это оказалось так, поэтому я принимаю этот ответ;) –
.... но .... cmake - это инструмент, который _generated_ ваш Makefile.Таким образом, если CMake производит Makefile, который не может быть распараллелен, тогда для исправления проблемы требуется исправление ваших CMakeLists, нет? –
Это правильно, но никоим образом не помогает и не помогает. ▼ – ulidtko