Re[10]: скопировать в outputdir фал xml документации
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.12.22 10:39
Оценка:
Здравствуйте, MadHuman, Вы писали:

MH>в чем корявость включение инфы о каждом файле зависимости в проект?

нуууу, в том, что у меня уже есть инфа о зависимости моего проекта от выхлопа проекта X. Теперь мне надо ещё раз продублировать ту же инфу, но уже на уровне конкретных файлов.
При этом если, скажем, в проекте X я поменяю output dir, то всё съедет.

MH>после этого, автоматически проекты которые зареференсили ваш будут получать эти зависимости. как раз то что нужно.

Это — да, то, что нужно. П
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[11]: скопировать в outputdir фал xml документации
От: MadHuman Россия  
Дата: 12.12.22 10:44
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, MadHuman, Вы писали:


MH>>в чем корявость включение инфы о каждом файле зависимости в проект?

S>нуууу, в том, что у меня уже есть инфа о зависимости моего проекта от выхлопа проекта X. Теперь мне надо ещё раз продублировать ту же инфу, но уже на уровне конкретных файлов.
S>При этом если, скажем, в проекте X я поменяю output dir, то всё съедет.
речь о следующем, если ваш зависит от проекта Х и Х зависит ещё от каких-то файлов, то в Х и надо включить эти файлы как зависимости.
далее в вашем проекте, зависимости проекта Х автоматом подтянутся.
что ещё нужно?
Re[12]: скопировать в outputdir фал xml документации
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.12.22 12:37
Оценка:
Здравствуйте, MadHuman, Вы писали:
MH>>>в чем корявость включение инфы о каждом файле зависимости в проект?
S>>нуууу, в том, что у меня уже есть инфа о зависимости моего проекта от выхлопа проекта X. Теперь мне надо ещё раз продублировать ту же инфу, но уже на уровне конкретных файлов.
S>>При этом если, скажем, в проекте X я поменяю output dir, то всё съедет.
MH>речь о следующем, если ваш зависит от проекта Х и Х зависит ещё от каких-то файлов, то в Х и надо включить эти файлы как зависимости.
MH>далее в вашем проекте, зависимости проекта Х автоматом подтянутся.
MH>что ещё нужно?
Всё правильно вы говорите. Я только не понимаю, как именно всё это обеспечить, не прибивая в одном из проектов (назовём его X) поимённый список аутпут файлов проекта Y, да ещё и с платформенно-зависимыми путями расположения этих аутпутов.
Лекцию про MSBuild прослушал. Пока что понятнее не стало.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[13]: скопировать в outputdir фал xml документации
От: Ночной Смотрящий Россия  
Дата: 12.12.22 13:33
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Впрочем, я вообще не понимаю, что и как они собирают — в корне лежат .sh и .ps1, которые, судя по всему, вызывают какой-то cmake. Как это всё интегрируется с msbuild — .


1) Из плюсового репа libgit2 они сабмодулем тянут исходники.
2) Батником собирают эти исходники под разные таргеты
3) Делают из этого nupkg, где сборки под разный рантайм разложены по папочкам
4) Референсят этот nupkg уже в managed проекте (libgit2sharp), а там есть специальные таски для формирования таргетов (https://github.com/libgit2/libgit2sharp/tree/master/Targets).

НС>>Все что есть имелось в виду под все таргеты, а не писать условия когда что копировать.

S>Простите, я не понимаю эту фразу. Что такое "под все таргеты"?

Это значит что в твоем nupkg должна быть папочка runtime в котором сложены dll/so под все поддерживаемые платформы, а выбор нужной либы будет делать рантам дотнета уже после запуска приложения.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[13]: скопировать в outputdir фал xml документации
От: MadHuman Россия  
Дата: 12.12.22 14:11
Оценка:
Здравствуйте, Sinclair, Вы писали:

MH>>речь о следующем, если ваш зависит от проекта Х и Х зависит ещё от каких-то файлов, то в Х и надо включить эти файлы как зависимости.

MH>>далее в вашем проекте, зависимости проекта Х автоматом подтянутся.
MH>>что ещё нужно?
S>Всё правильно вы говорите. Я только не понимаю, как именно всё это обеспечить, не прибивая в одном из проектов (назовём его X) поимённый список аутпут файлов проекта Y, да ещё и с платформенно-зависимыми путями расположения этих аутпутов.

не понимаю этого — "не прибивая в одном из проектов (назовём его X) поимённый список аутпут файлов проекта Y"
1. если у вас Х имеет зависимости (файлы которые надо в его аутпут ложить), то в Х и надо их задефайнить. и тут либо поименно (пофайлово) их перечислить, ну либо группой (например все из папки).
причем тут "поимённый список аутпут файлов проекта Y"?

если Y, подцепляет Х, то в Y уже не надо думать как сделать чтоб зависимости из Х попали в аутпут Y.
если п.1 сделать, то оно само начнет работать (подтянет зависимости Х и в аутпут Y).
если непонятно как сделать п.1 — так и скажите, можно пояснить детальней.
мне пока непонятно, что вам непонятно.

как именно сделать п1. — подсказал Михаил тут
Автор: Михаил Романов
Дата: 08.12.22
Отредактировано 12.12.2022 14:15 MadHuman . Предыдущая версия . Еще …
Отредактировано 12.12.2022 14:13 MadHuman . Предыдущая версия .
Отредактировано 12.12.2022 14:12 MadHuman . Предыдущая версия .
Re[14]: скопировать в outputdir фал xml документации
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.12.22 14:12
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>1) Из плюсового репа libgit2 они сабмодулем тянут исходники.

НС>2) Батником собирают эти исходники под разные таргеты
НС>3) Делают из этого nupkg, где сборки под разный рантайм разложены по папочкам
НС>4) Референсят этот nupkg уже в managed проекте (libgit2sharp), а там есть специальные таски для формирования таргетов (https://github.com/libgit2/libgit2sharp/tree/master/Targets).
В указанной папочке про нативные DLL ничего нету — ну, кроме динамического добавления в исходники проекта файла NativeDllName.g.cs c таким кодом:
namespace LibGit2Sharp.Core
{
  internal static class NativeDllName  
  {  
    public const string Name = "$(libgit2_filename)"; // надо полагать, что libgit2_filename генерируется какой-то магией заранее. 
  }
}



НС>>>Все что есть имелось в виду под все таргеты, а не писать условия когда что копировать.

S>>Простите, я не понимаю эту фразу. Что такое "под все таргеты"?

НС>Это значит что в твоем nupkg должна быть папочка runtime в котором сложены dll/so под все поддерживаемые платформы, а выбор нужной либы будет делать рантам дотнета уже после запуска приложения.

У меня пока что нету nupkg
А когда будет, то dll/so в него не войдут — они используются только в рамках тестов и бенчмарков.

Поэтому всё это очень интересно, но я по-прежнему не понимаю, как решить мою проблему.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Отредактировано 12.12.2022 14:18 Sinclair . Предыдущая версия .
Re[14]: скопировать в outputdir фал xml документации
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.12.22 14:18
Оценка:
Здравствуйте, MadHuman, Вы писали:
MH>1. если у вас Х имеет зависимости (файлы которые надо в его аутпут ложить), то в Х и надо их задефайнить.
X зависит от проекта Y.
https://github.com/evilguest/linq2d/blob/master/Linq2d.Tests/Linq2d.Tests.csproj#L46

X = Linq2d.Tests.csproj
Y = SauvolaBinarizeCPP.vcxproj
MH>и тут либо поименно (пофайлово) их перечислить, ну либо группой (например все из папки).
MH>причем тут "поимённый список аутпут файлов проекта Y"?
Ну так это и есть оно. Чтобы "поименно (пофайлово) их перечислить", мне нужно как-то узнать, какие файлы порождаются в SauvolaBinarizeCPP.vcxproj. Чтобы "группой (например все из папки)", нужно знать, в какую папку собирается складывать свои файлы SauvolaBinarizeCPP.vcxproj.
Чтобы в следующем коммите, который меняет что-то в настройках SauvolaBinarizeCPP.vcxproj, не сломать сборку зависящих от него проектов.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[15]: скопировать в outputdir фал xml документации
От: MadHuman Россия  
Дата: 12.12.22 14:23
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>X зависит от проекта Y.

S>https://github.com/evilguest/linq2d/blob/master/Linq2d.Tests/Linq2d.Tests.csproj#L46
S>X = Linq2d.Tests.csproj
S>Y = SauvolaBinarizeCPP.vcxproj
ок

S>Чтобы "поименно (пофайлово) их перечислить", мне нужно как-то узнать, какие файлы порождаются в SauvolaBinarizeCPP.vcxproj.

если SauvolaBinarizeCPP.vcxproj ваш, то вам в нём и надо указать (задефайнить) какие ему нужны для работы файлы.
если не ваш и вы не знаете как он подтягивает свои зависимости, тогда да, хз как это сделать, надо дальше думать.

но правильный путь тут, поправить SauvolaBinarizeCPP.vcxproj так, чтоб в нём как надо были зависимости задефайнены, тогда они автоматом везде будут подтягиваться правильно
Отредактировано 12.12.2022 14:25 MadHuman . Предыдущая версия .
Re[16]: скопировать в outputdir фал xml документации
От: Sinclair Россия https://github.com/evilguest/
Дата: 13.12.22 04:43
Оценка:
Здравствуйте, MadHuman, Вы писали:

MH>если SauvolaBinarizeCPP.vcxproj ваш, то вам в нём и надо указать (задефайнить) какие ему нужны для работы файлы.

Мой. Но ему для работы никакие файлы не нужны.
MH>если не ваш и вы не знаете как он подтягивает свои зависимости, тогда да, хз как это сделать, надо дальше думать.
У SauvolaBinarizeCPP зависимостей нет.
MH>но правильный путь тут, поправить SauvolaBinarizeCPP.vcxproj так, чтоб в нём как надо были зависимости задефайнены, тогда они автоматом везде будут подтягиваться правильно
Поэтому мне по-прежнему непонятно, что нужно делать.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[17]: скопировать в outputdir фал xml документации
От: MadHuman Россия  
Дата: 13.12.22 06:50
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, MadHuman, Вы писали:


MH>>если SauvolaBinarizeCPP.vcxproj ваш, то вам в нём и надо указать (задефайнить) какие ему нужны для работы файлы.

S>Мой. Но ему для работы никакие файлы не нужны.
я описываю задачу, вы говорите — да так. а потом на ключевой момент — нет (что означает что у вас другая задача, отличается от которой я описал).
тогда нужно возвращаться на исходную и уточнять что же вам надо и достигать одинакового понимания
Re[18]: скопировать в outputdir фал xml документации
От: Sinclair Россия https://github.com/evilguest/
Дата: 13.12.22 11:43
Оценка:
Здравствуйте, MadHuman, Вы писали:

MH>тогда нужно возвращаться на исходную и уточнять что же вам надо и достигать одинакового понимания

Я описал задачу. В общем виде — вот: https://rsdn.org/forum/dotnet/8423539.1
Автор: Sinclair
Дата: 07.12.22

у меня есть солюшн, в котором есть C# проект и С++ проект.
Шарповому проекту нужна .dll/.so, которая является результатом сборки C++ проекта. Она должна лечь рядом с шарповой .dll

В конкретном виде описал тут: https://rsdn.org/forum/dotnet/8426579.1
Автор: Sinclair
Дата: 12.12.22

X зависит от проекта Y.
https://github.com/evilguest/linq2d/blob/master/Linq2d.Tests/Linq2d.Tests.csproj#L46

X = Linq2d.Tests.csproj
Y = SauvolaBinarizeCPP.vcxproj

Каких именно деталей не хватает для одинаковости понимания?
Могу изложить ещё подробнее. Смотрите, у проекта Linq2d.Tests две зависимости: https://github.com/evilguest/linq2d/blob/master/Linq2d.Tests/Linq2d.Tests.csproj#L45:L46
Первая — от шарпового проекта. Наличие этой зависимости обеспечивает мне корректное копирование Linq2d.dll и других результатов сборки проекта Linq2d.csproj в результаты сборки проекта linq2d.Tests.
Мне нет никакой нужды руками прописывать в проекте Linq2d.Tests никакие "переложи в OutputDir для Linq2d.Tests.csproj всякие Linq2d.dll, Linq2d.pdb, собранные в проекте Linq2d.csproj". И если я, скажем, пойду в проект Linq2d, и поменяю в нём настройки OutputDir, то у меня сборка Linq2d.Tests всё равно пройдёт корректно. Потому что — магия.


Вторая зависимость — от C++ проекта.
Но SauvolaBinarizeCPP.dll сама никуда не копируется. Почему я должен руками в проекте Linq2d.Tests хардкодить расположение OutputDir и состав файлов SauvolaBinarizeCPP.vcxproj? Это как-то нелогично.
Я же не просто так для красоты поставил на него ProjectReference.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Отредактировано 13.12.2022 11:55 Sinclair . Предыдущая версия . Еще …
Отредактировано 13.12.2022 11:46 Sinclair . Предыдущая версия .
Re[8]: скопировать в outputdir фал xml документации
От: Sinclair Россия https://github.com/evilguest/
Дата: 13.12.22 13:48
Оценка:
Здравствуйте, Михаил Романов, Вы писали:

МР>В общем, если познакомиться с неким базовым Tutorial, то дальше будет гораздо проще.

Познакомился. Пока что — не помогает.

МР>2. Просто офигенный инструмент от Кирилла ОсенковаMSBuild Binary and Structured Log Viewer!

Поставил. Правда, пока непонятно, как в новой винде сделать так, чтобы он открывал .binlog по дабл-клику. Но хоть как-то вручную могу посмотреть.
МР>Просто ставите себе этот вьюер, затем запускаете msbuild с нужными параметрами и ключом /bl (запись бинарного лога)
МР>И дальше всё как на ладони
МР>- какие выполнялись targets (а какие из-за условий пропускались — т.е. вы все равно видите полный pipeline)
МР>- какие параметры передавались в tasks
МР>- какие на выходе этими задачами менялись коллекции items или properties
МР>- ...
Пока что — очень много всего.
Видно, что в целом ResolveProjectReferences работает по-разному для csharp-проектов и для c++ — проектов.
Почему — .
Видно, что вообще в целом происходит какая-то наркомания, и для начала, наверное, нужно разобраться со сборкой С++ проекта, т.к. он у меня собирается то через GCC, то через CL.exe, в зависимости от погоды и фазы луны.
Наверное, после этого можно попробовать понять, почему сборка C++ проекта в рамках пре-реквизита к дотнентому проекту не копирует результаты в output dir дотнетного проекта.

МР>+ Поиск по всему

МР>+ Переход к исходному коду
Ну, это явно инструмент для тех, кто понимает. Ну вот нашёл я внутри билда некую Copy таску:

Task "Copy" skipped, due to false condition; ('$(CopyBuildOutputToOutputDirectory)' == 'true' and '$(SkipCopyBuildProduct)' != 'true') was evaluated as ('true' == 'true' and 'true' != 'true').

Не факт, что она должна была копировать нужные мне файлы — ведь параметров у этой таски никаких не видно. Ну, может быть, это как раз она.
Ищем откуда взялся $(SkipCopyBuildProduct), равный true.
А ниоткуда — просто он такой есть, в списке пропертей vcxproj-проекта, вместе со своим значением.
Попробовал добавить такую проперть в сам .vcxproj-файл — хрен там, ничего не поменялось. Магия.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[9]: скопировать в outputdir фал xml документации
От: Михаил Романов Удмуртия https://mihailromanov.wordpress.com/
Дата: 13.12.22 15:03
Оценка: 70 (1)
Здравствуйте, Sinclair, Вы писали:

S>Видно, что вообще в целом происходит какая-то наркомания, и для начала, наверное, нужно разобраться со сборкой С++ проекта, т.к. он у меня собирается то через GCC, то через CL.exe, в зависимости от погоды и фазы луны.

S>Наверное, после этого можно попробовать понять, почему сборка C++ проекта в рамках пре-реквизита к дотнентому проекту не копирует результаты в output dir дотнетного проекта.
Возможно. На самом деле, MS одно время много чего унифицировали, но я помню, что натыкался на очень разное поведение пайплайна сборки даже внутри .Net (например, для Web-проекта и просто библиотеки).
Это было давно, но верю, что отголоски этого (всё же там разные команды всё это поддерживают) может встречаться на раз.

сорри, нет совсем времени посмотреть внимательнее, но тем не менее глянул.
S>Не факт, что она должна была копировать нужные мне файлы — ведь параметров у этой таски никаких не видно. Ну, может быть, это как раз она.
S>Ищем откуда взялся $(SkipCopyBuildProduct), равный true.
S>А ниоткуда — просто он такой есть, в списке пропертей vcxproj-проекта, вместе со своим значением.
S>Попробовал добавить такую проперть в сам .vcxproj-файл — хрен там, ничего не поменялось. Магия.

Не-не, он обязательно где-то назначается. Найти можно 2-я способами:
— перейти в том же Log Viewer на закладку "Find In Files" и поискать там SkipCopyBuildProduct — он покажет что-то типа

Microsoft.CppCommon.targets
2006 <SkipCopyBuildProduct>true</SkipCopyBuildProduct>

Т.е. обявляется в Microsoft.CppCommon.targets

— или вставить в самое начало вашего проекта
<PropertyGroup>
  <SkipCopyBuildProduct>True</SkipCopyBuildProduct>
</PropertyGroup>

И после сборки поискать в логе снова SkipCopyBuildProduct
И там будет что-то типа

Property reassignment: $(SkipCopyBuildProduct)="true" (previous value: "True") at C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets (2006,5)

Т.е. ваше назначение этой переменной переопределяется в подключенном файле Microsoft.CppCommon.targets.

Значит нам нужно найти где в нашем файле этот Microsoft.CppCommon.targets импортируется (бывает хуже когда он не сам импортируется а его подключают из какого-то файла по цепочке) и вставить
<PropertyGroup>
  <SkipCopyBuildProduct>True</SkipCopyBuildProduct>
</PropertyGroup>

— после этого импорта (а он почти в конце файла проекта стоит)

Я попробовал, но у меня сразу посыпались какие-то новые ошибки. Оказалось, что почему-то, что в папке x64\Debug внутри проекта dll-ка не создается. Вместо неё лежит SauvolaBinarizeCPP.dll.recipe в котором ссылаются на папку x64 в самом солюшене. Хотя последняя вроде как кладется в репозиторий...

В общем, сорри, просто пока нет времени покопаться.
Re[10]: скопировать в outputdir фал xml документации
От: Sinclair Россия https://github.com/evilguest/
Дата: 14.12.22 08:02
Оценка:
Здравствуйте, Михаил Романов, Вы писали:


МР>Значит нам нужно найти где в нашем файле этот Microsoft.CppCommon.targets импортируется (бывает хуже когда он не сам импортируется а его подключают из какого-то файла по цепочке) и вставить

МР>
МР><PropertyGroup>
МР>  <SkipCopyBuildProduct>True</SkipCopyBuildProduct>
МР></PropertyGroup>
МР>

МР>- после этого импорта (а он почти в конце файла проекта стоит)
Вы совершенно правы — эти шаги помогли.
Но щасте так и не настало — там в итоге DLL копируется сама в себя (а не в фолдер зависимого проекта). Надо полагать, именно поэтому Microsoft.CppCommon.targets задавливает эту таску — файл выкладывается в выходной фолдер другими тасками.
Надо копать с другой стороны: разбираться, какой магией дотнетовые проекты узнают, что именно нужно тащить к себе после сборки ProjectReference.

МР>Я попробовал, но у меня сразу посыпались какие-то новые ошибки. Оказалось, что почему-то, что в папке x64\Debug внутри проекта dll-ка не создается. Вместо неё лежит SauvolaBinarizeCPP.dll.recipe в котором ссылаются на папку x64 в самом солюшене. Хотя последняя вроде как кладется в репозиторий...

Ну, вот конкретно это и есть то, о чём я говорил — сборка C++ в msbuild работает не как у людей, а просто гадит результатами в папку на уровне solution.
Поэтому зависимости между двумя С++ проектами резолвятся корректно — A.exe собирается в папку $(SolutionDir)\x64\Debug, и B.dll тоже собирается в папку $(SolutionDir)\x64\Debug.

P.S. Вообще, это же какая-то достаточно популярная штука — реализовать часть функций в неуправляемой DLL и заиспользовать её в своём проекте. Непонятно, почему она не работает из коробки.
P.P.S. Я, в целом, понимаю (особенно после комментариев коллег в этой ветке), что вот такая вот нативно-управляемая сборка по хорошему должна делаться через мультиплатформенную сборку, т.к. в отличие от управляемого кода, неуправляемый код нельзя скомпилировать под "любая битность, любая платформа".

Правильное решение, конечно же, иметь некоторый NuGet-package, который ставит на текущую платформу нужную неуправляемую DLL. Тогда в дотнетном проекте можно просто сделать PackageRef на этот пакет, а всё остальное магически заработает.

Но у меня по-прежнему отсутствует понимание:
1. Как мне собрать пакет под 2 платформы, компилируясь на 1й
2. Как мне обойтись без публикации пакета (хотя бы и в локальном репозитории) при локальной сборке.
Но это так, вопросы в воздух — их изучение явно выходит за рамки формата форумных постов.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[11]: скопировать в outputdir фал xml документации
От: Михаил Романов Удмуртия https://mihailromanov.wordpress.com/
Дата: 14.12.22 10:38
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Но у меня по-прежнему отсутствует понимание:

S>1. Как мне собрать пакет под 2 платформы, компилируясь на 1й
S>2. Как мне обойтись без публикации пакета (хотя бы и в локальном репозитории) при локальной сборке.
S>Но это так, вопросы в воздух — их изучение явно выходит за рамки формата форумных постов.
Увы, но для меня Unmamged код и всё что с ним связано — Terra incognita, и с ходу ответить на эти вопросы, я увы, не смогу.

Также как и на вопрос, как именно осуществляется передача информации между зависимыми проектами — точного ответа у меня нет (там есть несколько путей — например, сама target Build порождает output значения с полным путем до сборки, а еще пишется некий промежуточный файл, куда, в частности, попадают вообще все файлы, записанные в Output директорию). Но, вот на что ориентируется принимающая сторона, а также что из этого делает (или может делать) C++ проект, я увы...
Re[19]: скопировать в outputdir фал xml документации
От: MadHuman Россия  
Дата: 14.12.22 10:43
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, MadHuman, Вы писали:


MH>>тогда нужно возвращаться на исходную и уточнять что же вам надо и достигать одинакового понимания

S>у меня есть солюшн, в котором есть C# проект и С++ проект.
S>Шарповому проекту нужна .dll/.so, которая является результатом сборки C++ проекта. Она должна лечь рядом с шарповой .dll
S>X зависит от проекта Y.
S>https://github.com/evilguest/linq2d/blob/master/Linq2d.Tests/Linq2d.Tests.csproj#L46

S>X = Linq2d.Tests.csproj

S>Y = SauvolaBinarizeCPP.vcxproj

S>Могу изложить ещё подробнее. Смотрите, у проекта Linq2d.Tests две зависимости: https://github.com/evilguest/linq2d/blob/master/Linq2d.Tests/Linq2d.Tests.csproj#L45:L46

S>Первая — от шарпового проекта. Наличие этой зависимости обеспечивает мне корректное копирование Linq2d.dll и других результатов сборки проекта Linq2d.csproj в результаты сборки проекта linq2d.Tests.
S>Мне нет никакой нужды руками прописывать в проекте Linq2d.Tests никакие "переложи в OutputDir для Linq2d.Tests.csproj всякие Linq2d.dll, Linq2d.pdb, собранные в проекте Linq2d.csproj". И если я, скажем, пойду в проект Linq2d, и поменяю в нём настройки OutputDir, то у меня сборка Linq2d.Tests всё равно пройдёт корректно. Потому что — магия.
S>Вторая зависимость — от C++ проекта.
S>Но SauvolaBinarizeCPP.dll сама никуда не копируется. Почему я должен руками в проекте Linq2d.Tests хардкодить расположение OutputDir и состав файлов SauvolaBinarizeCPP.vcxproj? Это как-то нелогично.
S>Я же не просто так для красоты поставил на него ProjectReference.
понятно. ну значит для C++ проектов даже при подцеплении его в ваш X через ProjectReference, не обеспечивает автоматическое корректное копирование его артифактов билда в аутпут X.
правильный способ (а это исправление неправильного поведения) требует сильно углубиться в анализ билда C++ проекта и анализ — как .Net проект подтягивает зависимости себе от другого. непростой путь.
тут я думаю лучше — завести ишью в репу сишарпа (или спп) — пусть чинят.

есть вариант проще. в X вы можете подцепить ссылки на готовые дллки от Y (как итемы проекта). и Y не подцеплять, пусть отдельно компилится и в некую шаред папку ложит артефакты.
либо ссылки на дллки от Y подцепить явно на его аутпут.
после того как в Х это проделаете, эти дллки (от Y) автоматом будут подтягиваться в аутпут Х (а также в аутпут тех проектов кто подцепит Х).
чтоб разрулить разноплатформенность у подцепленных ссылок прописать Condition (аналогично как вы прописали для таргета по копированию).
по моему норм.
Отредактировано 14.12.2022 10:45 MadHuman . Предыдущая версия .
Re[20]: скопировать в outputdir фал xml документации
От: Sinclair Россия https://github.com/evilguest/
Дата: 14.12.22 11:15
Оценка:
Здравствуйте, MadHuman, Вы писали:
MH>понятно. ну значит для C++ проектов даже при подцеплении его в ваш X через ProjectReference, не обеспечивает автоматическое корректное копирование его артифактов билда в аутпут X.
То-то и оно.

MH>есть вариант проще. в X вы можете подцепить ссылки на готовые дллки от Y (как итемы проекта). и Y не подцеплять, пусть отдельно компилится и в некую шаред папку ложит артефакты.

Непонятно, как вы себе это представляете. Вы имеете в виду
1. Собрать С++ проект
2. Добавить в C# проект артефакты от 1 как Project Item, поставив Copy To Output folder = CopyIfNewer
3. Надеяться, что всё заработает само?
Ну, как бы имхо способ ненамного лучше, чем пост-билд с copy command. Особенно с учётом того, что расположение этих dll-ек зависит от платформы и битности.


MH>либо ссылки на дллки от Y подцепить явно на его аутпут.

Я не понимаю, что значит эта фраза. Ссылок в X есть два типа: PackageReference и ProjectReference. "дллки от Y" не являются ни тем ни другим.

MH>после того как в Х это проделаете, эти дллки (от Y) автоматом будут подтягиваться в аутпут Х (а также в аутпут тех проектов кто подцепит Х).

MH>чтоб разрулить разноплатформенность у подцепленных ссылок прописать Condition (аналогично как вы прописали для таргета по копированию).
MH>по моему норм.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[21]: скопировать в outputdir фал xml документации
От: MadHuman Россия  
Дата: 14.12.22 11:30
Оценка: 41 (1)
Здравствуйте, Sinclair, Вы писали:

MH>>есть вариант проще. в X вы можете подцепить ссылки на готовые дллки от Y (как итемы проекта). и Y не подцеплять, пусть отдельно компилится и в некую шаред папку ложит артефакты.

S>Непонятно, как вы себе это представляете. Вы имеете в виду
S>1. Собрать С++ проект
S>2. Добавить в C# проект артефакты от 1 как Project Item, поставив Copy To Output folder = CopyIfNewer
S>3. Надеяться, что всё заработает само?
да. только причем тут надеятся? это рабочий вариант.

S>Ну, как бы имхо способ ненамного лучше, чем пост-билд с copy command. Особенно с учётом того, что расположение этих dll-ек зависит от платформы и битности.

на мой имхо получше. в обоих случаях фиксируется информация о внешней зависимости, только в варианте о котором я — это естественный способ (описали что нужно путем добавления project item-ов, далее оно само будет в ауптут Х ложиться).
не надо разные команды копирования прописывать под разные платформы. если вдруг Х будет использован в других проектах (через проджект-референс), то эти зависимости автоматически подтянутся.
зависимость от платформы точно также за счет Condition прописать на Project Item-мах.
если это ненамного — ну ок, оставьте как есть.


MH>>либо ссылки на дллки от Y подцепить явно на его аутпут.

S>Я не понимаю, что значит эта фраза. Ссылок в X есть два типа: PackageReference и ProjectReference. "дллки от Y" не являются ни тем ни другим.
я о Project Item, вот как их.
Re[9]: скопировать в outputdir фал xml документации
От: Михаил Романов Удмуртия https://mihailromanov.wordpress.com/
Дата: 04.01.23 17:20
Оценка: 150 (2)
Здравствуйте, Sinclair, Вы писали:

S>Корявость — в том, что гвоздями прибивается информация о конкретных файлах в конкретных проектах. И что я не понимаю, как сделать так, чтобы выполнение этого копирования зависело от успешности сборки. Всё, на что меня хватило — разруливание копирования .dll/.so в зависимости от платформы, на которой выполняется сборка.


S>Нормальное решение — чтобы зависимый проект автоматически находил все output-ы С++-зависимостей и тащил из за собой. В том числе, к примеру, и .pdb.

S>Именно так всё работает для дотнетных зависимостей.
S>А для C++ — проектов эта очевидная штука из коробки не работает, и как её заставить работать у меня ума не хватает разобраться.
S>Зависимости между плюсовыми проектами резолвятся благодаря как раз тому, что С++ гадит свои результаты не в фолдер проекта, а на уровень солюшна. В итоге все .dll и .exe случайно оказываются в одном и том же месте.

Добрый вечер, Антон.
Я наконец-то собрался (праздники развращают!) и смог взглянуть на ваш проект и в целом покопаться в том, как работают зависимости между проектами.
В первом приближении, некоторое решение у меня появилось, оно, правда, не сказать что прямо совсем изящное..., а еще я не смог его протестировать на сборку под Linux (простите — но стало очень лень возиться и разбираться как работает сборка для Linux), буду признателен, если проверите и расскажите.

В общем, моя идея: заменить вашу PostBuild на вот такое (по поводу _ThisProjectItemsToCopyToOutputDirectoryAlways я рассказывал в соседней ветке, а остальное постарался по возможности пояснить в комментариях)
<Target Name="_CopyLibsFromVCProjects" BeforeTargets="GetCopyToOutputDirectoryItems">
    <!-- 
        Получаем из ProjectReferences те из проектов, которые имеют расширение
        .vcxproj (проекты для VC). Мы тут используем не ProjectReferences, а его "обогащенную"
        версию ProjectReferenceWithConfiguration - там для каждого проекта посчитаны и добавлены 
        всякие важные параметры, например, в какой конфигурации собирать
    -->
    <ItemGroup>
        <_NativeProjects Include="@(ProjectReferenceWithConfiguration)" 
                         Condition="'%(Extension)' == '.vcxproj'" />
    </ItemGroup>
    
    <!-- 
        Запускаем для этих проектов MSBuild, точно таким же образом, как он запускается когда идет 
        обработка ProjectReferences. Разница только в том, что там вызываются Targets по умолчанию (или 
        те, которые задаются явно в ProjectReferences, но обычно это просто Build), а мы вызываем  
        GetTargetPath, которая просто возвращает путь до результат компиляции
    -->
    <MSBuild
        Projects="@(_NativeProjects)"
        Targets="GetTargetPath"
        BuildInParallel="$(BuildInParallel)"
        Properties="%(_NativeProjects.SetConfiguration); %(_NativeProjects.SetPlatform);  %(_NativeProjects.SetTargetFramework)"
        RemoveProperties="%(_NativeProjects.GlobalPropertiesToRemove)$(_GlobalPropertiesToRemoveFromProjectReferences)"
        >

        <Output TaskParameter="TargetOutputs" ItemName="_NativeProjectLibs"/>
    </MSBuild>
    
    <!-- 
        Полученный набор файлов (обычно от одного проекта 1 файл - основной результат компиляции, 
        т.е. файл .exe или .dll) мы добавляем в коллекцию _ThisProjectItemsToCopyToOutputDirectoryAlways 
        - это файлы из проекта, которые помечены "CopyAlways". Эта задача копирует файлы с учетом всех 
        папок от корня проекта до нужного файла, а у нас файл вообще вне проекта ,поэтому мы такое поведение 
        пресекаем, указывая явно метаданные TargetPath (а в нем - просто имя файла с расширением)
    -->
    <ItemGroup>
        <_ThisProjectItemsToCopyToOutputDirectoryAlways Include="%(_NativeProjectLibs.FullPath)">
            <TargetPath>%(_NativeProjectLibs.Filename)%(_NativeProjectLibs.Extension)</TargetPath>
        </_ThisProjectItemsToCopyToOutputDirectoryAlways>
    </ItemGroup>
</Target>
Re[10]: скопировать в outputdir фал xml документации
От: Михаил Романов Удмуртия https://mihailromanov.wordpress.com/
Дата: 04.01.23 18:32
Оценка:
Здравствуйте, Михаил Романов, Вы писали:

Ну и если интересно откуда это нарисовалось, то кратко пройдусь по тому, что я накопал (а потом, если будут нужны подробности, можно будет по ключевым словам пройти и раскопать нужное)

Для начала, как работает резолвинг зависимостей в .Net проектах...
Основная "точка входа" это target ResolveReferences. Которая объявлена как
  <PropertyGroup>
    <ResolveReferencesDependsOn>
      BeforeResolveReferences;
      AssignProjectConfiguration;
      ResolveProjectReferences;
      FindInvalidProjectReferences;
      ResolveNativeReferences;
      ResolveAssemblyReferences;
      GenerateBindingRedirects;
      ResolveComReferences;
      AfterResolveReferences
    </ResolveReferencesDependsOn>
  </PropertyGroup>

  <Target
      Name="ResolveReferences"
      Returns="@(ReferencePath)"
      DependsOnTargets="$(ResolveReferencesDependsOn)"/>


Т.е. это просто мета-цель, а вся работа делается в целях из списка ResolveReferencesDependsOn (что в общем является обычной практикой для MSBuild файлов от MS).

Нас из этого списка интересуют:
AssignProjectConfiguration — в этой цели для каждого проекта, которые перечислены в коллекции ProjectReference, вычисляются параметры, с которыми этот проект нужно запустить на сборку (в первую очередь, конечно, это Platform и Configuration. Возможно что-то еще, но я уже не смотрел). В результате формируется коллекция ProjectReferenceWithConfiguration — это та же ProjectReference, только в метаданных у каждого Item дополнительно параметры сборки.
ResolveProjectReferences — в этой target берется коллекция ProjectReferenceWithConfiguration (это не совсем точно: там берется _MSBuildProjectReferenceExistent — это ProjectReferenceWithConfiguration из которой убрали все уже разрезолвенные проекты) и для всех проектов пробуют запустить MSBuild с рассчитанными параметрами сборки и собирают список того, что эти вызовы вернули

Что это дает?
Напомню, что у любой Target можно объявить атрибут Returns — это то, что вернет Target, если её вызвать с помощью встроенной задачи <MSBuild ... />.
Так вот, по умолчанию для всех проектов вызывается target Build. Эта цель:
— в .Net проектах возвращает полный путь до сгенерированного файла сборки
— в C++ тоже полный путь до результат сборки, но (!) только если это Managed C++
Причем, в ResolveProjectReferences еще дополнительно проверяется, что полученный список результатов компиляций содержит только Managed сборки и всё остальное безжалостно выкидывается.

В принципе, логика в таком поведении есть, т.к. этот список сборок напрямую идет на вход C# компилятора, а он не умеет обрабатывать unmaged файлы.

В общем, вызывать у C++ проектов Build так же как у .Net проектов смысла нет.
Но (по счастью!), оказалось, что в C++ проектах реализована специальная Target — GetTargetPath. Она (если передать на вход такие же параметры сборки как для Build) возвращает путь до результата сборки, как это делает Build в .Net проектах.
Ну собственно, дальше оставалось это и сделать — получить список .Net проектов и вызвать для них GetTargetPath с нужными параметрами (сразу скажу — я тупо этот вызов <MSbuild> стащил из файлов MS).
Ну а дальше уже копируйте каким вам удобно способом — напрямую через <Copy /> или как я — добавляя в какую-нибудь подходящую коллекцию, которая формирует список файлов для выходного каталога.

Ну а что касается вопроса "откуда берутся все остальные файлы (.pdb, .xml, ...)", то тут срабатывает target ResolveAssemblyReferences.
В ней вызывается некая одноименная задача (если интересно, можно посмотреть что конкретно она делает), которая получает на вход список сборок, подключеннных проекту, а также то, что было получено предыдущими ResolveXXX целями.

Сразу скажу я её код не смотрел, но судя по параметрам, он берет входные сборки, анализирует их и формирует список сателитных файлов.
Причем, там напрямую указывается какие расширения (т.е. имя такое же — но меняется расширение) нужно подхватывать. Я это писал раньше вот тут
Автор: Михаил Романов
Дата: 07.12.22
.

Т.е. по большому счету мы имеем следующее:
— в принципе, все проекты, для которых существует MSBuild сборка (и её писала MS) умеют вернуть полный путь к целевому файлу. Разница в том, что .Net проекты это делают при вызове target Build (и по умолчанию она и вызывается, если в проект добавлена ссылка на другой проект), а вот C++ такое делают только если на выходе Managed сборка (т.е. если это Managed C++).
— с другой стороны для С++ есть еще target GetTargetPath, которая частично проблему решает. Другой момент, что простого способа этот обходной путь задействовать я не нашел, пришлось нагромоздить.
— ну а все сопутствующие файлы — это задач не генерирующего проекта, а ссылающегося. Т.е. каждый ссылающийся проект сам решает, что ему "прихватить" помимо самой сборки.

Может я чего где напутал или упустил, но тут уж только смотреть и проверять.

P.S. Сорри за сумбурность изложения. Тема хоть и интересная, но от силы паре человек, и писать подробно нет особо желания. Да и не во всем я хорошо разобрался, увы.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.