Как MSBuild решает, нужно ли перестраивать библиотеку C # или нет? - PullRequest
22 голосов
/ 22 февраля 2011

Как MSBuild решает, нужно ли ему перестраивать библиотеку (то есть вызывать csc) или нет, когда она запускается с файлом проекта C #?

Я представляю (но хочу подтвердить):

  • Если нет выходного каталога, перестройте (duh :))
  • Если файл C # был изменен, перестройте
  • Если включенный файл, помеченный как copy-всегда, имеетизменен, перестроен
    • Или он достаточно умен, чтобы не перестраивать, а просто скопировать файл в существующий вывод?
  • Если включенный файл помечен как copy-if-newerизменился, перестроить
    • Тот же вопрос, что и выше

Ответы [ 3 ]

12 голосов
/ 22 февраля 2011

Если вы посмотрите в Microsoft.CSharp.targets (файл MSBuild для компиляции проектов C #), для цели CoreCompile определен набор входов и выходов. Они используются для проверки зависимостей, чтобы узнать, нужно ли запускать CoreCompile. В список входных данных входят файлы C #, файлы ресурсов, значок приложения, файл ключа строгого имени и другие пользовательские входные данные, которые вы можете определить.

Если у вас есть решение и вы запускаете на нем MSBuild с включенным ведением журнала диагностики (/ v: параметр командной строки diag), вы можете увидеть это сообщение, если выходные данные обновлены:

Пропуск цели "CoreCompile", потому что все выходные файлы обновлены с уважение к входным файлам.

Файл целей находится в каталоге .NET Framework (C:\windows\Microsoft.NET\Framework\v3.5 or v4.0.30319).

4 голосов
/ 31 января 2012

MSBuild имеет встроенную функциональность для этого.

Цель имеет два свойства: Inputs и Outputs.

Всякий раз, когда Input изменяется илиOutput старше или отсутствует, Target выполняется.

3 голосов
/ 22 февраля 2011

Дело в том, что любая эвристика, которая может звучать правдоподобно, вероятно, не собирается ее сокращать. И когда вы просите, чтобы ваш компилятор (система сборки) выдал вывод, вы, черт побери, гарантируете, что вывод будет именно тем, что вы ожидаете.

Насколько я знаю, MSBuild этого не делает. Он всегда перестраивает (с нуля) все решение / проект. Однако, когда MSBuild вызывается из Visual Studio, временные модули компиляции сохраняются в папке \ obj вашего проекта. Очистка этой папки аналогична восстановлению.

Это сказало, что если компилятор или система сборки будет повторно использовать выходные данные, он будет использовать контрольные суммы фактического содержимого файла, чтобы определить, можно ли получить скомпилированный вывод из какого-либо другого места. По сути, это единственный надежный способ определить, нужно ли перекомпилировать файл с нуля. Кстати, это делается компилятором Visual C #, а не MSBuild.

Атрибут «дата последнего изменения» файловой системы не будет согласованным между системами и, следовательно, в конечном итоге не будет использоваться для определения, следует ли создавать с кэшированным выводом или создавать с нуля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...