前言

我在上一篇随笔“在 Ubuntu 10.10 操作系统中安装 Mono 2.8.2”中说过:

所以说,从源代码编译高版本的 Mono,需要先安装低版本的 Mono。

博客无双大赛的评委老赵在我这篇随笔的评论中说:


引用所以说,从源代码编译高版本的 Mono,需要先安装低版本的 Mono。

这说法是不对的,完全可以从一台裸机上安装mono-2.8,编译时自然会先生成个C#编译器,再用它来编译Framework。其实你虽然是并行安装,但是编译mono 2.8的时候没有用到任何mono 2.6的东西。

这样,就让我们在一台裸机上安装 Mono 2.8.2,看看到底要不要先安装低版本的 Mono。

安装 Ubuntu 10.10 Server

首先到 Ubuntu 网站下载 ubuntu-10.10-server-amd64.iso 文件。

然后,在 Oracle VM VirtualBox 4.0 中新建一个虚拟机:

从源代码编译 Mono 2.8.2 是否需要低版本的 Mono

 

注意,为了能够使宿主机能够从网络上访问虚拟机,网络连接方式必须设为 Bridged Adapter,如下图所示:

从源代码编译 Mono 2.8.2 是否需要低版本的 Mono

 

在上图中的 MAC 地址栏输入我在“在 Linux 操作系统中运行 ASP.NET 4 (上)”一文中为 openSUSE 11.3 虚拟机分配的同样的 MAC 地址:

从源代码编译 Mono 2.8.2 是否需要低版本的 Mono

 

以便我家的 TP-LINK 宽带路由路也为 Ubuntu 10.10 Server 操作系统分配同样的静态 IP 地址:192.168.1.251,如下图所示:

从源代码编译 Mono 2.8.2 是否需要低版本的 Mono

 

现在,可以点击 Oracle VM VirtualBox 工具栏的“开始”按钮,开始安装 Ubuntu 10.10 Server 操作系统。

从源代码编译 Mono 2.8.2 是否需要低版本的 Mono

从源代码编译 Mono 2.8.2 是否需要低版本的 Mono

 

我决定安装英文版的 Ubuntu 10.10 Server 操作系统,回答了一些问题,主要是时区、键盘等,开始安装 Ubuntu 的基本系统了:

从源代码编译 Mono 2.8.2 是否需要低版本的 Mono

 

又回答一些问题,主要是用户名和密码,继续安装,中途又要你选择预装的软件:

从源代码编译 Mono 2.8.2 是否需要低版本的 Mono

 

什么也不选,继续安装:

从源代码编译 Mono 2.8.2 是否需要低版本的 Mono

 

等待几分钟后,终于安装完成了:

从源代码编译 Mono 2.8.2 是否需要低版本的 Mono

 

如上图所示,点击 Oracle VM VirtualBox 的“设备 –> 分配光驱 –> Remove disk from virtual drive”后,按回车键重启虚拟机。十来秒钟后,重启完成,进入 login 画面:

从源代码编译 Mono 2.8.2 是否需要低版本的 Mono

 

如上图所示,输入用户名和密码,登录到 Ubuntu 10.10 操作系统。让我们使用以下命令获得一些基本信息吧:

从源代码编译 Mono 2.8.2 是否需要低版本的 Mono

 

从上图中可以看出,Ubuntu 10.10 Server 操作系统的 IP 地址已经是 TP-LINK 宽带路由器分的静态地址 192.168.1.251 了。而且没有安装 Mono,因为这是 Server 版。如果是 Desktop 版,默认是预装了 Mono Runtime 的。最后使用 shutdown 命令关机。关闭 Ubuntu 10.10 Server 虚拟机后,应该在该虚拟机“设置”中把“光驱”从“启动顺序”去除,如下图所示:

从源代码编译 Mono 2.8.2 是否需要低版本的 Mono

设置 DNS 服务器地址

重新启动虚拟机后,再次登录系统。用 vi 修改 /etc/dhcp3/dhclient.conf 文件:

ben@D1520:~$ suod vi /etc/dhcp3/dhclient.conf

在文件末尾追加:

prepend domain-name-servers 192.168.1.1;

然后使用以下命令重启网络服务:

ben@D1520:~$ sudo /etc/init.d/networking restart
 * Reconfiguring network interfaces...                                          There is already a pid file /var/run/dhclient.eth0.pid with pid 2281
killed old client process, removed PID file
Internet Systems Consortium DHCP Client V3.1.3
Copyright 2004-2009 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/eth0/08:00:27:51:5b:0b
Sending on   LPF/eth0/08:00:27:51:5b:0b
Sending on   Socket/fallback
DHCPRELEASE on eth0 to 192.168.1.1 port 67
Internet Systems Consortium DHCP Client V3.1.3
Copyright 2004-2009 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/eth0/08:00:27:51:5b:0b
Sending on   LPF/eth0/08:00:27:51:5b:0b
Sending on   Socket/fallback
DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 3
DHCPOFFER of 192.168.1.251 from 192.168.1.1
DHCPREQUEST of 192.168.1.251 on eth0 to 255.255.255.255 port 67
DHCPACK of 192.168.1.251 from 192.168.1.1
bound to 192.168.1.251 -- renewal in 3948329 seconds.
ssh stop/waiting
ssh start/running, process 4991
                                                                         [ OK ]
ben@D1520:~$

验证一下 DNS 服务器地址是否设置正常:

ben@D1520:~$ cat /etc/resolv.conf
nameserver 192.168.1.1
nameserver 202.96.128.68
nameserver 202.96.134.188
nameserver 202.96.134.133
nameserver 192.168.1.1
domain domain
search domain
ben@D1520:~$ ping www.cctv.com
PING g1.ctc.cctvcdn.net (121.14.55.6) 56(84) bytes of data.
64 bytes from 121.14.55.6: icmp_req=1 ttl=246 time=23.6 ms
64 bytes from 121.14.55.6: icmp_req=2 ttl=246 time=23.6 ms
^C
--- g1.ctc.cctvcdn.net ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1004ms
rtt min/avg/max/mdev = 23.655/23.676/23.697/0.021 ms
ben@D1520:~$

安装和配置 SSH 登录

由于我们安装的是纯文本模式的 Server 版,无法安装 Oracle VM VirtualBox 的增强功能,因此没有办法直接在 Oracle VM VirtualBox 中复制文本,很不方便。于是,先在 Ubuntu 10.10 Server  操作系统中安装一个 SSH 服务,如下图所示:

从源代码编译 Mono 2.8.2 是否需要低版本的 Mono

注意,上图中的 apt-get install 命令已经执行过一遍了,由于信息太多,滚出了屏幕,这是第二次执行。

现在,需要在宿主机的 Windows Vista 操作系统中安装一个 SSH 客户端软件。到 PuTTY Download Page 下载一个 putty.exe 文件,这是个绿色软件,不需要安装,直接运行就行了:

从源代码编译 Mono 2.8.2 是否需要低版本的 Mono

在上图中的“Host Name” 和“Saved Sessions”中输入“ben.skyiv.com”, 点击“Save”按钮。下次使用 PuTTY 时只要直接双击已经保存的“ben.skyiv.com”就可以登录虚拟机中的 Ubutnu 10.10 Server 了。登录后的画面如下图氘示:

从源代码编译 Mono 2.8.2 是否需要低版本的 Mono

让 sudo 命令不要输密码

参阅“Ubuntu 9.04 安装和配置备忘录”,使用以下命令让 sudo 命令不要输密码:

ben@D1520:~$ sudo visudo

从源代码编译 Mono 2.8.2 是否需要低版本的 Mono

如上图所示,在最后一行输入“%sudo ALL=NOPASSWD: ALL”,再执行以下命令就行了:

ben@D1520:~$ sudo adduser `whoami` sudo
Adding user `ben' to group `sudo' ...
Adding user ben to group sudo
Done.

更新系统

使用以下命令更新系统:

ben@D1520:~$ sudo apt-get update
======> 这里省略了一大堆输出 <======
ben@D1520:~$ sudo apt-get upgrade
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages have been kept back:
  linux-headers-server linux-image-server linux-server
The following packages will be upgraded:
  apparmor apparmor-utils bind9-host dnsutils dpkg ifupdown initscripts
  libapparmor-perl libapparmor1 libbind9-60 libc-bin libc6 libcairo2 libdns66
  libdrm-intel1 libdrm-nouveau1 libdrm-radeon1 libdrm2 libfreetype6
  libgssapi-krb5-2 libisc60 libisccc60 libisccfg60 libk5crypto3 libkrb5-3
  libkrb5support0 libldap-2.4-2 liblwres60 libpam-modules libpam-runtime
  libpam0g libplymouth2 libsqlite3-0 libssl0.9.8 libudev0 libxml2
  linux-headers-2.6.35-22 linux-headers-2.6.35-22-server
  linux-image-2.6.35-22-server openssl plymouth plymouth-theme-ubuntu-text
  python python-minimal sysv-rc sysvinit-utils tzdata udev update-manager-core
49 upgraded, 0 newly installed, 0 to remove and 3 not upgraded.
Need to get 61.7MB of archives.
After this operation, 36.9kB disk space will be freed.
Do you want to continue [Y/n]?
======> 这里进行漫长的升级,并产生一大堆输出 <======
ben@D1520:~$ sudo apt-get dist-upgrade
Reading package lists... Done
Building dependency tree
Reading state information... Done
Calculating upgrade... Done
The following NEW packages will be installed:
  linux-headers-2.6.35-24 linux-headers-2.6.35-24-server
  linux-image-2.6.35-24-server
The following packages will be upgraded:
  linux-headers-server linux-image-server linux-server
3 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
Need to get 45.0MB of archives.
After this operation, 229MB of additional disk space will be used.
Do you want to continue [Y/n]?
======> 这里进行漫长的升级,并产生一大堆输出 <======
Setting up linux-headers-2.6.35-24 (2.6.35-24.42) ...
Setting up linux-headers-2.6.35-24-server (2.6.35-24.42) ...
Setting up linux-headers-server (2.6.35.24.28) ...
Setting up linux-image-server (2.6.35.24.28) ...
Setting up linux-server (2.6.35.24.28) ...
ben@D1520:~$

升级完成后,我重新启动了虚拟机。升级的时候系统并没有提示要要重新启动机器,不知道是 Server 版本是不是可以不重启机器。

下载 Mono 2.8.2 源代码并编译

参阅“在 Ubuntu 10.10 操作系统中安装 Mono 2.8.2”一文,使用以下命令下载 Mono 2.8.2 源代码并编译:

ben@D1520:~$ mkdir src
ben@D1520:~$ cd src
ben@D1520:~/src$ wget http://ftp.novell.com/pub/mono/sources/mono/mono-2.8.2.tar.bz2
--2011-01-08 12:29:27--  http://ftp.novell.com/pub/mono/sources/mono/mono-2.8.2.tar.bz2
Resolving ftp.novell.com... 130.57.1.88
Connecting to ftp.novell.com|130.57.1.88|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 31292886 (30M) [application/x-bzip2]
Saving to: `mono-2.8.2.tar.bz2'

100%[======================================>] 31,292,886   189K/s   in 2m 59s

2011-01-08 12:32:28 (171 KB/s) - `mono-2.8.2.tar.bz2' saved [31292886/31292886]

ben@D1520:~/src$ tar xjf mono-2.8.2.tar.bz2
ben@D1520:~/src$ cd mono-2.8.2
ben@D1520:~/src/mono-2.8.2$ ./configure --prefix=/opt/mono-2.8.2
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking target system type... x86_64-unknown-linux-gnu
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... no
checking for mawk... mawk
checking whether make sets $(MAKE)... yes
checking how to create a ustar tar archive... gnutar
checking whether to enable maintainer-specific portions of Makefiles... no
checking whether ln -s works... yes
checking host platform characteristics... ok
checking for gcc... no
checking for gcc... gcc
checking for C compiler default output file name...
configure: error: in `/home/ben/src/mono-2.8.2':
configure: error: C compiler cannot create executables
See `config.log' for more details.
ben@D1520:~/src$

 

不出所料,因为没有安装 C 编译器而无法继续:

ben@D1520:~/src/mono-2.8.2$ gcc
The program 'gcc' can be found in the following packages:
 * gcc
 * pentium-builder
Try: sudo apt-get install 
ben@D1520:~/src/mono-2.8.2$

安装基本编译环境

使用以下命令安装基本编译环境,包括 C/C++ 编译器:

ben@D1520:~/src/mono-2.8.2$ sudo apt-get install build-essential
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
  linux-headers-2.6.35-22-server linux-headers-2.6.35-22
Use 'apt-get autoremove' to remove them.
The following extra packages will be installed:
  binutils dpkg-dev fakeroot g++ g++-4.4 gcc gcc-4.4 libalgorithm-diff-perl
  libalgorithm-merge-perl libc-dev-bin libc6-dev libdpkg-perl libgomp1
  libstdc++6-4.4-dev linux-libc-dev manpages-dev patch
Suggested packages:
  binutils-doc debian-keyring g++-multilib g++-4.4-multilib gcc-4.4-doc
  libstdc++6-4.4-dbg gcc-multilib autoconf automake1.9 libtool flex bison gdb
  gcc-doc gcc-4.4-multilib libmudflap0-4.4-dev gcc-4.4-locales libgcc1-dbg
  libgomp1-dbg libmudflap0-dbg libcloog-ppl0 libppl-c2 libppl7 glibc-doc
  libstdc++6-4.4-doc diffutils-doc
The following NEW packages will be installed:
  binutils build-essential dpkg-dev fakeroot g++ g++-4.4 gcc gcc-4.4
  libalgorithm-diff-perl libalgorithm-merge-perl libc-dev-bin libc6-dev
  libdpkg-perl libgomp1 libstdc++6-4.4-dev linux-libc-dev manpages-dev patch
0 upgraded, 18 newly installed, 0 to remove and 0 not upgraded.
Need to get 19.6MB of archives.
After this operation, 59.6MB of additional disk space will be used.
Do you want to continue [Y/n]?
======> 这里省略了一大堆输出 <======
ben@D1520:~/src/mono-2.8.2$ sudo apt-get autoremove
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages will be REMOVED:
  linux-headers-2.6.35-22 linux-headers-2.6.35-22-server
0 upgraded, 0 newly installed, 2 to remove and 0 not upgraded.
After this operation, 90.3MB disk space will be freed.
Do you want to continue [Y/n]?
(Reading database ... 67103 files and directories currently installed.)
Removing linux-headers-2.6.35-22-server ...
Removing linux-headers-2.6.35-22 ...
ben@D1520:~/src/mono-2.8.2$ gcc --version
gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

ben@D1520:~/src/mono-2.8.2$ 

然后重新为编译 Mono 2.8.2 准备配置文件:

ben@D1520:~/src/mono-2.8.2$ ./configure --prefix=/opt/mono-2.8.2
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking target system type... x86_64-unknown-linux-gnu
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... no
checking for mawk... mawk
checking whether make sets $(MAKE)... yes
checking how to create a ustar tar archive... gnutar
checking whether to enable maintainer-specific portions of Makefiles... no
checking whether ln -s works... yes
checking host platform characteristics... ok
checking for gcc... gcc
checking for gcc... (cached) gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking for g++... g++
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking dependency style of g++... gcc3
checking dependency style of gcc... gcc3
checking for gcc... (cached) gcc
checking whether we are using the GNU C compiler... (cached) yes
checking whether gcc accepts -g... (cached) yes
checking for gcc option to accept ISO C89... (cached) none needed
checking dependency style of gcc... (cached) gcc3
checking for a BSD-compatible install... /usr/bin/install -c
checking for gawk... (cached) mawk
checking for bison... no
configure: error: You need to install bison
ben@D1520:~/src/mono-2.8.2$

这次缺少 bison,使用以下命令安装:

ben@D1520:~/src/mono-2.8.2$ sudo apt-get install bison
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
  m4
Suggested packages:
  bison-doc
The following NEW packages will be installed:
  bison m4
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 782kB of archives.
After this operation, 2,540kB of additional disk space will be used.
Do you want to continue [Y/n]?
Get:1 http://us.archive.ubuntu.com/ubuntu/ maverick/main m4 amd64 1.4.14-3 [290kB]
Get:2 http://us.archive.ubuntu.com/ubuntu/ maverick/main bison amd64 1:2.4.1.dfsg-3 [493kB]
Fetched 782kB in 5s (140kB/s)
Selecting previously deselected package m4.
(Reading database ... 47512 files and directories currently installed.)
Unpacking m4 (from .../archives/m4_1.4.14-3_amd64.deb) ...
Selecting previously deselected package bison.
Unpacking bison (from .../bison_1%3a2.4.1.dfsg-3_amd64.deb) ...
Processing triggers for install-info ...
Processing triggers for man-db ...
Setting up m4 (1.4.14-3) ...
Setting up bison (1:2.4.1.dfsg-3) ...
update-alternatives: using /usr/bin/bison.yacc to provide /usr/bin/yacc (yacc) in auto mode.
ben@D1520:~/src/mono-2.8.2$

再次为编译 Mono 2.8.2 准备配置文件:

ben@D1520:~/src/mono-2.8.2$ ./configure --prefix=/opt/mono-2.8.2
======> 这里省略了一大堆输出 <======
checking for msgfmt... no
configure: error: msgfmt not found. You need to install the 'gettext' package, or pass --enable-nls=no to configure.

现在需要安装 gettext 软件包:

ben@D1520:~/src/mono-2.8.2$ sudo apt-get install gettext
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
  libcroco3 libunistring0
Suggested packages:
  gettext-doc
The following NEW packages will be installed:
  gettext libcroco3 libunistring0
0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
Need to get 1,856kB of archives.
After this operation, 6,042kB of additional disk space will be used.
Do you want to continue [Y/n]?
Get:1 http://us.archive.ubuntu.com/ubuntu/ maverick/main libcroco3 amd64 0.6.2-1 [101kB]
Get:2 http://us.archive.ubuntu.com/ubuntu/ maverick/main libunistring0 amd64 0.9.3-1 [438kB]
Get:3 http://us.archive.ubuntu.com/ubuntu/ maverick/main gettext amd64 0.18.1.1-1ubuntu2 [1,317kB]
Fetched 1,856kB in 17s (109kB/s)
Selecting previously deselected package libcroco3.
(Reading database ... 47612 files and directories currently installed.)
Unpacking libcroco3 (from .../libcroco3_0.6.2-1_amd64.deb) ...
Selecting previously deselected package libunistring0.
Unpacking libunistring0 (from .../libunistring0_0.9.3-1_amd64.deb) ...
Selecting previously deselected package gettext.
Unpacking gettext (from .../gettext_0.18.1.1-1ubuntu2_amd64.deb) ...
Processing triggers for man-db ...
Processing triggers for install-info ...
Setting up libcroco3 (0.6.2-1) ...
Setting up libunistring0 (0.9.3-1) ...
Setting up gettext (0.18.1.1-1ubuntu2) ...
Processing triggers for libc-bin ...
ldconfig deferred processing now taking place

继续为编译 Mono 2.8.2 准备配置文件:

ben@D1520:~/src/mono-2.8.2$ ./configure --prefix=/opt/mono-2.8.2

======> 这里省略了一大堆输出 <======

        mcs source:    mcs
        olive source:

   Engine:
        GC:            sgen and bundled Boehm GC with typed GC and parallel mark
        GLIB:          embedded
        TLS:           __thread
        SIGALTSTACK:   yes
        Engine:        Building and using the JIT
        oprofile:      no
        BigArrays:     no
        DTrace:        no
        Parallel Mark: yes
        LLVM Back End: no (dynamically loaded: no)

    Libraries:
        Moon Profile:  no
        MonoTouch:     no
        JNI support:   IKVM Native
        libgdiplus:    assumed to be installed
        zlib:

ben@D1520:~/src/mono-2.8.2$

终于可以了。总结一下,从源代码编译 Mono 2.8.2 需要 build-essential、bison、gettext 这三个软件包。

编译 Mono 2.8.2

让我们开始编译 Mono 2.8.2 吧:

ben@D1520:~/src/mono-2.8.2$ make
======> 这里进行漫长的编译,并产生一大堆输出 <======
ben@D1520:~/src/mono-2.8.2$ sudo make install
======> 这里省略了一大堆输出 <======
ben@D1520:~/src/mono-2.8.2$

终于安装好了。

设置 PATH 环境变量

使用 vi 命令修改 .bashrc 文件:

ben@D1520:~$ vi .bashrc

在该文件末尾追加以下语句:

if [ -d /opt/mono-2.8.2/bin ]; then
    export PATH=/opt/mono-2.8.2/bin:$PATH
fi

然后:

ben@D1520:~$ . .bashrc
ben@D1520:~$ echo $PATH
/opt/mono-2.8.2/bin:/opt/mono-2.8.2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
ben@D1520:~$

验证 Mono

使用以下命令验证 Mono 是否正确安装:

ben@D1520:~$ mono --version
Mono JIT compiler version 2.8.2 (tarball Sat Jan  8 14:54:41 CST 2011)
Copyright (C) 2002-2010 Novell, Inc and Contributors. www.mono-project.com
        TLS:           __thread
        SIGSEGV:       altstack
        Notifications: epoll
        Architecture:  amd64
        Disabled:      none
        Misc:          debugger softdebug
        LLVM:          supported, not enabled.
        GC:            Included Boehm (with typed GC and Parallel Mark)
ben@D1520:~$ dmcs --version
Mono C# compiler version 2.8.2.0
ben@D1520:~$

可以看出,一切正常。

结论

老赵是正确的,从源代码编译 Mono 2.8.2 的确不需要低版本的 Mono。而是在编译的过程中会译时自然会先生成个C#编译器,再用它来编译 .NET Framework Base Class Library。其实编译前的准备工作就是安装以下软件包

ben@D1520:~$ sudo apt-get install build-essential bison gettext

为什么我会误认为需要低版本的 Mono 呢?其实也是看了老赵在“在 Ubuntu 9.10 操作系统中安装 mono 2.6”一文七楼的评论

真奇怪,装mono 2.6需要mono-complete做什么?
找了点资料,原来是build from source需要一个mono编译器和runtime啊。
不过build from tarball就不需要这些了:)

而没有正确理解评论造成的。

相关文章:

  • 2022-12-23
  • 2021-08-17
  • 2021-12-23
  • 2021-10-31
  • 2021-08-06
  • 2022-12-23
  • 2021-11-27
猜你喜欢
  • 2021-11-19
  • 2021-07-22
  • 2021-11-05
  • 2022-12-23
相关资源
相似解决方案