У меня есть проект под названием cryptdll.vcxproj
. cryptdll зависит от артефактов из двух других проектов в решении. Другие проекты: cryptlib и cryptest. Для тех, кто интересуется компоновкой элементов в cryptdll, он находится по адресу cryptdll
.Преобразование объекта PreBuildEvent в цель с условием?
Зависимости несколько необычны и не так легко выражаются в редакторе Visual Studio. Они необычны, потому что политика требует, чтобы Win32\Output\Debug\cryptest.exe
всегда использовался для использования PostBuildEvent
cryptdll.
я обнаружил, что могу добавить следующее 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.
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
Еще раз спасибо @stijn. Я попытался удалить дубликат атрибута 'Name' *. Это приводит к *** «Обязательный атрибут« Имя »пуст или отсутствует в элементе. ***.Я также пробовал самое очевидное имя, но также приводит к ошибке: * 'Name =" cryptest.exe "' *. Если вам интересно, почему * «Label» * есть, документы MSBuild сказали мне, что они похожи на «отображаемые имена» * для таких инструментов, как IDE, поэтому они всегда должны присутствовать. Если их нет, мы рискуем отвечать на вопросы пользователей и отчеты об ошибках. –
jww
Предварительное условие будет выражено с использованием атрибута DependsOnTargets. Что касается дублирования: имя является обязательным атрибутом, а не ярлыком. Я не знаю, с какими документами вы ссылаетесь, но если там уже есть трудное требование для ярлыка, это не будет для целевых элементов, так как эти метки являются afaik, которые никогда не вываливаются в gui нигде, особенно не для пользовательских элементов, не добавленных ui, в первую очередь, это только случай для некоторых объектов Property/Item/ImportGroups. – stijn