我可以查看使用 MSBuild 实际执行的构建命令吗?
Posted
技术标签:
【中文标题】我可以查看使用 MSBuild 实际执行的构建命令吗?【英文标题】:Can I view what build commands are actually executed with MSBuild? 【发布时间】:2011-06-16 14:48:13 【问题描述】:我使用 MSBuild 来构建项目文件。 默认情况下,MSBuild 只是打印编译结果,但我需要检查正在执行的命令。
我可以查看实际执行了哪些构建命令吗?我想检查编译器选项和引用是否与csc
命令一起使用。
【问题讨论】:
对我来说,msbuild
默认打印所有csc
命令。
【参考方案1】:
您可以使用 /v[erbosity] 标志。我不知道您是否可以获得传递给 CSC 的标志列表,但如果您使用 /v:Detailed 或 /v:diagnostic,它将转储大量有关正在执行的目标、所有 MSBuild 变量及其值,以及所有已解析的引用程序集。
[edit:] 如果你寻找它,它看起来也会显示对 csc.exe 的命令行调用,即使在 /v:detailed 上也是如此。
【讨论】:
【参考方案2】:您可以将 Visual Studio 构建的输出设置为详细。 转到菜单工具 -> 选项 -> 项目和解决方案 -> 构建和运行。更改 MSBuild 项目构建输出详细程度选项,通常从默认的 Minimal 更改为 Normal、Detailed 或 Diagnostic。
【讨论】:
【参考方案3】:-
来自 Visual Studio 2019 命令提示符,
cd 目录_包含_my_sln,
删除所有对象文件和可执行文件(如果有),因为如果不这样做,MSBUILD 可能不会重新编译
msbuild /v:normal > msbuild.log
观察 msbuild.log 包含 CLCompile 和 Link:
ClCompile:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\CL.exe /c /IC:\Users\Administrator\Desktop\pdelib\test_pdelib\v7.8.3\VSE2019.16.11.4\..\..\src /IC:\Users\Administrator\Desktop\pdelib\test_pdelib\v7.8.3\VSE2019.16.11.4\..\..\..\..\pdelib\pdelib_v7.8.3\v7.8.3\msdos_mcn\vc140_64_md\core\include /IC:\Users\Administrator\Desktop\pdelib\test_pdelib\v7.8.3\VSE2019.16.11.4\..\..\..\..\pdelib\pdelib_v7.8.3\v7.8.3\msdos_mcn\vc140_64_md\step\include /IC:\Users\Administrator\Desktop\pdelib\test_pdelib\v7.8.3\VSE2019.16.11.4\..\..\..\..\pdelib\pdelib_v7.8.3\v7.8.3\msdos_mcn\vc140_64_md\iges\include /ZI /JMC /nologo /W3 /WX- /diagnostics:column /sdl /Od /D _DEBUG /D _CONSOLE /D _UNICODE /D UNICODE /Gm- /EHsc /RTC1 /MD /GS /fp:precise /permissive- /Zc:wchar_t /Zc:forScope /Zc:inline /Fo"x64\Debug\\" /Fd"x64\Debug\vc142.pdb" /external:W3 /Gd /TP /FC /errorReport:queue /wd4996 /wd4703 ..\..\src\test_pdelib.cpp ..\..\src\test_step.cpp
test_pdelib.cpp
test_step.cpp
Generating Code...
Link:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\link.exe /ERRORREPORT:QUEUE /OUT:"C:\Users\Administrator\Desktop\pdelib\test_pdelib\v7.8.3\VSE2019.16.11.4\x64\Debug\test_pdelib.exe" /INCREMENTAL /ILK:"x64\Debug\test_pdelib.ilk" /NOLOGO /LIBPATH:C:\Users\Administrator\Desktop\pdelib\test_pdelib\v7.8.3\VSE2019.16.11.4\..\..\..\pdelib_v7.8.3\v7.8.3\msdos_mcn\vc140_64_md\core\lib /LIBPATH:C:\Users\Administrator\Desktop\pdelib\test_pdelib\v7.8.3\VSE2019.16.11.4\..\..\..\pdelib_v7.8.3\v7.8.3\msdos_mcn\vc140_64_md\step\lib /LIBPATH:C:\Users\Administrator\Desktop\pdelib\test_pdelib\v7.8.3\VSE2019.16.11.4\..\..\..\pdelib_v7.8.3\v7.8.3\msdos_mcn\vc140_64_md\iges\lib libgdx.lib libpdx.lib libstep.lib libiges.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"C:\Users\Administrator\Desktop\pdelib\test_pdelib\v7.8.3\VSE2019.16.11.4\x64\Debug\test_pdelib.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:\Users\Administrator\Desktop\pdelib\test_pdelib\v7.8.3\VSE2019.16.11.4\x64\Debug\test_pdelib.lib" /MACHINE:X64 x64\Debug\test_pdelib.obj
x64\Debug\test_step.obj
test_pdelib.vcxproj -> C:\Users\Administrator\Desktop\pdelib\test_pdelib\v7.8.3\VSE2019.16.11.4\x64\Debug\test_pdelib.exe
【讨论】:
-fl
也会写入日志。默认名称是 msbuild.log :-) 可以使用 -flp
更改名称/位置。您还可以为日志文件设置与控制台不同的详细程度,例如-flp:LogFile=msbuild-detailed.log;Verbosity=diagnostic
.【参考方案4】:
在控制台上控制它的最细粒度的方法是使用
-consoleLoggerParameters:ShowCommandLine
又名-clp:ShowCommandLine
。作为文档explain, for VS2019:
默认控制台记录器处于正常冗长状态并包含摘要。
(Summary
也是一种可以打印或不打印的输出,与ShowCommandLine
属于同一类)
事实证明(请参阅下面的 VS 2019 实验),最小的 -v:m
详细级别抑制了工具的 stdout 输出(msbuild 横幅除外)和 cmd 回显。
在正常及以上详细度下,cmd echo 和 tool stdout 都使用 VS 2019 打印。但您可以通过添加 -clp:ShowCommandLine
将 echo 添加回 -v:m
。这实际上比正常的 msbuild 详细级别打印出更少的喋喋不休,尤其是来自 msbuild 本身。唉,你不能将 -clp:ShowCommandLine
与 -v:q
结合起来,以抑制工具的横幅,但让 cmd 得到回应; -v:q
仍然会打印横幅,但不会影响 -clp:ShowCommandLine
的效果。
我自己并没有构建太多 C# 项目,但问题下的评论(user202729 2018 年 2 月 25 日 15:35)是正确的,msbuild,至少来自 VS2019 的那个,将在正常的详细程度。
我使用最小的 msbuild C# 示例 provided by MS 进行了测试,从 x64 开发 cmd 提示符运行:
M:\tests\cs-build>msbuild helloworld.csproj -t:Build
Microsoft (R) Build Engine version 16.11.2+f32259642 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
Build started 1/16/2022 9:42:20 AM.
Project "M:\tests\cs-build\helloworld.csproj" on node 1 (Build target(s)).
Build:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current
\Bin\Roslyn\csc.exe /out:Helloworld.exe Helloworld.cs
CompilerServer: tool - using command line tool by design 'C:\Program Files (x
86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\Roslyn\csc.exe
' - 753a030a-3ca4-43b9-9e98-18d923493186
Done Building Project "M:\tests\cs-build\helloworld.csproj" (Build target(s)).
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.80
某些 VS 生成的构建文件可能会覆盖隐式默认值。作为记录,如果 MS 更改该示例,csproj 文件为:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Compile Include="helloworld.cs" />
</ItemGroup>
<Target Name="Build">
<Csc Sources="@(Compile)"/>
</Target>
</Project>
我无法完全找到记录在每个详细级别中包含哪些精确的输出内容集。有一个Q here 对此进行了讨论,但目前的答案只是重复了 MS 文档所说的内容,这还不够详细。
人们have discovered 的一件事是,来自 msbuild 调用的工具的 stdout 消息在最小详细级别被抑制,但在正常及更高级别打印。所以,我猜最小也会抑制 cmd echo ......而且确实如此:
M:\tests\cs-build>msbuild helloworld.csproj -t:Build -v:m
Microsoft (R) Build Engine version 16.11.2+f32259642 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
M:\tests\cs-build>
因此,您实际上可以通过使用-v:m -clp:ShowCommandLine
获得 cmd echo 但没有其他 msbuild 喋喋不休,除了错误和 msbuild 横幅:
M:\tests\cs-build>msbuild helloworld.csproj -t:Build -v:m -clp:ShowCommandLine
Microsoft (R) Build Engine version 16.11.2+f32259642 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current
\Bin\Roslyn\csc.exe /out:Helloworld.exe Helloworld.cs
唉,你不能将-clp:ShowCommandLine
与-v:q
结合起来,以抑制横幅但得到 cmd 回显; -v:q
仍会打印横幅,但不会影响 -clp:ShowCommandLine
的效果。
M:\tests\cs-build>msbuild helloworld.csproj -t:Build -v:q -clp:ShowCommandLine
Microsoft (R) Build Engine version 16.11.2+f32259642 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
M:\tests\cs-build>
您可以使用 -nologo
单独抑制 msbuild 横幅,因此 -v:m -clp:ShowCommandLine -nologo
是一个有效的组合。
M:\tests\cs-build>msbuild helloworld.csproj -t:Build -v:m -nologo -clp:ShowCommandLine
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current
\Bin\Roslyn\csc.exe /out:Helloworld.exe Helloworld.cs
M:\tests\cs-build>
测试minimal-ish native CPP example(我更感兴趣),我得到了类似的输出,这意味着默认情况下会打印命令行。
M:\tests\cpp-build>msbuild myproject.vcxproj /p:configuration=debug
Microsoft (R) Build Engine version 16.11.2+f32259642 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
Build started 1/16/2022 10:05:01 AM.
Project "M:\tests\cpp-build\myproject.vcxproj" on node 1 (default targets).
InitializeBuildStatus:
Touching "debug\myproject.tlog\unsuccessfulbuild".
ClCompile:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\1
4.29.30133\bin\HostX86\x86\CL.exe /c /Zi /nologo /W1 /WX- /diagnostics:column
/O2 /Oy- /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline
/Fo"debug\\" /Fd"debug\vc142.pdb" /external:W1 /Gd /TP /analyze- /FC /errorRe
port:queue main.cpp
main.cpp
Link:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\1
4.29.30133\bin\HostX86\x86\link.exe /ERRORREPORT:QUEUE /OUT:"M:\tests\cpp-bui
ld\debug\myproject.exe" /NOLOGO kernel32.lib user32.lib gdi32.lib winspool.li
b comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc3
2.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'
" /manifest:embed /DEBUG:FULL /PDB:"M:\tests\cpp-build\debug\myproject.pdb" /
TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"M:\tests\cpp-build\debug\myproject.li
b" /MACHINE:X86 /SAFESEH debug\main.obj
myproject.vcxproj -> M:\tests\cpp-build\debug\myproject.exe
FinalizeBuildStatus:
Deleting file "debug\myproject.tlog\unsuccessfulbuild".
Touching "debug\myproject.tlog\myproject.lastbuildstate".
Done Building Project "M:\tests\cpp-build\myproject.vcxproj" (default targets).
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:02.32
我不会在此处粘贴 .vcxproj
文件,因为它要长一些。
这个相当冗长的输出(包括 cmd 行)肯定不是我从典型 cmake 项目生成的此类文件的经验,尽管在对后者进行了一些测试后,cmake 默认使用... msbuild 默认冗长,所以包括cmd回显。我通过 cmake 生成的 vcxproj 从构建中为您节省了(甚至更长的)输出粘贴,但您可以在 https://pastebin.com/WQtbYeDE 上看到它。这是为之前的 MS C++ 示例制作的最小 CMakeLists.txt。
cmake_minimum_required(VERSION 3.10)
# set the project name
project(Tutorial)
# add the executable
add_executable(Tutorial main.cpp)
此外,我是否更直接地 msbuild 生成 cmake 生成的 .sln
而不是 cmake 生成的 .vcxproj
也没有区别。
TLDR:现在使用 msbuild 您必须关闭而不是打开 cmd echo;大多数工作流程的默认设置是打开的。不过,我还没有在(cmd echo)方面测试过 VS IDE 生成的文件。
【讨论】:
以上是关于我可以查看使用 MSBuild 实际执行的构建命令吗?的主要内容,如果未能解决你的问题,请参考以下文章
MSBuild:是不是可以在实际项目文件中指定项目构建依赖项?