Как заголовочные файлы и make-файлы помогают пошаговой компиляции в c ++? - PullRequest
3 голосов
/ 20 марта 2020

Я понимаю, что такое инкрементная компиляция: когда компилятор компилирует только тот код, который вы редактировали, а не весь. Но как разделение кода на файлы .h и .c /.cc и make-файлы в C ++ помогает пошаговой компиляции?

1 Ответ

3 голосов
/ 20 марта 2020

Заголовочные файлы на самом деле противоречат пошаговой компиляции. Любое изменение любого заголовка приведет к повторной компиляции всех исходных файлов, которые включают заголовок (даже косвенно через другой заголовок). Но заголовки значительно упрощают поддержание идентичности всех определений, как того требует язык, для нескольких единиц перевода, поэтому их использование практически необходимо. Такая встречная производительность является причиной того, что «включать только то, что вам нужно» является практическим правилом.

Что помогает инкрементальной компиляции просто иметь меньше определений на единицу перевода. Если вы напишите всю свою программу в одном исходном файле, то любое маленькое изменение в любой маленькой части программы приведет к необходимости перекомпиляции всей программы.

Если вы вместо этого напишите каждую функцию в отдельном исходном файле изменение любой из этих функций приведет к необходимости перекомпиляции только этого крошечного исходного файла и последующего связывания с немодифицированными ранее скомпилированными объектными файлами. Компиляция одной функции обычно быстрее, чем компиляция всей программы. Хотя, если изменение относится, например, к аргументам функции, то все, что вызывает функцию, то есть ее зависимые элементы, также должны быть перекомпилированы (так что это будет случай, когда изменение находится в заголовочном файле, и все зависимые элементы должен включать заголовок).

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

Системы сборки, такие как make и ninja, являются инструментами, которые помимо прочих функций отслеживают ранее скомпилированные исходные файлы и решают, какие из исходных файлов требуют повторной компиляции после модификации. Решение обычно основывается на времени модификации исходного файла (и всех включенных файлов) по сравнению с его скомпилированным объектным файлом.


Это все относится к использованию "тупого" неинкрементного компилятора (который большинство компиляторов), которым требуется инструмент для сборки, чтобы отфильтровать необходимые перекомпиляции, и в них нет инкрементальных логик c. Для по-настоящему инкрементного компилятора системы сборки и, возможно, даже подразделения блоков перевода могут не понадобиться.

...