Порядок сборки MSBuild
У меня есть большое решение с более чем 100 проектами (С++, Managed С++, С#), и многие из них зависят друг от друга.
У меня есть сервер TeamCity, и я хочу создать там это решение.
Когда я создаю решение в VisualStudio, все идет хорошо, но с TeamCity у меня ошибка CS0006.
Я знаю, почему это так - TeamCity использует MSBuild 4 для создания решений, но в MSBuild 4 есть известная ошибка - она игнорирует порядок построения и создает проекты из решений, чтобы они этого захотели.
Из-за этого поведения, если у вас есть:
Project A
Project B which has reference to A
MSBuild может построить этот проект в следующем порядке:
1. B
2. A
Самое простое решение - установить BuildProjectReferences = true (по умолчанию), и все связанные проекты будут построены автоматически. Но я не могу использовать этот подход, потому что не все ссылки проекта в этом решении, и я не могу строить проекты из другого решения.
Вот еще одно исправление для этой проблемы - используйте ConfigurationManager и отключите все проекты, которые не следует создавать, но они работают только в VisualStudio. MSBuild игнорирует это и создает все проекты, на которые ссылаются.
Проблема заключается в том, чтобы восстановить порядок сборки, который я могу увидеть в VisualStudio в окне ProjectBuildOrder, что неверно, если я использую MSBuild непосредственно из консоли.
Ответы
Ответ 1
См. Неверное упорядочение сборки решения при использовании MSBuild.exe в блоге Visual Studio:
Следуйте этому принципу: не используйте зависимости, выраженные в файле решения вообще! Лучше выразить зависимости в файле, который имеет зависимость: вместо этого поставьте ссылку на проект в проекте. В нашем примере это будет ссылка на проект от B до C.
Возможно, вы не сделали этого раньше, потому что вы не хотели ссылаться на цель ссылки на проект, а просто заказываете сборку. Однако в 4.0 вы можете создать ссылку на проект, которая только заказывает сборку без добавления ссылки. Это будет выглядеть так: обратите внимание на элемент метаданных, и все это находится внутри тега <ItemGroup>
, конечно:
<ProjectReference Include="foo.csproj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
Обратите внимание, что вам нужно добавить дочерний элемент в текстовый редактор - Visual Studio может добавить ссылку на проект, но не предоставляет интерфейс для этих метаданных.
Я могу привести в порядок, удалив зависимость в файле решения, а теперь - ненужные строки вроде этого - ваш GUID будет другим, но используйте диалог VS, и он выполнит задание...
Ответ 2
У меня была такая проблема. Это проявилось в решении, требуя двух сборок, прежде чем успешно построить все решение.
Как оказалось, я случайно добавил ссылку, а не ProjectReference (ищите это в файле .sln), то есть VS/MSBuild потребует и ищет файл библиографии, на который ссылается, но полностью не осознает, как постройте его, если он отсутствует. В конечном итоге процесс сборки будет реализован в проекте с помощью библиотеки ссылок, построив ее и сделав ее доступной для следующей попытки сборки.
В зависимости от вашего дерева зависимостей и конкретного настроения инструментальной цепочки MS это может появиться как спорадическая ошибка и, таким образом, быть отлаживаемой сукой.
Краткая версия. Убедитесь, что ссылки на проекты внутри решения указаны как ProjectReference, а не только Reference. Сделайте это, добавив ссылку на вкладку Solution вместо просмотра и выбора DLL файла.