Почему поведение детерминированной сборки отличается в зависимости от типа проекта

#c# #.net #msbuild #csproj #deterministic

#c# #.net #msbuild #csproj #детерминированный

Вопрос:

У меня есть 2 проекта — ClassLibrary1, ClassLibrary2, оба с включенной детерминированной сборкой. ClassLibrary1 ссылается на ClassLibrary2. Если в ClassLibrary2 внесено изменение, и это изменение никак не влияет на ClassLibrary1 (например, добавлено поле, версия сборки не изменена), я бы ожидал, что детерминированный вывод ClassLibrary1 не должен меняться. И на самом деле, это не меняется, если проекты относятся к классическому типу, отличному от SDK. Однако, как только я меняю тип проекта на стиль SDK, любое изменение ClassLibrary2 вызывает двоичное изменение ClassLibrary1. (протестировано на net472)

На самом деле, в документации указано, что двоичное содержимое всех файлов, явно переданных компилятору, влияет на детерминизм. Поэтому я думаю, что новое поведение довольно правильное. Но у меня есть несколько вопросов.

Почему поведение отличается в зависимости от типа проекта?

Действительно ли необходимо, чтобы детерминированный вывод зависел от двоичного вывода ссылочных библиотек (а не только от используемого из них API)?

Есть ли способ преодолеть это и вернуться к первоначальному поведению?

Комментарии:

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

2. @mirva можете ли вы попробовать ту же настройку с проектами в стиле SDK и .NET 5 или .NET 6 в качестве цели? По умолчанию используется компиляция с использованием компиляции ссылочной сборки, которая должна быть тем, что вы описываете. Вы можете выбрать такое же поведение, установив для свойства ProduceReferenceAssembly значение True в группе свойств csproj

3. Спасибо @martin-ullrich. Это действительно работает для всей поверхности API ссылочной сборки. Но это все еще не то же поведение, что и для старых проектов — там только используемый API влиял на результат. И кстати. создание ссылочных сборок, похоже, теперь используется по умолчанию в .NET5.

4. У вас есть воспроизводимый образец? (еще одна вещь, о которой я могу думать, которая вызывает это, — атрибуты версии сборки / файла, содержащие подстановочные знаки)