Вопрос

Я пытаюсь настроить параллельную сборку на основе Cmake для моего исходного дерева, но когда я выпускаю

$ cmake .
$ make -j2

Я получил:

jobserver unavailable: using -j1.  Add '+' to parent make rule

как предупреждение. У кого-нибудь есть идея, если можно каким-то образом можно исправить?

Это было полезно?

Решение

Похоже, это не проблема Cmake, но только делает.

Другие советы

В сгенерированном makefile при вызове в поддесячественную его необходимо либо использовать $ (make) (не просто 'make'), либо не предшествую строке с A +. То есть правило должно выглядеть так:

mysubdir:
    $(MAKE) -C mysubdir

Или, как это:

mysubdir:
    +make -C mysubdir

Если вы не сделаете это одним из этих двух способов, сделать вам это предупреждение.

Я ничего не знаю о Cmake, поэтому, возможно, это генерирует Makefiles, которые не являются правильными. Или, может быть, вы сделали что-то неправильно на вашем конце.

В моем случае (с Cmake 3.5.2) тривиально cd build && cmake .. && make -j5 работает просто хорошо.

Но я получаю Расповедка не допущена Ошибка при создании пользовательских целей (как зависимости других целей) через 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 восстановит Makefiles, если это необходимо, запустите компиляцию, install все именно так, как с make install, а затем запустите свои пользовательские сценарии, чтобы упаковать заполненную сборку в любой форме или форме, которую мне нужно.

Конечно, я бы хотел make -j15 deb - Но это терпит неудачу.


Теперь, как объяснил На списке рассылки CMake Devs, корневая причина лежит, удивительно (или нет), внутри GNU; Есть обходной путь.

Основная причина в том, что 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 Откатывает среду Portiferver, в конечном итоге, вызывающей однопоточную компиляцию.


То обходной путь Что отлично подходит для меня, как отдано в связанном электронном письме, является префикс всех пользовательских команд с +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 заставить себя вести себя должным образом и уважать -j.

Надеюсь это поможет.

Только от Googleing, похоже, вы используете distcc (например, здесь)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top