Как правильно добавить зависимости для отдельных файлов при использовании настройки Visual Studio MSBuild? - PullRequest
0 голосов
/ 10 января 2019

Использование Visual Studio 2013 У меня есть проект, который использует настройку сборки (файлы .props, .targets и .xml, преобразованные и измененные вручную из старого подхода .rules), чтобы связать модели Simulink с решением Visual Studio. Сборка этого проекта делает вызов командной строки MATLAB для каждого из файлов Simulink (.slx) в проекте. Затем MATLAB генерирует заголовки, которые используются другими проектами в решении, а также создает DLL для каждой модели Simulink. Однако я не уверен, как правильно связать зависимости с отдельными файлами .slx. Каждый файл .slx может зависеть от нескольких файлов .m или даже от других. Reference. Model Reference, которые не созданы сами по себе.

MATLAB понимает, что изменение файла .m потребует перестройки файла .slx, даже если нет изменений в самом файле .slx, но Visual Studio автоматически не знает об этой взаимосвязи. Поэтому без дальнейшего вмешательства он будет вызывать MATLAB только в случае изменения самого файла .slx.

После некоторых поисков в Интернете, предположений и экспериментов я обнаружил, что, если я вручную редактирую свой файл .vcxproj, я могу добавить <AdditionalDependencies> для каждого файла .slx в проекте, например так:

<ItemGroup>
  <Real_Time_Workshop___SLX Include="Propulsion\AllEengines.slx">
    <AdditionalDependencies>Propulsion\EngineBasic.slx;Propulsion\PropParam_Common.m;Propulsion\EngineBasic_Data.m;%(AdditionalDependencies)</AdditionalDependencies>
  </Real_Time_Workshop___SLX>
  <Real_Time_Workshop___SLX Include="Propulsion\XMSN.slx">
    <AdditionalDependencies>Propulsion\PropParam_Common.m;Propulsion\PropParam_Mask_XMSN.m;%(AdditionalDependencies)</AdditionalDependencies>
  </Real_Time_Workshop___SLX>
</ItemGroup>

где Real_Time_Workshop___SLX - это правило сборки, определенное в упомянутых выше файлах .props, .targets и .xml, которое заменяет ClCompile для исходных файлов в более традиционном файле проекта C ++.

Эксперимент работал отлично, когда щелкнул правой кнопкой мыши по отдельному файлу .slx в проекте и нажал Compile: если я изменил одну из указанных зависимостей, он вызовет MATLAB и перестроит выбранную модель Simulink; если нет никаких изменений в какой-либо из указанных зависимостей (или в самом файле .slx), то он просто сразу говорит «успешно» (в отличие от «актуальных» или «пропущенных»).

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

Примечание. Я могу публиковать части файлов .props, .targets или .xml, которые определяют правила сборки, или больше моего файла .vcxproj, но я не уверен в соответствующих разделах и не хочу загромождать вопрос с огромным дампом файла. Если есть часть, которая, по вашему мнению, является актуальной, просто спросите, и я отредактирую вопрос, чтобы добавить ее.

===== ОБНОВЛЕНИЕ =====
После некоторых дополнительных экспериментов мне удалось заставить проект обнаруживать изменения в зависимостях, используя некоторые вещи, которые я нашел в этом блоге . Итак, теперь соответствующий раздел моего файла .targets:

<!-- This tag added -->
<ItemGroup>
  <Real_Time_Workshop___SLX_inputs Include="%(Real_Time_Workshop___SLX.AdditionalDependencies)"/>
</ItemGroup>
<ItemGroup>
  <Real_Time_Workshop___SLX_tlog
    Include="%(Real_Time_Workshop___SLX.Outputs)"
    Condition="'%(Real_Time_Workshop___SLX.Outputs)' != '' and '%(Real_Time_Workshop___SLX.ExcludedFromBuild)' != 'true'">
    <Source>@(Real_Time_Workshop___SLX, '|')</Source>
    <Inputs>@(Real_Time_Workshop___SLX_inputs, ';')</Inputs> <!-- This line added -->
  </Real_Time_Workshop___SLX_tlog>
</ItemGroup>
<WriteLinesToFile
  Condition="'@(Real_Time_Workshop___SLX_tlog)' != '' and '%(Real_Time_Workshop___SLX_tlog.ExcludedFromBuild)' != 'true'"
  File="$(TLogLocation)$(ProjectName).write.1u.tlog"
  Lines="^%(Real_Time_Workshop___SLX_tlog.Source);@(Real_Time_Workshop___SLX_tlog-&gt;'%(Fullpath)')"
  Encoding="Unicode" />
<!-- This tag added -->
<WriteLinesToFile
  Condition="'@(Real_Time_Workshop___SLX_tlog)' != '' and '%(Real_Time_Workshop___SLX_tlog.ExcludedFromBuild)' != 'true'"
  File="$(TLogLocation)$(ProjectName).read.1.tlog"
  Lines="^%(Real_Time_Workshop___SLX_tlog.FullPath);%(Real_Time_Workshop___SLX_tlog.Inputs)" />

Если я пересоберу проект, затем внесу изменение в зависимость, а затем соберу, изменение будет обнаружено, и он соберет соответствующий элемент. Если я затем снова нажму «Построить», то сразу появится сообщение «Успешно». Тем не менее, если я снова внесу изменение в зависимость и соберу ее, она не получит это изменение зависимости. Причина в том, что сборка, когда все уже было обновлено, закончилась уничтожением содержимого файла .read.1.tlog. Я не могу понять, почему / как это стирается или как этого избежать. При просмотре подробного журнала уровня «диагностики» я не показываю, когда этот файл записывается ни с чем (хотя журнал действительно показывает, когда он записывается правильно на предыдущих этапах). Поэтому я немного продвинулся, но снова застрял.

...