Из страниц справочника:
- j [задания], - задания [=jobs] Определяет количество заданий (команды) для выполнения одновременно. Если существует больше чем одна-j опция, последний является эффективным. Если-j опция дана без аргумента, составьте завещание не, ограничивают количество заданий, которые могут работать одновременно.
Я знаю, что это использует зависимость от графика для знания, какие правила независимы.
Я хотел бы знать, как этот график создается, и поймите то, что является используемыми критериями.
спасибо.
Граф зависимостей основан, как и следовало ожидать, на предварительных требованиях, перечисленных для каждой цели Makefile. make
построит граф, в котором цели и предварительные условия являются вершинами, а от предварительных условий к целям идет направленное ребро. Таким образом, количество входящих ребер говорит о том, сколько предварительных требований у цели. Если у нее нет входящих ребер, значит, у нее нет предпосылок.
Вершины для файлов .c
и .h
, например, не будут иметь входящих ребер. Эти файлы являются вашими исходными файлами и не нуждаются в сборке.
Затем он выполняет топологическую сортировку на графе, чтобы определить порядок выполнения. Из Википедии:
Каноническим применением топологической сортировки (топологического порядка) является планирование последовательности заданий или задач; алгоритмы топологической сортировки были впервые изучены в начале 1960-х годов в контексте методики PERT для планирования в управлении проектами (Jarnagin 1960). Задания представлены вершинами, и существует ребро от x к y, если задание x должно быть завершено до начала выполнения задания y (например, при стирке одежды стиральная машина должна закончить работу до того, как мы положим одежду сушиться). Затем топологическая сортировка дает порядок, в котором следует выполнять задания.
Суть топологической сортировки заключается в том, чтобы найти вершины без входящих ребер (без зависимостей) и поместить их первыми. Затем удалите их из графа. Теперь у вас будет новый набор вершин без входящих ребер (без зависимостей). Они будут следующими. И так далее, пока не закончится. (Если вы когда-нибудь достигнете точки, где нет таких вершин, то граф зависимостей содержит цикл, что является условием ошибки.)
В типичном Makefile это означает, что сначала вы собираете исходные файлы (ничего не нужно делать). Затем объектные файлы, которые зависят от этих исходных файлов. Затем библиотеки и исполняемые файлы, собранные из этих объектных файлов.
При нормальной непараллельной работе make
будет просто выбирать одну цель на каждой итерации и собирать ее. При параллельной работе он будет брать столько целей без зависимостей, сколько сможет, и собирать их параллельно, вплоть до количества разрешенных одновременных заданий.
Поэтому, когда make
дойдет, скажем, до этапа создания объектных файлов, у него будет большое количество вершин в графе, которые все не имеют входящих ребер. Он знает, что может строить объектные файлы параллельно, и поэтому для создания объектных файлов он использует n копий gcc
.
Я подозреваю, что вы ожидаете чего-то более волшебного, чем есть на самом деле. Make-файлы содержат такие строки, как:
target: prereq1 prereq2 prereq3 ...
Это определяет отношения между файлами в системе; на языке графа каждое слово в строке, разделенное пробелами, неявно объявляет узел в графе, а направленное ребро создается между каждым из узлов слева от двоеточия и каждым из узлов справа от двоеточия. , указывая от последнего к первому.
Отсюда просто обойти граф, чтобы найти узлы, у которых нет входящих ребер, и выполнить команды, связанные с этими узлами, а затем оттуда выполнить резервное копирование графа.
Надеюсь, что это поможет.