msbuild игнорирует переданный ReferencePath - PullRequest
3 голосов
/ 22 апреля 2020

Резюме:

Я передаю /p:ReferencePath в msbuild, когда строю проект Xamarin. Android. Это работает с Visual Studio 2017, но не с Visual Studio 2019.

Подробно:

У меня есть два проекта:

  • Xamarin.Forms (с основной библиотекой классов, проект iOS и Android внизу)
  • Библиотека классов

Проект Xamarin.Forms ссылается на библиотеку классов через HintPath прямо в Debug сборке. На сервере сборки (Jenkins) все работает по-другому (сборка выпуска), и библиотека собирается отдельно. Поэтому я использую ReferencePath, чтобы перезаписать сохраненную HintPath и ссылаться на библиотеку классов (dll) на сервере Jenkins, который был ранее собран.

Сбой команды сборки выглядит следующим образом

"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin\MSBuild" 
    TestJenkins/TestJenkins/TestJenkins.Android/TestJenkins.Android.csproj 
    /p:Configuration=Release /p:ReferencePath=C:\Jenkins\workspace\TestMSBuild\MPL1.0 
    /t:PackageForAndroid /t:Build /v:diag

Я упустил другие части, потому что они работают. При чтении выходного журнала я заметил следующее: при сборке с Visual Studio 2019:

  • задача ResolveAssemblyReference не отображает переданный ReferencePath в SearchPaths= для сборки Android , но он указан для сборки библиотеки классов (основная библиотека для проекта Xamarin.Forms, а не отдельная библиотека классов)
  • одно предупреждение MSB3245
  • многократная ошибка CS0246

На другом компьютере Jenkins установлено Visual Studio 2017 и тот же код, те же сценарии работают без ошибок. Итак, вопрос в том, в чем разница. В последнее время я обновился до .NET Standard. Возможно, я что-то забыл?

Что я пробовал:

  • настроить аналогичный тестовый проект, но здесь он терпит неудачу с ошибкой CS0103
  • использовать жестко закодированную ссылку в dll с BeforeResolveReferences, и это работает, но это только взлом (непрерывная интеграция не должна работать таким образом)
  • добавление ReferencePath в csproj в Android проекте , но все те же ошибки
  • изменено Copy local в проекте Android
  • Visual Studio 2019 создает проект на сервере Jenkins, если я обновляю ссылки и использую жестко запрограммированный код ссылки
  • читать журнал диагностики c (140 тыс. строк)
  • читать руководство, но использование RerencePath на самом деле не объясняется
  • и многое другое ...

Вопрос:

Как вы можете видеть, я использую инструменты сборки Visual Studio 2019, но я не знаю, что изменилось на Visual Studio 2017 Build Tools. Я звоню msbuild неправильно? /p:ReferencePath работает иначе, чем я ожидаю? Может ли кто-нибудь дать мне подсказку, чтобы найти причину этого?

Edit (1):

Теперь я обнаружил следующее: Ошибка CS0246 указывает на строк в моем проекте Android, где делается оператор using: например, using MyClassLibrary.Component.Feature;.

Предупреждение MSB3245 появляется, если HintPath в проекте Android не может быть решенным.

Вернемся к утверждению using: у меня есть интерфейс, определенный моей внешней библиотекой классов. Класс в проекте Android реализует это. Например,

Код во внешней библиотеке классов:

public interface ITextService
{
    string GetText();
}

Код в Android проекте:

using SomeLibrary; // error CS0246
using Xamarin.Forms;

[assembly: Dependency(typeof(TestJenkins.Droid.TextService))]
namespace TestJenkins.Droid
{
    public class TextService : ITextService // error CS0246
    {
        public string GetText()
        {
            return SomeLibrary.ServiceClass.NativeKey;
        }
    }
}

Вопрос все еще в том, почему нельзя ссылаться на проект Android будет решен?

Редактировать (2):

Для меня это должно быть ошибка в msbuild с VS2019 или изменение поведения. Поэтому я подумал, что могу объединить это с это :

<Project DefaultTargets="Build" InitialTargets="ValidateToolsDllExists" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="ValidateToolsDllExists">
    <Error
        Text=" The ToolsDllPath property must be set on the command line."
        Condition="'$(ToolsDllPath)' == ''" />
    <Error
        Text=" The ToolsDllPath property must be set to the full path to tools.dll."
        Condition="!Exists('$(ToolsDllPath)')" />
  </Target>
  <Target Name="BeforeResolveReferences">
    <CreateProperty
      Value="$(ToolsDllPath);$(AssemblySearchPaths)">
      <Output TaskParameter="Value"
        PropertyName="AssemblySearchPaths" />
    </CreateProperty>
  </Target>
  <!-- ... -->
</Project>

Но передача /p:ToolsDllPath=C:\path\to\my\dll в msbuild по-прежнему выдает ошибку CS0246.

...