1

写这篇文章的动机是什么,为什么要去研究构建工具 (翻看 .csproj) ,用 Visual Studio IDE 新建 C# 项目,点击 build 运行,不就可以了吗?

答:参考 Thirty_minutes_before_coding 。我把它称作 “工程化”。工程化的开发 不仅仅是打开 IDE 新建项目就开写 就完事了的。它需要遵循一个清晰的范式,每一个部件都有自己的作用。它有自己的意义,每一个部件也有自己的意义 (完成一个东西的办法 有很多,有一个清晰的规划可以帮助你完成得更快)。

你应该有理由用任何你喜欢的编辑器去写代码。它本身就是 源文件+编译过程+编译结果 而已,你需要编辑的仅仅是源文件,任何一个文本编辑器都可以。IDE 不是唯一选项。( 虽然在实际的大项目中,你会用到 IDE 因为它可以帮你 “省力” ,但目前 一些小项目里 你不需要 IDE 去隐藏一些东西、过程,命令行可以看出所有发生的事是什么。而且 让项目跑起来,用正确的命令行足矣:如果不足 则是命令不对,应该去找正确的命令,而不是换用 IDE 接受它的黑箱式的 “省力”:不知道背后发生了什么 就很不爽。这其实很没有意思(同样的结果 由2种方式办到了),但这是一种执念 ) (然而并没有什么卵用,听起来完全像是心理作用) (主要还是为了 学习 MSBuild (以及 csproj) 1 2 3)

答:命令行可以替代 IDE。 JavaScript 的开发,仅仅是各种工具链就可以了,构建工具很完备 都是一个个命令行里的命令 (不需要 IDE)。Java 的开发,也可以不用 IDE,直接是 javac 和 java 命令就 OK 了。那么面对 C# 的开发,也可以建立项目。当然,显然 建立项目:从 Visual Studio 建立项目,不过要求填入项目名字然后填进去一些模板最后得到了项目目录和里面的文件,命令行当然理应可以做到;运行项目:不过是 确定 target 之后,按照构建文件去构建就完事了,命令行当然理应可以做到。
要考虑的东西:

  • 一个文本文档,一些命令行,就可以开启项目了
  • 用命令行开启的项目,应该是可以在 IDE 里打开的,反之亦然,这里是有兼容性
  • 用全命令行的操作 代替IDE ,反正得到最后的项目文件(目录结构)就可以了。
  • 项目最后的运行:构建 编译 运行,保证最后程序的正确运行 (通过命令行 or IDE,几个命令行能搞定的事情 就不劳 IDE 的大驾了 )
  • 项目最初的建立:不过是一些文件生成器而已 得到一个目录结构
  • 粒度:到命令行为止
  • 兼容性:网上可以下载一些 C# 项目,显然 它们是 IDE 构建的,我要想办法把它们用命令行的方式运行;同时,我用命令行建立的 C# 项目,可以保证用 IDE 来打开

构建工具是什么?
构建工具[1] 会按照 构建文档[2] 来 build 出二进制,方便运行。

基本感受:就功能而言,dotnet run (含 dotnet restore + dotnet build + dotnet run -f netstandard2.0)msbuild + mono 123.exe 理论上 应该是相同的效果 [1],但实际上 mono系的还是好用,尤其是可以避免很多兼容性的问题。包括但不限于 (这些都是 dotnet run -f netstandard2.0 遇到的问题)

  • /usr/local/share/dotnet/sdk/3.0.100/Microsoft.Common.CurrentVersion.targets(1175,5): error MSB3644: The reference assemblies for .NETFramework,Version=v4.7.2 were not found. To resolve this, install the Developer Pack (SDK/Targeting Pack) for this framework version or retarget your application. You can download .NET Framework Developer Packs at https://aka.ms/msbuild/develo... [Demo12.GTK/Demo12.GTK.csproj] // 解决办法 export FrameworkPathOverride
  • Unable to run your project. Ensure you have a runnable project type and ensure 'dotnet run' supports this project. A runnable project should target a runnable TFM (for instance, netcoreapp2.0) and have OutputType 'Exe'. The current OutputType is 'WinExe'. // 解决办法 修改 csproj 改为 Exe
  • error CS0246: The type or namespace name 'Gtk' could not be found (are you missing a using directive or an assembly reference?) [Demo12.GTK/Demo12.GTK.csproj] // 解决办法未知

-
-

构建文件:

  • 简单的构建工具:类似 C++ 的 makefile
  • 复杂的构建工具: .csproj (C# 项目 csproj 文件格式)

参考
https://blog.lindexi.com/post...
https://walterlv.com/post/und... # 新旧 csproj 有什么不同, TargetFrameworkVersion 属性 是旧格式,TargetFrameworks 属性 是新格式 *
参考
https://docs.microsoft.com/en...
https://docs.microsoft.com/en...
https://www.cnblogs.com/linia... MSBuild 入门
https://docs.microsoft.com/en...

注意:
.NET Standard 的实现的两个方式:dotnet core 和 mono ,它们各有自己的 runtime ,所以有自己的一套命令(dnc的命令是 dotnet run,mono 的命令是 msbuild + mono 123.exe ,参考 dotnet-mono )。但是 读取的构建文件是一样的 (.csproj)。

疑问:
作为包管理工具,nuget 和 dotnet add 可以完成第三方包的下载,然而它似乎并没有处理包依赖 (dependency management) 的问题 (一个包有很多被依赖的包 dependency management ) 1
所以要引入 Paket 1 2
does dotnet add resolve dependencies
C# dependency management

疑问:
msbuild + mono 123.exedotnet run (含 dotnet restore + dotnet build + dotnet run) 的关系
参考 dotnet-mono

一个天才的排错举动,关于 dotnet run 在 mac / linux 上因为 target 是 .NET Framework 而 失灵 的问题
1 export FrameworkPathOverride 但似乎并无作用,还没有 msbuild + mono 123.exe 好用
2

mono 系

用于运行二进制(exe)的 runtime:

  • mono 123.exe

构建工具

  • msbuild

构建文件
.csproj (C# 项目 csproj 文件格式)

位置
/Library/Frameworks/Mono.framework/Versions/Current/Commands/mono
/Library/Frameworks/Mono.framework/Versions/Current/Commands/msbuild

可能涉及的命令:

  • msbuild
  • csc
  • gcs

可能涉及的命令:

  • msbuild 123.csproj -t:build
  • msbuild -t:rebuild
  • msbuild -t:clean
  • msbuild -verbosity:minimal

IDE
VS Mac 里使用的是 msbuild 和 mono

可能涉及编译命令 (.NET Standard 的实现):

  • mono系:csc, mono, MSBuild [1]()
> which mono
/Library/Frameworks/Mono.framework/Versions/Current/Commands/mono
> which msbuild 
/Library/Frameworks/Mono.framework/Versions/Current/Commands/msbuild 
支持的命令:
msbuild 
msbuild 123.csproj
msbuild -t:rebuild
msbuild -t:clean 
mono bin/Debug/123.exe

https://blog.lindexi.com/post...
https://walterlv.com/post/und...

dotnet 系

用于运行二进制(exe)的 runtime:

  • dotnet run

构建工具:

  • dotnet build

构建文件:

  • .csproj (C# 项目 csproj 文件格式)

可能涉及的命令:

  • dotnet run
  • dotnet run -f netstandard2.0
  • dotnet watch run
  • dotnet msbuild -t:Publish -p:OutputPath=pub -p:Configuration=Release #参考 https://docs.microsoft.com/en...
  • dotnet build
  • dotnet msbuild
  • dotnet restore

路径 (mac):

  • /usr/local/share/dotnet/dotnet

IDE
?

  • dotnet core 系:dotnet 1 2
> which dotnet
/usr/local/share/dotnet/dotnet
支持的命令:
dotnet run
dotnet build
dotnet msbuild
dotnet msbuild -t:rebuild
dotnet msbuild -t:clean

Paket

Paket 一个面向.NET 的包管理器
用于处理包依赖关系,类似 ruby bundle 。它相当于 enhanced nuget .

可能涉及包管理命令(第三方包的依赖和下载):

  • Paket (也是一个构建工具,a package manager,enhanced nuget ,处理包依赖关系 (packet 会自动调用 nuget 用于完成一些第三方包的下载,这等于一个第三方包的下载功能 wrapper ,一个更强大的第三方包管理器 ),明显借鉴 ror 的 bundle 和 Gemfile。粒度在于显式处理第三方包的包依赖,类似 ruby bundle ,兼容 nuget 。类似 Gemfile.lock 有自己的 paket.lock ) 1 2
  • cake

changsj
211 声望11 粉丝

changsj.