添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
睿智的玉米  ·  CTest does not find ...·  5 天前    · 
低调的菠菜  ·  Build fails behind ...·  3 天前    · 
慷慨大方的镜子  ·  Godot 4.3.x github ...·  2 天前    · 
安静的松树  ·  ImportError: DLL load ...·  23 小时前    · 
帅气的小摩托  ·  How to Build ...·  6 小时前    · 
威武的蜡烛  ·  如何重置密码?·  3 周前    · 
深沉的松树  ·  毒舌律师 ...·  2 月前    · 

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Edit: See #27374 (comment) for investigation

Description

qiao@X64:~/work_qiao/dotnet-runtime-loongarch/.dotnet$ ./dotnet --info
.NET SDK (反映任何 global.json):
 Version:   6.0.108
 Commit:    4e3a463d2b
运行时环境:
 OS Name:     debian
 OS Version:  10
 OS Platform: Linux
 RID:         debian.10-x64
 Base Path:   /home/qiao/work_qiao/dotnet-runtime-loongarch/.dotnet/sdk/6.0.108/
global.json file:
  /home/qiao/work_qiao/dotnet-runtime-loongarch/global.json
Host:
  Version:      6.0.8
  Architecture: x64
  Commit:       55fb7ef977
.NET SDKs installed:
  6.0.108 [/home/qiao/work_qiao/dotnet-runtime-loongarch/.dotnet/sdk]
.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.8 [/home/qiao/work_qiao/dotnet-runtime-loongarch/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.8 [/home/qiao/work_qiao/dotnet-runtime-loongarch/.dotnet/shared/Microsoft.NETCore.App]
Download .NET:
  https://aka.ms/dotnet-download
Learn about .NET Runtimes and SDKs:
  https://aka.ms/dotnet/runtimes-sdk-info
----------------------------------
qiao@X64:~/work_qiao/dotnet-runtime-loongarch/.dotnet$  time ./dotnet build --help
Description:
  .NET 生成器
Usage:
  dotnet [options] build [<PROJECT | SOLUTION>...]
Arguments:
  <PROJECT | SOLUTION>  要操作的项目或解决方案文件。如果没有指定文件,则命令将在当前目录里搜索一个文件。
Options:
  --use-current-runtime                将当前运行时用作目标运行时。
  -f, --framework <FRAMEWORK>          要生成的目标框架。必须在项目文件中指定目标框架。
  -c, --configuration <CONFIGURATION>  用于生成项目的配置。大多数项目的默认值是 "Debug"。
  -r, --runtime <RUNTIME_IDENTIFIER>   要生成的目标运行时。
  --version-suffix <VERSION_SUFFIX>    设置生成项目时使用的 $(VersionSuffix) 属性的值。
  --no-restore                         生成前请勿还原项目。
  --interactive                        允许命令停止和等待用户输入或操作(例如,用以完成身份验证)。
  -v, --verbosity <LEVEL>              设置 MSBuild 详细程度。允许值为 q[uiet]、m[inimal]、n[ormal]、d[etailed] 和 diag[nostic]。
  --debug
  -o, --output <OUTPUT_DIR>            要放置生成项目的输出目录。
  --no-incremental                     请勿使用增量生成。
  --no-dependencies                    请勿生成项目到项目引用,仅生成指定项目。
  --nologo                             不显示启动版权标志或版权消息。
  --sc, --self-contained               随应用程序一起发布 .NET 运行时,这样就不需要在目标计算机上安装运行时。
                                       如果指定了运行时标识符,则默认值为 "true"。
  --no-self-contained                  将应用程序发布为依赖框架的应用程序。目标计算机上必须安装兼容的 .NET 运行时才能运行该应用程序。
  -a, --arch <arch>                    目标体系结构。
  --os <os>                            目标操作系统。
  -?, -h, --help                       显示命令行帮助。
real	0m0.520s
user	0m0.413s
sys	0m0.028s

while the .NET7 is slower,

qiao@X64:~/work_qiao/runtime$ .dotnet/dotnet --info
.NET SDK (反映任何 global.json):
 Version:   7.0.100-preview.7.22377.5
 Commit:    ba310d9309
运行时环境:
 OS Name:     debian
 OS Version:  10
 OS Platform: Linux
 RID:         debian.10-x64
 Base Path:   /home/qiao/work_qiao/runtime/.dotnet/sdk/7.0.100-preview.7.22377.5/
Host:
  Version:      7.0.0-preview.7.22375.6
  Architecture: x64
  Commit:       eecb028078
.NET SDKs installed:
  7.0.100-preview.7.22377.5 [/home/qiao/work_qiao/runtime/.dotnet/sdk]
.NET runtimes installed:
  Microsoft.AspNetCore.App 7.0.0-preview.7.22376.6 [/home/qiao/work_qiao/runtime/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 7.0.0-preview.7.22375.6 [/home/qiao/work_qiao/runtime/.dotnet/shared/Microsoft.NETCore.App]
Other architectures found:
Environment variables:
  Not set
global.json file:
  /home/qiao/work_qiao/runtime/global.json
Learn more:
  https://aka.ms/dotnet/info
Download .NET:
  https://aka.ms/dotnet/download
-----------------------------------------
qiao@X64:~/work_qiao/runtime$ time .dotnet/dotnet build --help
Description:
  .NET 生成器
Usage:
  dotnet build [<PROJECT | SOLUTION>...] [options]
Arguments:
  <PROJECT | SOLUTION>  要操作的项目或解决方案文件。如果没有指定文件,则命令将在当前目录里搜索一个文件。
Options:
  --use-current-runtime                将当前运行时用作目标运行时。
  -f, --framework <FRAMEWORK>          要生成的目标框架。必须在项目文件中指定目标框架。
  -c, --configuration <CONFIGURATION>  用于生成项目的配置。大多数项目的默认值是 "Debug"。
  -r, --runtime <RUNTIME_IDENTIFIER>   要生成的目标运行时。
  --version-suffix <VERSION_SUFFIX>    设置生成项目时使用的 $(VersionSuffix) 属性的值。
  --no-restore                         生成前请勿还原项目。
  --interactive                        允许命令停止和等待用户输入或操作(例如,用以完成身份验证)。
  -v, --verbosity <LEVEL>              设置 MSBuild 详细程度。允许值为 q[uiet]、m[inimal]、n[ormal]、d[etailed] 和 diag[nostic]。
  --debug
  -o, --output <OUTPUT_DIR>            要放置生成项目的输出目录。
  --no-incremental                     请勿使用增量生成。
  --no-dependencies                    请勿生成项目到项目引用,仅生成指定项目。
  --nologo                             不显示启动版权标志或版权消息。
  --sc, --self-contained               随应用程序一起发布 .NET 运行时,这样就不需要在目标计算机上安装运行时。
                                       如果指定了运行时标识符,则默认值为 "true"。
  --no-self-contained                  将应用程序发布为依赖框架的应用程序。目标计算机上必须安装兼容的 .NET 运行时才能运行该应用程序。
  -a, --arch <arch>                    目标体系结构。
  --os <os>                            目标操作系统。
  --disable-build-servers              Force the command to ignore any persistent build servers.
  -?, -h, --help                       显示命令行帮助。
          

There is a very insteresting thing:

If entered the .dotnet directory, it will be very fast.

qiao@X64:~/work_qiao/runtime/.dotnet$ time ./dotnet build --help
Description:
  .NET 生成器
Usage:
  dotnet build [<PROJECT | SOLUTION>...] [options]
Arguments:
  <PROJECT | SOLUTION>  要操作的项目或解决方案文件。如果没有指定文件,则命令将在当前目录里搜索一个文件。
Options:
  --use-current-runtime                将当前运行时用作目标运行时。
  -f, --framework <FRAMEWORK>          要生成的目标框架。必须在项目文件中指定目标框架。
  -c, --configuration <CONFIGURATION>  用于生成项目的配置。大多数项目的默认值是 "Debug"。
  -r, --runtime <RUNTIME_IDENTIFIER>   要生成的目标运行时。
  --version-suffix <VERSION_SUFFIX>    设置生成项目时使用的 $(VersionSuffix) 属性的值。
  --no-restore                         生成前请勿还原项目。
  --interactive                        允许命令停止和等待用户输入或操作(例如,用以完成身份验证)。
  -v, --verbosity <LEVEL>              设置 MSBuild 详细程度。允许值为 q[uiet]、m[inimal]、n[ormal]、d[etailed] 和 diag[nostic]。
  --debug
  -o, --output <OUTPUT_DIR>            要放置生成项目的输出目录。
  --no-incremental                     请勿使用增量生成。
  --no-dependencies                    请勿生成项目到项目引用,仅生成指定项目。
  --nologo                             不显示启动版权标志或版权消息。
  --sc, --self-contained               随应用程序一起发布 .NET 运行时,这样就不需要在目标计算机上安装运行时。
                                       如果指定了运行时标识符,则默认值为 "true"。
  --no-self-contained                  将应用程序发布为依赖框架的应用程序。目标计算机上必须安装兼容的 .NET 运行时才能运行该应用程序。
  -a, --arch <arch>                    目标体系结构。
  --os <os>                            目标操作系统。
  --disable-build-servers              Force the command to ignore any persistent build servers.
  -?, -h, --help                       显示命令行帮助。
real	0m0.261s
user	0m0.223s
sys	0m0.053s

While if outside of the .dotnet directory, it will be very slow.

qiao@X64:~/work_qiao/runtime$ time .dotnet/dotnet build --help
Description:
  .NET 生成器
Usage:
  dotnet build [<PROJECT | SOLUTION>...] [options]
Arguments:
  <PROJECT | SOLUTION>  要操作的项目或解决方案文件。如果没有指定文件,则命令将在当前目录里搜索一个文件。
Options:
  --use-current-runtime                将当前运行时用作目标运行时。
  -f, --framework <FRAMEWORK>          要生成的目标框架。必须在项目文件中指定目标框架。
  -c, --configuration <CONFIGURATION>  用于生成项目的配置。大多数项目的默认值是 "Debug"。
  -r, --runtime <RUNTIME_IDENTIFIER>   要生成的目标运行时。
  --version-suffix <VERSION_SUFFIX>    设置生成项目时使用的 $(VersionSuffix) 属性的值。
  --no-restore                         生成前请勿还原项目。
  --interactive                        允许命令停止和等待用户输入或操作(例如,用以完成身份验证)。
  -v, --verbosity <LEVEL>              设置 MSBuild 详细程度。允许值为 q[uiet]、m[inimal]、n[ormal]、d[etailed] 和 diag[nostic]。
  --debug
  -o, --output <OUTPUT_DIR>            要放置生成项目的输出目录。
  --no-incremental                     请勿使用增量生成。
  --no-dependencies                    请勿生成项目到项目引用,仅生成指定项目。
  --nologo                             不显示启动版权标志或版权消息。
  --sc, --self-contained               随应用程序一起发布 .NET 运行时,这样就不需要在目标计算机上安装运行时。
                                       如果指定了运行时标识符,则默认值为 "true"。
  --no-self-contained                  将应用程序发布为依赖框架的应用程序。目标计算机上必须安装兼容的 .NET 运行时才能运行该应用程序。
  -a, --arch <arch>                    目标体系结构。
  --os <os>                            目标操作系统。
  --disable-build-servers              Force the command to ignore any persistent build servers.
  -?, -h, --help                       显示命令行帮助。

There is a very insteresting thing:

If entered the .dotnet directory, it will be very fast.

qiao@X64:~/work_qiao/runtime/.dotnet$ time ./dotnet build --help
Description:
  .NET 生成器
Usage:
  dotnet build [<PROJECT | SOLUTION>...] [options]
Arguments:
  <PROJECT | SOLUTION>  要操作的项目或解决方案文件。如果没有指定文件,则命令将在当前目录里搜索一个文件。
Options:
  --use-current-runtime                将当前运行时用作目标运行时。
  -f, --framework <FRAMEWORK>          要生成的目标框架。必须在项目文件中指定目标框架。
  -c, --configuration <CONFIGURATION>  用于生成项目的配置。大多数项目的默认值是 "Debug"。
  -r, --runtime <RUNTIME_IDENTIFIER>   要生成的目标运行时。
  --version-suffix <VERSION_SUFFIX>    设置生成项目时使用的 $(VersionSuffix) 属性的值。
  --no-restore                         生成前请勿还原项目。
  --interactive                        允许命令停止和等待用户输入或操作(例如,用以完成身份验证)。
  -v, --verbosity <LEVEL>              设置 MSBuild 详细程度。允许值为 q[uiet]、m[inimal]、n[ormal]、d[etailed] 和 diag[nostic]。
  --debug
  -o, --output <OUTPUT_DIR>            要放置生成项目的输出目录。
  --no-incremental                     请勿使用增量生成。
  --no-dependencies                    请勿生成项目到项目引用,仅生成指定项目。
  --nologo                             不显示启动版权标志或版权消息。
  --sc, --self-contained               随应用程序一起发布 .NET 运行时,这样就不需要在目标计算机上安装运行时。
                                       如果指定了运行时标识符,则默认值为 "true"。
  --no-self-contained                  将应用程序发布为依赖框架的应用程序。目标计算机上必须安装兼容的 .NET 运行时才能运行该应用程序。
  -a, --arch <arch>                    目标体系结构。
  --os <os>                            目标操作系统。
  --disable-build-servers              Force the command to ignore any persistent build servers.
  -?, -h, --help                       显示命令行帮助。
real	0m0.261s
user	0m0.223s
sys	0m0.053s

While if outside of the .dotnet directory, it will be very slow.

qiao@X64:~/work_qiao/runtime$ time .dotnet/dotnet build --help
Description:
  .NET 生成器
Usage:
  dotnet build [<PROJECT | SOLUTION>...] [options]
Arguments:
  <PROJECT | SOLUTION>  要操作的项目或解决方案文件。如果没有指定文件,则命令将在当前目录里搜索一个文件。
Options:
  --use-current-runtime                将当前运行时用作目标运行时。
  -f, --framework <FRAMEWORK>          要生成的目标框架。必须在项目文件中指定目标框架。
  -c, --configuration <CONFIGURATION>  用于生成项目的配置。大多数项目的默认值是 "Debug"。
  -r, --runtime <RUNTIME_IDENTIFIER>   要生成的目标运行时。
  --version-suffix <VERSION_SUFFIX>    设置生成项目时使用的 $(VersionSuffix) 属性的值。
  --no-restore                         生成前请勿还原项目。
  --interactive                        允许命令停止和等待用户输入或操作(例如,用以完成身份验证)。
  -v, --verbosity <LEVEL>              设置 MSBuild 详细程度。允许值为 q[uiet]、m[inimal]、n[ormal]、d[etailed] 和 diag[nostic]。
  --debug
  -o, --output <OUTPUT_DIR>            要放置生成项目的输出目录。
  --no-incremental                     请勿使用增量生成。
  --no-dependencies                    请勿生成项目到项目引用,仅生成指定项目。
  --nologo                             不显示启动版权标志或版权消息。
  --sc, --self-contained               随应用程序一起发布 .NET 运行时,这样就不需要在目标计算机上安装运行时。
                                       如果指定了运行时标识符,则默认值为 "true"。
  --no-self-contained                  将应用程序发布为依赖框架的应用程序。目标计算机上必须安装兼容的 .NET 运行时才能运行该应用程序。
  -a, --arch <arch>                    目标体系结构。
  --os <os>                            目标操作系统。
  --disable-build-servers              Force the command to ignore any persistent build servers.
  -?, -h, --help                       显示命令行帮助。
sys	0m7.146s

This only happens within the runtime directory while includes the global.json.
If deleting the global.json, it will be normal.

Tagging subscribers to this area: @vitek-karas, @agocke, @VSadov
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

qiao@X64:~/work_qiao/dotnet-runtime-loongarch/.dotnet$ ./dotnet --info
.NET SDK (反映任何 global.json):
 Version:   6.0.108
 Commit:    4e3a463d2b
运行时环境:
 OS Name:     debian
 OS Version:  10
 OS Platform: Linux
 RID:         debian.10-x64
 Base Path:   /home/qiao/work_qiao/dotnet-runtime-loongarch/.dotnet/sdk/6.0.108/
global.json file:
  /home/qiao/work_qiao/dotnet-runtime-loongarch/global.json
Host:
  Version:      6.0.8
  Architecture: x64
  Commit:       55fb7ef977
.NET SDKs installed:
  6.0.108 [/home/qiao/work_qiao/dotnet-runtime-loongarch/.dotnet/sdk]
.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.8 [/home/qiao/work_qiao/dotnet-runtime-loongarch/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.8 [/home/qiao/work_qiao/dotnet-runtime-loongarch/.dotnet/shared/Microsoft.NETCore.App]
Download .NET:
  https://aka.ms/dotnet-download
Learn about .NET Runtimes and SDKs:
  https://aka.ms/dotnet/runtimes-sdk-info
----------------------------------
qiao@X64:~/work_qiao/dotnet-runtime-loongarch/.dotnet$  time ./dotnet build --help
Description:
  .NET 生成器
Usage:
  dotnet [options] build [<PROJECT | SOLUTION>...]
Arguments:
  <PROJECT | SOLUTION>  要操作的项目或解决方案文件。如果没有指定文件,则命令将在当前目录里搜索一个文件。
Options:
  --use-current-runtime                将当前运行时用作目标运行时。
  -f, --framework <FRAMEWORK>          要生成的目标框架。必须在项目文件中指定目标框架。
  -c, --configuration <CONFIGURATION>  用于生成项目的配置。大多数项目的默认值是 "Debug"。
  -r, --runtime <RUNTIME_IDENTIFIER>   要生成的目标运行时。
  --version-suffix <VERSION_SUFFIX>    设置生成项目时使用的 $(VersionSuffix) 属性的值。
  --no-restore                         生成前请勿还原项目。
  --interactive                        允许命令停止和等待用户输入或操作(例如,用以完成身份验证)。
  -v, --verbosity <LEVEL>              设置 MSBuild 详细程度。允许值为 q[uiet]、m[inimal]、n[ormal]、d[etailed] 和 diag[nostic]。
  --debug
  -o, --output <OUTPUT_DIR>            要放置生成项目的输出目录。
  --no-incremental                     请勿使用增量生成。
  --no-dependencies                    请勿生成项目到项目引用,仅生成指定项目。
  --nologo                             不显示启动版权标志或版权消息。
  --sc, --self-contained               随应用程序一起发布 .NET 运行时,这样就不需要在目标计算机上安装运行时。
                                       如果指定了运行时标识符,则默认值为 "true"。
  --no-self-contained                  将应用程序发布为依赖框架的应用程序。目标计算机上必须安装兼容的 .NET 运行时才能运行该应用程序。
  -a, --arch <arch>                    目标体系结构。
  --os <os>                            目标操作系统。
  -?, -h, --help                       显示命令行帮助。
real	0m0.520s
user	0m0.413s
sys	0m0.028s

while the .NET7 is slower,

qiao@X64:~/work_qiao/runtime$ .dotnet/dotnet --info
.NET SDK (反映任何 global.json):
 Version:   7.0.100-preview.7.22377.5
 Commit:    ba310d9309
运行时环境:
 OS Name:     debian
 OS Version:  10
 OS Platform: Linux
 RID:         debian.10-x64
 Base Path:   /home/qiao/work_qiao/runtime/.dotnet/sdk/7.0.100-preview.7.22377.5/
Host:
  Version:      7.0.0-preview.7.22375.6
  Architecture: x64
  Commit:       eecb028078
.NET SDKs installed:
  7.0.100-preview.7.22377.5 [/home/qiao/work_qiao/runtime/.dotnet/sdk]
.NET runtimes installed:
  Microsoft.AspNetCore.App 7.0.0-preview.7.22376.6 [/home/qiao/work_qiao/runtime/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 7.0.0-preview.7.22375.6 [/home/qiao/work_qiao/runtime/.dotnet/shared/Microsoft.NETCore.App]
Other architectures found:
Environment variables:
  Not set
global.json file:
  /home/qiao/work_qiao/runtime/global.json
Learn more:
  https://aka.ms/dotnet/info
Download .NET:
  https://aka.ms/dotnet/download
-----------------------------------------
qiao@X64:~/work_qiao/runtime$ time .dotnet/dotnet build --help
Description:
  .NET 生成器
Usage:
  dotnet build [<PROJECT | SOLUTION>...] [options]
Arguments:
  <PROJECT | SOLUTION>  要操作的项目或解决方案文件。如果没有指定文件,则命令将在当前目录里搜索一个文件。
Options:
  --use-current-runtime                将当前运行时用作目标运行时。
  -f, --framework <FRAMEWORK>          要生成的目标框架。必须在项目文件中指定目标框架。
  -c, --configuration <CONFIGURATION>  用于生成项目的配置。大多数项目的默认值是 "Debug"。
  -r, --runtime <RUNTIME_IDENTIFIER>   要生成的目标运行时。
  --version-suffix <VERSION_SUFFIX>    设置生成项目时使用的 $(VersionSuffix) 属性的值。
  --no-restore                         生成前请勿还原项目。
  --interactive                        允许命令停止和等待用户输入或操作(例如,用以完成身份验证)。
  -v, --verbosity <LEVEL>              设置 MSBuild 详细程度。允许值为 q[uiet]、m[inimal]、n[ormal]、d[etailed] 和 diag[nostic]。
  --debug
  -o, --output <OUTPUT_DIR>            要放置生成项目的输出目录。
  --no-incremental                     请勿使用增量生成。
  --no-dependencies                    请勿生成项目到项目引用,仅生成指定项目。
  --nologo                             不显示启动版权标志或版权消息。
  --sc, --self-contained               随应用程序一起发布 .NET 运行时,这样就不需要在目标计算机上安装运行时。
                                       如果指定了运行时标识符,则默认值为 "true"。
  --no-self-contained                  将应用程序发布为依赖框架的应用程序。目标计算机上必须安装兼容的 .NET 运行时才能运行该应用程序。
  -a, --arch <arch>                    目标体系结构。
  --os <os>                            目标操作系统。
  --disable-build-servers              Force the command to ignore any persistent build servers.
  -?, -h, --help                       显示命令行帮助。
          

@shushanhf do you see the same slower execution with commands like dotnet --info (or dotnet --help or dotnet new --help) or is it only dotnet build --help? From the runtime host side, we look at the global.json the same way in all those cases, so I'm wondering if there's something with the SDK command handling itself.

Could you also share the contents of your global.json?

I don't think we ended up changing how we handle global.json in .NET 7 (although there were definitely discussions about improvements). We did disable multi-level lookup, but that was Windows-only behaviour to begin with.

Could you also share the contents of your global.json?

This file is within the runtime, and both runtime6.0 and runtime7.0 have this interesting thing.

@shushanhf do you see the same slower execution with commands like dotnet --info (or dotnet --help or dotnet new --help) or is it only dotnet build --help?

The dotnet --help and dotnet new --help are normal, the dotnet build --help and dotnet run --help had this interesting thing.

From the runtime host side, we look at the global.json the same way in all those cases, so I'm wondering if there's something with the SDK command handling itself.

#27374

You must be under the root directory of the runtime project and you had downloaded the SDK, and then run the command time .dotnet/dotnet build --help.
If you changed the directory, for example cd .. which changed to the parent directory, the command time ./runtime/.dotnet/dotnet build --help is very fast.

Ah, I missed that you were seeing this in both .NET 6 and 7.

The dotnet --help and dotnet new --help are normal, the dotnet build --help and dotnet run --help had this interesting thing.

That definitely makes me think there is something with the SDK command handling itself.

Could you try setting the environment variables:

DOTNET_CLI_PERF_LOG=1
DOTNET_PERFLOG_DIR=<path_to_directory_for_logs>

@marcpopMSFT @baronfel Is there a better/recommended way and instructions for collecting information for SDK command perf?

I tried to make a simple repro, but did not observe this behaviour. This is my understanding of the scenario - please let me know if I have something wrong.

Created a directory with this layout:

.dotnet/
  dotnet
  [layout of a downloaded .NET SDK]
global.json

Where the .NET SDK is a downloaded/unzipped .NET 7 Preview 7 and global.json is copied from https://github.com/dotnet/runtime/blob/main/global.json

  • Running from within the .dotnet directory
  • These are all normal:
    dotnet --info
    dotnet --help
    dotnet new --help
    dotnet build --help
    dotnet run --help
              

    This is due to some SDK commands doing a project evaluation - including resolving msbuild SDKs based on a global.json - just to print their help. When the command was run from the .dotnet directory, there is no project in the working directory to evaluate, so it was fine.

    It is triggered by the command completion for the framework option:
    sdk/src/Cli/dotnet/commands/dotnet-complete/Complete.cs Lines 22 to 33 7e62e8d

    Running --help for any command using that would hit this issue, including:

    dotnet build
    dotnet clean
    dotnet publish
    dotnet run
    dotnet store
    dotnet test
    dotnet add reference
    

    Call stack:

    > Microsoft.Build.NuGetSdkResolver.dll!Microsoft.Build.NuGetSdkResolver.NuGetSdkResolver.Resolve(Microsoft.Build.Framework.SdkReference sdkReference, Microsoft.Build.Framework.SdkResolverContext resolverContext, Microsoft.Build.Framework.SdkResultFactory factory)
      Microsoft.Build.dll!Microsoft.Build.BackEnd.SdkResolution.SdkResolverService.TryResolveSdkUsingSpecifiedResolvers(System.Collections.Generic.IList<Microsoft.Build.Framework.SdkResolver> resolvers, int submissionId, Microsoft.Build.Framework.SdkReference sdk, Microsoft.Build.BackEnd.Logging.LoggingContext loggingContext, Microsoft.Build.Construction.ElementLocation sdkReferenceLocation, string solutionPath, string projectPath, bool interactive, bool isRunningInVisualStudio, out Microsoft.Build.BackEnd.SdkResolution.SdkResult sdkResult)
      Microsoft.Build.dll!Microsoft.Build.BackEnd.SdkResolution.SdkResolverService.ResolveSdkUsingResolversWithPatternsFirst(int submissionId, Microsoft.Build.Framework.SdkReference sdk, Microsoft.Build.BackEnd.Logging.LoggingContext loggingContext, Microsoft.Build.Construction.ElementLocation sdkReferenceLocation, string solutionPath, string projectPath, bool interactive, bool isRunningInVisualStudio)
      Microsoft.Build.dll!Microsoft.Build.BackEnd.SdkResolution.SdkResolverService.ResolveSdk(int submissionId, Microsoft.Build.Framework.SdkReference sdk, Microsoft.Build.BackEnd.Logging.LoggingContext loggingContext, Microsoft.Build.Construction.ElementLocation sdkReferenceLocation, string solutionPath, string projectPath, bool interactive, bool isRunningInVisualStudio)
      Microsoft.Build.dll!Microsoft.Build.BackEnd.SdkResolution.CachingSdkResolverService.ResolveSdk.AnonymousMethod__2()
      System.Private.CoreLib.dll!System.Lazy<Microsoft.Build.BackEnd.SdkResolution.SdkResult>.ViaFactory(System.Threading.LazyThreadSafetyMode mode)
      System.Private.CoreLib.dll!System.Lazy<Microsoft.Build.BackEnd.SdkResolution.SdkResult>.ExecutionAndPublication(System.LazyHelper executionAndPublication, bool useDefaultConstructor)
      System.Private.CoreLib.dll!System.Lazy<Microsoft.Build.BackEnd.SdkResolution.SdkResult>.CreateValue()
      Microsoft.Build.dll!Microsoft.Build.BackEnd.SdkResolution.CachingSdkResolverService.ResolveSdk(int submissionId, Microsoft.Build.Framework.SdkReference sdk, Microsoft.Build.BackEnd.Logging.LoggingContext loggingContext, Microsoft.Build.Construction.ElementLocation sdkReferenceLocation, string solutionPath, string projectPath, bool interactive, bool isRunningInVisualStudio)
      Microsoft.Build.dll!Microsoft.Build.Evaluation.Evaluator<Microsoft.Build.Evaluation.ProjectProperty, Microsoft.Build.Evaluation.ProjectItem, Microsoft.Build.Evaluation.ProjectMetadata, Microsoft.Build.Evaluation.ProjectItemDefinition>.ExpandAndLoadImportsFromUnescapedImportExpressionConditioned(string directoryOfImportingFile, Microsoft.Build.Construction.ProjectImportElement importElement, out System.Collections.Generic.List<Microsoft.Build.Construction.ProjectRootElement> projects, out Microsoft.Build.BackEnd.SdkResolution.SdkResult sdkResult, bool throwOnFileNotExistsError)
      Microsoft.Build.dll!Microsoft.Build.Evaluation.Evaluator<Microsoft.Build.Evaluation.ProjectProperty, Microsoft.Build.Evaluation.ProjectItem, Microsoft.Build.Evaluation.ProjectMetadata, Microsoft.Build.Evaluation.ProjectItemDefinition>.ExpandAndLoadImports(string directoryOfImportingFile, Microsoft.Build.Construction.ProjectImportElement importElement, out Microsoft.Build.BackEnd.SdkResolution.SdkResult sdkResult)
      Microsoft.Build.dll!Microsoft.Build.Evaluation.Evaluator<Microsoft.Build.Evaluation.ProjectProperty, Microsoft.Build.Evaluation.ProjectItem, Microsoft.Build.Evaluation.ProjectMetadata, Microsoft.Build.Evaluation.ProjectItemDefinition>.EvaluateImportElement(string directoryOfImportingFile, Microsoft.Build.Construction.ProjectImportElement importElement)
      Microsoft.Build.dll!Microsoft.Build.Evaluation.Evaluator<Microsoft.Build.Evaluation.ProjectProperty, Microsoft.Build.Evaluation.ProjectItem, Microsoft.Build.Evaluation.ProjectMetadata, Microsoft.Build.Evaluation.ProjectItemDefinition>.PerformDepthFirstPass(Microsoft.Build.Construction.ProjectRootElement currentProjectOrImport)
      Microsoft.Build.dll!Microsoft.Build.Evaluation.Evaluator<Microsoft.Build.Evaluation.ProjectProperty, Microsoft.Build.Evaluation.ProjectItem, Microsoft.Build.Evaluation.ProjectMetadata, Microsoft.Build.Evaluation.ProjectItemDefinition>.Evaluate()
      Microsoft.Build.dll!Microsoft.Build.Evaluation.Evaluator<Microsoft.Build.Evaluation.ProjectProperty, Microsoft.Build.Evaluation.ProjectItem, Microsoft.Build.Evaluation.ProjectMetadata, Microsoft.Build.Evaluation.ProjectItemDefinition>.Evaluate(Microsoft.Build.Evaluation.IEvaluatorData<Microsoft.Build.Evaluation.ProjectProperty, Microsoft.Build.Evaluation.ProjectItem, Microsoft.Build.Evaluation.ProjectMetadata, Microsoft.Build.Evaluation.ProjectItemDefinition> data, Microsoft.Build.Evaluation.Project project, Microsoft.Build.Construction.ProjectRootElement root, Microsoft.Build.Evaluation.ProjectLoadSettings loadSettings, int maxNodeCount, Microsoft.Build.Collections.PropertyDictionary<Microsoft.Build.Execution.ProjectPropertyInstance> environmentProperties, Microsoft.Build.BackEnd.Logging.ILoggingService loggingService, Microsoft.Build.Evaluation.IItemFactory<Microsoft.Build.Evaluation.ProjectItem, Microsoft.Build.Evaluation.ProjectItem> itemFactory, Microsoft.Build.Evaluation.IToolsetProvider toolsetP
    rovider, Microsoft.Build.Evaluation.ProjectRootElementCacheBase projectRootElementCache, Microsoft.Build.Framework.BuildEventContext buildEventContext, Microsoft.Build.BackEnd.SdkResolution.ISdkResolverService sdkResolverService, int submissionId, Microsoft.Build.Evaluation.Context.EvaluationContext evaluationContext, bool interactive)
      Microsoft.Build.dll!Microsoft.Build.Evaluation.Project.ProjectImpl.Reevaluate(Microsoft.Build.BackEnd.Logging.ILoggingService loggingServiceForEvaluation, Microsoft.Build.Evaluation.ProjectLoadSettings loadSettings, Microsoft.Build.Evaluation.Context.EvaluationContext evaluationContext)
      Microsoft.Build.dll!Microsoft.Build.Evaluation.Project.ProjectImpl.ReevaluateIfNecessary(Microsoft.Build.BackEnd.Logging.ILoggingService loggingServiceForEvaluation, Microsoft.Build.Evaluation.ProjectLoadSettings loadSettings, Microsoft.Build.Evaluation.Context.EvaluationContext evaluationContext)
      Microsoft.Build.dll!Microsoft.Build.Evaluation.Project.ProjectImpl.Initialize(System.Collections.Generic.IDictionary<string, string> globalProperties, string toolsVersion, string subToolsetVersion, Microsoft.Build.Evaluation.ProjectLoadSettings loadSettings, Microsoft.Build.Evaluation.Context.EvaluationContext evaluationContext)
      Microsoft.Build.dll!Microsoft.Build.Evaluation.Project.Project(string projectFile, System.Collections.Generic.IDictionary<string, string> globalProperties, string toolsVersion, string subToolsetVersion, Microsoft.Build.Evaluation.ProjectCollection projectCollection, Microsoft.Build.Evaluation.ProjectLoadSettings loadSettings, Microsoft.Build.Evaluation.Context.EvaluationContext evaluationContext, Microsoft.Build.FileSystem.IDirectoryCacheFactory directoryCacheFactory)
      Microsoft.Build.dll!Microsoft.Build.Evaluation.ProjectCollection.LoadProject(string fileName, System.Collections.Generic.IDictionary<string, string> globalProperties, string toolsVersion)
      dotnet.dll!Microsoft.DotNet.Tools.MsbuildProject.GetEvaluatedProject()
      dotnet.dll!Microsoft.DotNet.Tools.MsbuildProject.GetTargetFrameworks()
      dotnet.dll!Microsoft.DotNet.Cli.Complete.get_TargetFrameworksFromProjectFile.AnonymousMethod__2_0(System.CommandLine.Completions.CompletionContext _context)
      System.Linq.dll!System.Linq.Enumerable.SelectManySingleSelectorIterator<System.CommandLine.Completions.ICompletionSource, System.CommandLine.Completions.CompletionItem>.MoveNext()
      System.Private.CoreLib.dll!System.Collections.Generic.HashSet<System.CommandLine.Completions.CompletionItem>.UnionWith(System.Collections.Generic.IEnumerable<System.CommandLine.Completions.CompletionItem> other)
      System.Private.CoreLib.dll!System.Collections.Generic.HashSet<System.CommandLine.Completions.CompletionItem>.HashSet(System.Collections.Generic.IEnumerable<System.CommandLine.Completions.CompletionItem> collection, System.Collections.Generic.IEqualityComparer<System.CommandLine.Completions.CompletionItem> comparer)
      System.Linq.dll!System.Linq.Enumerable.DistinctIterator<System.CommandLine.Completions.CompletionItem>.ToArray()
      System.Linq.dll!System.Linq.Buffer<System.CommandLine.Completions.CompletionItem>.Buffer(System.Collections.Generic.IEnumerable<System.CommandLine.Completions.CompletionItem> source)
      System.Linq.dll!System.Linq.OrderedEnumerable<System.CommandLine.Completions.CompletionItem>.GetEnumerator()
      System.Linq.dll!System.Linq.Enumerable.SelectIPartitionIterator<System.CommandLine.Completions.CompletionItem, string>.LazyToArray()
      System.Linq.dll!System.Linq.Enumerable.SelectIPartitionIterator<System.CommandLine.Completions.CompletionItem, string>.ToArray()
      System.CommandLine.dll!System.CommandLine.Help.HelpBuilder.Default.GetArgumentUsageLabel(System.CommandLine.Argument argument)
      System.CommandLine.dll!System.CommandLine.Help.HelpBuilder.Default.GetIdentifierSymbolUsageLabel(System.CommandLine.IdentifierSymbol symbol, System.CommandLine.Help.HelpContext context)
      System.CommandLine.dll!System.CommandLine.Help.HelpBuilder.GetTwoColumnRow.__GetIdentifierSymbolRow|0()
      System.CommandLine.dll!System.CommandLine.Help.HelpBuilder.GetTwoColumnRow(System.CommandLine.Symbol symbol, System.CommandLine.Help.HelpContext context)
      System.CommandLine.dll!System.CommandLine.Help.HelpBuilder.Default.OptionsSection.AnonymousMethod__10_0(System.CommandLine.Help.HelpContext ctx)
      System.CommandLine.dll!System.CommandLine.Help.HelpBuilder.Write(System.CommandLine.Help.HelpContext context)
      System.CommandLine.dll!System.CommandLine.Invocation.InvocationPipeline.GetExitCode(System.CommandLine.Invocation.InvocationContext context)
      System.CommandLine.dll!System.CommandLine.Invocation.InvocationPipeline.Invoke.__FullInvocationChain|3_0(System.CommandLine.Invocation.InvocationContext context)
      dotnet.dll!Microsoft.DotNet.Cli.Program.ProcessArgs(string[] args, System.TimeSpan startupTime, Microsoft.DotNet.Cli.Telemetry.ITelemetry telemetryClient)
      dotnet.dll!Microsoft.DotNet.Cli.Program.Main(string[] args)
    

    Moving to dotnet/sdk

    dotnet build --help is slower than .NET6 dotnet build --help results in project evaluation and msbuild SDK resolution Aug 23, 2022

    HelpBuilder.Default.GetArgumentUsageLabel wastes time by querying the completions even though it will ignore them in this case. That could be fixed in dotnet/command-line-api, by moving the var completions initialization to an else branch:

    https://github.com/dotnet/command-line-api/blob/209b724a3c843253d3071e8348c353b297b0b8b5/src/System.CommandLine/Help/HelpBuilder.Default.cs#L66-L87

    This scenario was not optimized in dotnet/command-line-api#1367 when HelpBuilder was changed to display Argument.HelpName. Filed as dotnet/command-line-api#2038.

    If Argument.HelpName was set, HelpBuilder.Default calls GetCompletions but ignores the result dotnet/command-line-api#2038
  •