2016-10-06 6 views
0

У меня есть проект под названием cryptdll.vcxproj. cryptdll зависит от артефактов из двух других проектов в решении. Другие проекты: cryptlib и cryptest. Для тех, кто интересуется компоновкой элементов в cryptdll, он находится по адресу cryptdll.Преобразование объекта PreBuildEvent в цель с условием?

Зависимости несколько необычны и не так легко выражаются в редакторе Visual Studio. Они необычны, потому что политика требует, чтобы Win32\Output\Debug\cryptest.exe всегда использовался для использования PostBuildEventcryptdll.

я обнаружил, что могу добавить следующее cryptdll, чтобы все заработало, как и ожидалось:

<!-- Win32/Debug cryptest.exe for DLL MAC'ing --> 
<ItemDefinitionGroup Condition="!Exists('Win32\Output\Debug\cryptest.exe')" Label="MAC tool"> 
    <PreBuildEvent> 
    <Message>Creating Win32/Debug cryptest.exe for MAC computation</Message> 
    <Command> 
     msbuild /t:Build /p:Configuration=Debug;Platform=Win32 cryptlib.vcxproj 
     msbuild /t:Build /p:Configuration=Debug;Platform=Win32 cryptest.vcxproj 
    </Command> 
    </PreBuildEvent> 
</ItemDefinitionGroup> 

Когда я попытался преобразовать его в мишень он перестал работать. Ниже приведено правило назначения.

<!-- Win32/Debug cryptest.exe for DLL MAC'ing --> 
<Target Condition="!Exists('Win32\Output\Debug\cryptest.exe')" Name="MAC tool" Label="MAC tool"> 
    <MSbuild 
    Projects="cryptlib.vcxproj" 
    Properties="Configuration=Debug;Platform=Win32;"/> 
    <MSbuild 
    Projects="cryptest.vcxproj" 
    Properties="Configuration=Debug;Platform=Win32;"/> 
</Target> 

Мой вопрос: что не так с кодом, преобразованным в цель, и как его исправить?


Для полноты, я хочу то, что Makefile люди называть Prerequisite. Лучшее, что я могу сказать из поиска, каждый результат для "MSBuild prerequisite" не имеет значения.


Вот как выглядит результат Target'd. Обратите внимание, что задача пропущена, как будто ее не было.

>del /q /s Win32 x64 
... 

>msbuild /t:build /p:Configuration=Release;Platform=x64 cryptdll.vcxproj 
Microsoft (R) Build Engine version 4.6.1055.0 

Build started 10/6/2016 11:40:26 AM. 
Project "c:\cryptopp\cryptdll.vcxproj" on node 1 (build target(s)). 
PrepareForBuild: 
    Creating directory "x64\cryptdll\Release\". 
    Creating directory "x64\DLL_Output\Release\". 
InitializeBuildStatus: 
    Creating "x64\cryptdll\Release\cryptdll.unsuccessfulbuild" because "AlwaysCre 
    ate" was specified. 
CustomBuild: 
    Performing Custom Build Tools 
    Assembling: c:\cryptopp\x64dll.asm 
ClCompile: 
    c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\AMD64\CL.exe /c /Z 
    i /nologo /W4 /WX- /O2 /Ob2 /Oi /Oy /D NDEBUG /D CRYPTOPP_EXPORTS /D CRYPTOPP 
    _ENABLE_COMPLIANCE_WITH_FIPS_140_2=1 /D USE_PRECOMPILED_HEADERS /D _WINDLL /G 
    F /Gm- /EHsc /MT /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Yc"pch.h" /Fp" 
    x64\cryptdll\Release\cryptopp.pch" /Fo"x64\cryptdll\Release\\" /Fd"x64\cryptd 
    ll\Release\vc100.pdb" /Gd /TP /errorReport:none pch.cpp 
    pch.cpp 
    ... 

    <rest of the DLL is built> 

PostBuildEvent: 
    Description: Adding MAC to DLL 

      Win32\output\debug\cryptest.exe mac_dll "cryptopp\x64\DLL_Output\Rele 
    ase\cryptopp.dll" 
      IF %ERRORLEVEL% EQU 0 (echo mac done > "x64\DLL_Output\Release\"\cryp 
    topp.mac.done) 

    :VCEnd 
    The system cannot find the path specified. 
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(1 
13,5): error MSB3073: The command "\r [c:\cryptopp\cryptdll.vcxproj] 
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(1 
13,5): error MSB3073:   Win32\output\debug\cryptest.exe mac_dll "c:\crypt 
opp\x64\DLL_Output\Release\cryptopp.dll"\r [c:\cryptopp\cryptdll.vcxproj] 
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(1 
13,5): error MSB3073:   IF %ERRORLEVEL% EQU 0 (echo mac done > "x64\DLL_O 
utput\Release\"\cryptopp.mac.done)\r [c:\cryptopp\cryptdll.vcxproj] 
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(1 
13,5): error MSB3073:  \r [c:\cryptopp\cryptdll.vcxproj] 
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(1 
13,5): error MSB3073: :VCEnd" exited with code 3. [c:\cryptopp\cryptdll.vcxproj 
Done Building Project "c:\cryptopp\cryptdll.vcxproj" (build target(s)) -- FAILE 
D. 

Build FAILED. 

ответ

1

Когда я попытался преобразовать его в Task Вы имеете в виду Target, что это не то же самое, как Task: первый содержит последний.

Обратите внимание, что задача пропущена, как если бы ее не было. Ну, вы не говорите msbuild о том, что делать с целью, поэтому он не может знать, когда ее вызывать. Вы хотите, чтобы это вызвало перед сборкой, поэтому вы должны это выразить. Здесь атрибут BeforeTargets (документация в той же ссылке выше) является каноническим способом:

<Target Condition="!Exists('Win32\Output\Debug\cryptest.exe')" 
     Name="MAC tool" 
     BeforeTargets="Build"> 

Sidenote: зачем добавлять метки к цели, которая просто дублирует имя?

+0

Thanks @stijn. Позвольте мне задать немой вопрос, пока не придет моя копия [MSBuild Trickery: 99 способов сгибать двигатель сборки по вашей воле] (https://www.amazon.com/gp/product/061550907X). Как я могу выразить то, что Makefile будет называть *** предварительным условием ***? Это то, что нужно делать. Для полноты приведена справочная страница GNU Make на предварительных требованиях: [4.3 Типы предварительных условий] (https://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html). Если вы хотите посмеяться, попробуйте выполнить поиск [MSBuild предварительное условие] (https://www.google.com/search?q=MSBuild+prerequisite) и посмотрите на все нерелевантные результаты. – jww

+0

Еще раз спасибо @stijn. Я попытался удалить дубликат атрибута 'Name' *. Это приводит к *** «Обязательный атрибут« Имя »пуст или отсутствует в элементе . ***.Я также пробовал самое очевидное имя, но также приводит к ошибке: * 'Name =" cryptest.exe "' *. Если вам интересно, почему * «Label» * есть, документы MSBuild сказали мне, что они похожи на «отображаемые имена» * для таких инструментов, как IDE, поэтому они всегда должны присутствовать. Если их нет, мы рискуем отвечать на вопросы пользователей и отчеты об ошибках. – jww

+0

Предварительное условие будет выражено с использованием атрибута DependsOnTargets. Что касается дублирования: имя является обязательным атрибутом, а не ярлыком. Я не знаю, с какими документами вы ссылаетесь, но если там уже есть трудное требование для ярлыка, это не будет для целевых элементов, так как эти метки являются afaik, которые никогда не вываливаются в gui нигде, особенно не для пользовательских элементов, не добавленных ui, в первую очередь, это только случай для некоторых объектов Property/Item/ImportGroups. – stijn

 Смежные вопросы

  • Нет связанных вопросов^_^