VS2010 и MSBuild получают разные результаты в комбинированном решении C ++ / C # - PullRequest
5 голосов
/ 25 февраля 2011

У меня есть большое решение VS2010, которое содержит несколько проектов на C #. Один из этих проектов использует библиотеку C ++ (нативную, иначе неуправляемую) через P / Invoke. Чтобы убедиться, что все собирается правильно, я включил указанный проект C ++ в то же решение. Вот тут-то и начинаются проблемы.

Короче говоря : MSBuild таинственным образом удаляет некоторые выходные файлы, в то время как VS2010 собирается правильно.
,

Длинная история :
Ранее (VS2005 / 2008) я бы использовал изящную функцию под названием «Зависимости проекта». Это то, что позволяет вам выбирать, от каких конкретных проектов зависит тот или иной проект, так что среда обязательно создаст их в первую очередь.

VS2010, однако, переместился в сторону MSBuild, и теперь зависимости проекта просто не работают. Они просто нет. (см. этот вопрос , например) Теперь, чтобы убедиться, что мой проект C ++ собирается до того, как он его потребит, мне нужно «добавить ссылку». Итак, я сделал это. И все вроде нормально.

Но затем я иду в командную строку и запускаю MSBuild для создания того же решения. И опять все строит нормально. Но когда я смотрю в выходную папку, вывода проекта C ++ там нет!

Вывод консоли MSBuild ясно показывает, что проект C ++ действительно был построен в какой-то момент. И я даже вставил некоторые операторы " dir bin \ MYPROJNAME.dll " в качестве шагов после сборки в некоторые проекты, чтобы посмотреть, есть ли там файлы - и они ! Здесь - скриншот окна командной строки. Красным кружком обозначен момент, когда файлы находятся там (вверху), а затем момент отсутствия файлов (внизу).

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

Похоже, что это второе событие сборки - это то, что вызывает удаление файлов: когда я вообще отключил сборку этого проекта (через свойства решения), он был собран только один раз, и файлы были в конце. Я мог бы назвать это «решением», но затем оно ломается в самой Visual Studio: VS просто не создает проект.

Еще один способ исправить это - удалить «Ссылку на проект» из потребляющего проекта C #. Тогда MSBuild соберет проект C ++ только один раз, и файлы будут там. Но затем он ломается в другом месте: изменения в проекте C ++ не вызовут перестройку потребляющего проекта C #.

Итак, вопрос : как мне сделать так, чтобы MSBuild не удалял чокнутые файлы?

Ответы [ 5 ]

1 голос
/ 24 марта 2011

Вероятно, стоит выяснить, что вызывает его создание с первого раза. Что-то запускает эту первую сборку на ранней стадии, даже если вы удалите ссылку на нее. Можете ли вы опубликовать полный журнал msbuild с помощью / v: diag? Часть, которую вы разместили, началась через после интересующего меня раздела:)

1 голос
/ 04 марта 2011

Краткий (немного хакерский) ответ на вопрос:

У вас был каталог в PostBuildEvents. Если вы добавите attrib + r, ваши файлы не будут удалены:

<Exec Command="attrib +r $(TargetPath)"/>

(где TargetPath должен быть DLL-файлами ...)

1 голос
/ 04 марта 2011

Похоже, у вас есть 2 проекта, оба зависят от третьего.Если это не так, тогда вы можете игнорировать весь этот ответ :)

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

Итак, у projectA и projectB есть зависимая сборка projectC.ProjectA запускается, видит, что выход для projectC отсутствует, и вызывает Rebuild.Пока он собирается, появляется другой поток компиляции, и он начинает собирать projectB.Он не видит вывод projectC (он еще не закончил сборку), поэтому вызывает Rebuild, снова очищая проект.Зависимые сборки проверяются в начале проекта, а не тогда, когда они необходимы.Поэтому, если у projectB есть 4 других проекта, которые он должен построить, прежде чем попадет в projectC в своей цепочке зависимостей, может пройти некоторое время, прежде чем эта вторая перестройка будет вызвана для projectC.

Есть несколько способов ее решить.

  1. Попробуйте разрешить зависимые сборки так, чтобы projectA полагалось на projectC.Конечно, это может быть не идеально.

  2. Я думаю, что VS2010 по-прежнему имеет порядок сборки, так что вы можете указать, в каком порядке строятся проекты. Не только зависимости.Убедитесь, что projectC указан перед обоими projectA и projectB.

  3. Самым простым будет сделать 2 вызова для сборки.Сначала позвоните msbuild <project> /target:Clean, затем позвоните msbuild <project> /target:Build не Rebuild, просто Build.Таким образом, и projectA, и projectB видят вывод projectC и не пытаются его построить.

0 голосов
/ 05 июля 2013

Решение: используйте разные промежуточные каталоги для каждого проекта

0 голосов
/ 02 марта 2011

Убедитесь, что вы строите для правильной конфигурации и платформы.Если вы не укажете платформу, она будет собираться без какой-либо платформы, что является своего рода платформой Mixed в зависимости от того, как создается файл msbuild.Visual Studio всегда строится с платформой, указанной в пользовательском интерфейсе, поэтому она может отличаться от командной строки.

Если вы не нашли решения, возможно, обходной путь - создать свойство на основеусловие, устраняющее все, что вызывает проблему, в командной строке (например, сборка проекта дважды) и установка свойства с помощью / p: из командной строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...