Re: MSBuild
От: Qbit86 Кипр
Дата: 17.10.11 09:32
Оценка: 4 (1)
Здравствуйте, mihhon, Вы писали:

M>Внутри каждого из solutions зависимости между projects.


Строго говоря, внутри sln-файла зависимости между C#-проектами не хранятся. Там по большему счёту вообще ничего особо ценного или невосполнимого нет. Имхо, не стоит трактовать solution'ы как какие-то логические единицы и вообще уделять им слишком много внимания.

M>Возникла необходимость создать один solution, который бы состоял из ~40 projects, внутри которого только project references, т.е. вместо

M><Reference ...>

M>в *.csproj было бы
M><ProjectReference ...>

M>При этом хотелось бы сохранить структуру 2х существующих solutions.

M>Кроме как написать скрипт , который подменяет (1) -> (2) в *.csproj перед тем, как начать работу в новом solution, и (2) -> (1) перед тем, как комитить в svn , не вижу больше вариантов...


Файлы MSBuild-проектов — это уже скрипты сборки, зачем привлекать какие-то сторонние средства скриптования?

M>Может есть какой-то ещё вариант?


Если вкратце — просто использовать условия в PropertyGroup. В зависимости от как-то определённого окружения (тут возможны варианты по вкусу) будет использоваться один или другой кусок. Ну а вообще, нужно взять и изучить наконец свой инструментарий, а не ограничиваться поисками решений частных проблем.
Глаза у меня добрые, но рубашка — смирительная!
Re[3]: MSBuild
От: Qbit86 Кипр
Дата: 17.10.11 13:38
Оценка: 4 (1)
Здравствуйте, mihhon, Вы писали:

M>http://msdn.microsoft.com/en-us/library/ms164289.aspx

M>ok, merci, something like this
M>    <Choose>
M>      <When Condition=" '$(SolutionName)' == 'X'">
M>      <ItemGroup>
M>        <ProjectReference Include="...">
M>          ...
M>        </ProjectReference>
M>              ...
M>      </ItemGroup>
M>      </When>
M>    </Choose>


По-моему, можно проще, но за точность деталей не ручаюсь:
<ItemGroup Condition=" '$(SolutionName)' == 'X' ">
  <ProjectReference Include="...">
    ...
  </ProjectReference>
</ItemGroup>
<ItemGroup Condition=" '$(SolutionName)' == 'Y' ">
  <Reference Include="...">
    ...
  </Reference>
</ItemGroup>


Но стоит учитывать, что при сборке проекта без Студии (скажем, на билд-сервере), свойство $(SolutionName) может быть не определено, его нужно будет задать отдельно ключём:
msbuild MainApplication.csproj /p:SolutionName=MyProductName

Возможно, лучше в коде скриптов сборки не ссылаться на свойства $(SolutionDir), $(SolutionName) напрямую, а выразить через них свои свойства и ссылаться только на последние. Будучи заданными через ключи сборки, они переопределяют свои объявления в скриптах.
Глаза у меня добрые, но рубашка — смирительная!
Re[4]: MSBuild
От: fddima  
Дата: 17.10.11 12:22
Оценка: 2 (1)
Здравствуйте, VladD2, Вы писали:

Мда. Я запускаю MSBuild с ключём /m (maxcpucount), веря в то что и студия тоже так делает, — в ней указано максимум 2 проекта билдить параллельно.

MSBuild.exe /v:m /m ConsoleApplication1.sln

BeforeBuild target from: '1'
BeforeBuild target from: '2
BeforeBuild target from: '3'
ConsoleApplication1 -> D:\ConsoleApplication1\ConsoleApplication1\bin\Debug\ConsoleApplication1.exe
ConsoleApplication2 -> D:\ConsoleApplication1\ConsoleApplication2\bin\Debug\ConsoleApplication2.exe
ConsoleApplication3 -> D:\ConsoleApplication1\ConsoleApplication3\bin\Debug\ConsoleApplication3.exe


Без него всё случается так же как в студии.
Re[3]: BeforeBuild
От: Qbit86 Кипр
Дата: 17.10.11 10:06
Оценка: +1
Здравствуйте, fddima, Вы писали:

F>BeforeBuild в студии будет выполнен в порядке сборки проектов в солюшине.

F>А MSBuild xxxx.sln -> выполнит сначала все BeforeBuild-таргеты и затем продолжит собирать все проекты.

Честно говоря, пока не проверю, не стану принимать на веру. Но в любом случае закладываться на подобное поведение нельзя. Проекты надо писать так, чтоб они могли быть собраны без всякой Студии.
Глаза у меня добрые, но рубашка — смирительная!
Re[4]: BeforeBuild
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.10.11 12:05
Оценка: +1
Здравствуйте, Qbit86, Вы писали:

Q>Честно говоря, пока не проверю, не стану принимать на веру.


Проверил. Не подтвердилось.

Q>Но в любом случае закладываться на подобное поведение нельзя. Проекты надо писать так, чтоб они могли быть собраны без всякой Студии.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
управление зависимостями projects в solutions VS
От: mihhon  
Дата: 17.10.11 09:08
Оценка:
Eсть 2 solutions s1 s2 , которыми занимаются 2 разные команды, в каждом solution примерно по 30 projects. Внутри каждого из solutions зависимости между projects. Кроме того, между solutions присутствуют взаимные зависимости, примерно по 10 projects из одного solution используются в другом, циклческих зависимостей нет, можно проиллюстрировать такой схемкой.
s1.p1
s1.p2 <----
           \
            ---- s2.p1
                 s2.p2
                 s2.p3
                 s2.p4
            ---> s2.p5
           /
s1.p3 ----
s1.p4


Зависимости внутри solution — project reference, inter-solution — скопированные dll + dll reference. Гемор, но работает.

Возникла необходимость создать один solution, который бы состоял из ~40 projects, внутри которого только project references, т.е. вместо
 (1) <Reference Include="X.Server, Version=0.0.3.0, Culture=neutral, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\..\ThirdParties\X\Assemblies\X.Server.dll</HintPath>
    </Reference>

в *.csproj было бы
(2)<ProjectReference Include="..\Server\Server.csproj">
      <Project>{xxxxxxxx-xxxxxxxxx-xxxxxxxxxx-xxx}</Project>
      <Name>Server</Name>
    </ProjectReference>


При этом хотелось бы сохранить структуру 2х существующих solutions.

Один большой solution — не решение, т.к. и так уже тормозит при компиляции и тестах + команда s2 не имеет доступ к исходникам s1

Кроме как написать скрипт , который подменяет (1) -> (2) в *.csproj перед тем, как начать работу в новом solution, и (2) -> (1) перед тем, как комитить в svn , не вижу больше вариантов...

Может есть какой-то ещё вариант ?


17.10.11 16:05: Перенесено модератором из '.NET' — VladD2
Re[2]: MSBuild
От: fddima  
Дата: 17.10.11 09:57
Оценка:
Здравствуйте, Qbit86, Вы писали:

M>>Внутри каждого из solutions зависимости между projects.

Q>Строго говоря, внутри sln-файла зависимости между C#-проектами не хранятся. Там по большему счёту вообще ничего особо ценного или невосполнимого нет. Имхо, не стоит трактовать solution'ы как какие-то логические единицы и вообще уделять им слишком много внимания.
Строго говоря — да.
Однако следует не забывать, что студия и MSBuild выполняет собирает проекты по разному:
BeforeBuild в студии будет выполнен в порядке сборки проектов в солюшине.
А MSBuild xxxx.sln -> выполнит сначала все BeforeBuild-таргеты и затем продолжит собирать все проекты.
Re[4]: BeforeBuild
От: fddima  
Дата: 17.10.11 11:21
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>Проекты надо писать так, чтоб они могли быть собраны без всякой Студии.

Это несомненно.
Я и сам билды собираю именно с помощью MSBuild.
Re[3]: MSBuild
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.10.11 12:03
Оценка:
Здравствуйте, fddima, Вы писали:

F> Однако следует не забывать, что студия и MSBuild выполняет собирает проекты по разному:

F>BeforeBuild в студии будет выполнен в порядке сборки проектов в солюшине.

Открою тебе сикрет. Сборку студия осуществляет через MSBuild (по крайней мере для проектов C#-а). А порядок компиляции проектов определяется зависимостями проектов которые так же вычисляются через MSBuild. Так что если есть какая-то разница, то она скорее определяется разными значениями окружения.

F>А MSBuild xxxx.sln -> выполнит сначала все BeforeBuild-таргеты и затем продолжит собирать все проекты.


Пошел проверил. Создал два C#-проекта. Добавил в них прожет-референс (смысл в этом нет, но для чистоты эксперимента...) Добавил в каждый по строчке:
   <Target Name="BeforeBuild">
        <Message Importance="high" Text="BeforeBuild target from: '$(AssemblyName)'" />
  </Target>

Выполнил реблид. Получил следующий консольный выхлоп:
------ Rebuild All started: Project: ConsoleApplication375, Configuration: Debug x86 ------
  BeforeBuild target from: 'ConsoleApplication375'
  ConsoleApplication375 -> E:\MyProjects\Tests\ConsoleApplication375\ConsoleApplication375\bin\Debug\ConsoleApplication375.exe
------ Rebuild All started: Project: ConsoleApplication1, Configuration: Debug x86 ------
  BeforeBuild target from: 'ConsoleApplication1'
  ConsoleApplication1 -> E:\MyProjects\Tests\ConsoleApplication375\ConsoleApplication1\bin\Debug\ConsoleApplication1.exe
========== Rebuild All: 2 succeeded, 0 failed, 0 skipped ==========

Из него следует, что очередной BeforeBuild выполняется только после окончания сборки предыдущего проекта.

Так что твое утверждение не соответствует действительности.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: MSBuild
От: fddima  
Дата: 17.10.11 12:04
Оценка:
Здравствуйте, VladD2, Вы писали:

А теперь выполни MSBuild xxxxxx.sln.
Re[5]: MSBuild
От: fddima  
Дата: 17.10.11 12:41
Оценка:
Здравствуйте, fddima, Вы писали:

В дополнение. Это случается только с проектами подключенными через референсы.
Если от 3-го проекта убрать референсы на 2 и 1-ый — но указать ему через Project Build Order, что он завист от 1-го и 2-го -> всё будет чётко следовать указанному порядку вне зависимости от maxcpucount.
Re[5]: MSBuild
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.10.11 12:53
Оценка:
Здравствуйте, fddima, Вы писали:

F>Мда. Я запускаю MSBuild с ключём /m (maxcpucount), веря в то что и студия тоже так делает, — в ней указано максимум 2 проекта билдить параллельно.


Ну, дык — это, как раз, можно и исправить.

Но, согласен, знать (и помнить) об этом надо.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: MSBuild
От: mihhon  
Дата: 17.10.11 13:23
Оценка:
Q>по большему счёту вообще ничего особо ценного или невосполнимого нет.
удобно загрузить все проекты одним кликом, в дебаггере всё видно без указания где исходники и т.п.

Q>Файлы MSBuild-проектов — это уже скрипты сборки, зачем привлекать какие-то сторонние средства скриптования?


http://msdn.microsoft.com/en-us/library/ms164289.aspx

ok, merci, something like this


    <Choose>
      <When Condition=" '$(SolutionName)' == 'X'">
      <ItemGroup>
        <ProjectReference Include="...">
          ...
        </ProjectReference>
              ...
      </ItemGroup>
      </When>
    </Choose>
Re[6]: MSBuild
От: fddima  
Дата: 17.10.11 13:41
Оценка:
Здравствуйте, VladD2, Вы писали:

F>>Мда. Я запускаю MSBuild с ключём /m (maxcpucount), веря в то что и студия тоже так делает, — в ней указано максимум 2 проекта билдить параллельно.

VD>Ну, дык — это, как раз, можно и исправить.
VD>Но, согласен, знать (и помнить) об этом надо.
Да я вот получается, что не знал, и было время когда изрядно помучался из-за этого, пока понял в чём дело...
Забавно, но студия C++ проекты у меня билдит в два процесса аж бегом (т.е. по два cl / link), хотя конечно это не тоже самое.
Re[4]: MSBuild
От: mihhon  
Дата: 17.10.11 13:57
Оценка:
Q>Но стоит учитывать, что при сборке проекта без Студии (скажем, на билд-сервере), свойство $(SolutionName) может быть не определено, его нужно будет задать отдельно ключём:
Q>
Q>msbuild MainApplication.csproj /p:SolutionName=MyProductName
Q>

Q>Возможно, лучше в коде скриптов сборки не ссылаться на свойства $(SolutionDir), $(SolutionName) напрямую, а выразить через них свои свойства и ссылаться только на последние. Будучи заданными через ключи сборки, они переопределяют свои объявления в скриптах.

ок, добавлю Otherwise,
    <Choose>
        <When Condition=" ... ">
            ...
        </When>
        <Otherwise>
            ...
        </Otherwise>
    </Choose>

не знаю, что там на build-server-e