【鸿蒙】0x00-OpenHarmony-4.1-Release DAYU200 RK3568开发环境总结(长文版
系列文章目录【鸿蒙】0x00-OpenHarmony-4.1-Release DAYU200 RK3568开发环境总结(长文版)
【鸿蒙】0x01-LiteOS-M基于Qemu Arm Cortex-m55运行
更新日记
日期变更内容2024-03-02鸿蒙OpenHarmony 4.x源码下载和编译流程2024-08-04完成编译章节编写2024-08-17增补编译乐成章节内容2024-08-17实行烧录章节内容2024-08-24增补FAQ中涉及BTF报错修改总结 先容OpenHarmony
OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及运营的开源项目,目的是面向全场景、全连接、全智能时代,搭建一个智能终端设备利用系统的框架和平台,促进万物互联产业的繁荣发展。
开源代码堆栈所在:https://openharmony.gitee.com
获取OpenHarmony源码
国内建议从码云堆栈获取
[*] 适用场景
[*]基于OpenHarmony的稳固分支建立本身的基线,分发鄙俚客户。
[*]已经完成自身软件与OpenHarmony的对接,必要进行OpenHarmony官方认证。
[*]芯片/模组/app通过OpenHarmony官方认证后,贡献代码到OpenHarmony社区。 修复OpenHarmony的问题。
[*]学习OpenHarmony的源码。
前提条件
[*]注册码云gitee帐号。
[*]注册码云SSH公钥,请参考码云资助中心。
[*]安装git客户端和git-lfs并设置用户信息。
ubuntu: apt安装
sudo apt install git-lfs
效果:
➜openHarmony git lfs install
Git LFS initialized.
设置用户信息:
git config --global user.name "yourname"
git config --global user.email "your-email-address"
git config --global credential.helper store
[*]实行如下命令安装码云repo工具
下述命令中的安装路径以"~/bin"为例,请用户自行创建所需目录。
mkdir ~/bin
curl https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 -o ~/bin/repo
chmod a+x ~/bin/repo
pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests
https://i-blog.csdnimg.cn/blog_migrate/fa09f14ff0b3d7fcf3344341fcfb55f3.png
[*]将repo添加到环境变量
vim ~/.bashrc
# 编辑环境变量
export PATH=~/bin:$PATH # 在环境变量的最后添加一行repo路径信息
source ~/.bashrc
# 应用环境变量
OpenHarmony主干代码获取
发布版本代码相对比力稳固,开发者可基于发布版本代码进行商勤奋能开发。Master主干为开发分支,开发者可通过Master主干获取最新特性。
[*] OpenHarmony发布版本代码获取
[*] OpenHarmony主干代码获取
通过repo + https下载
repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify
repo sync -c
repo forall -c 'git lfs pull'
下载代码过程如下:
➜openHarmony repo sync -c
Updating files: 100% (3152/3152), done.hird_party_unityUpdating files:15% (476/3152)
Updating files: 100% (11108/11108), done.rd_party_vixlUpdating files: 0% (99/11108)
Updating files: 100% (2396/2396), done.endor_telinkUpdating files:40% (965/2396)
Checking out projects: 100% (488/488), done.
repo sync has finished successfully.
➜openHarmony repo forall -c 'git lfs pull'
Downloading LFS objects: 9% (5/53), 219 MB | 10 MB/s
获取OpenHarmony release分支代码
https://i-blog.csdnimg.cn/blog_migrate/965c1b92aa715e839071448f1e6eb1e2.png
这里演示OpenHarmony-4.1-Release分支:
repo init -u https://gitee.com/openharmony/manifest.git-b OpenHarmony-4.1-Release --no-repo-verify
repo sync -c
repo forall -c 'git checkout -b OpenHarmony-4.1-Release'
repo forall -c 'git lfs pull'
如果拉代码乐成:
➜openHarmony repo sync -c
Fetching projects: 2% (7/245) third_party_ffmpegremote: Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
Fetching projects: 3% (9/245) developtools_profilerremote: Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
Fetching projects: 100% (245/245), done.
Checking out projects: 100% (245/245), done.
repo sync has finished successfully.
https://i-blog.csdnimg.cn/direct/48ffc76cca5b4030982bf6d77052c94c.png
源码目录简介
下表是OpenHarmony源码目录:
目录名描述applications应用步伐样例,包括camera等base基础软件服务子系统集&硬件服务子系统集build组件化编译、构建和设置脚本docs分析文档domains增强软件服务子系统集drivers驱动子系统foundation系统基础本领子系统集kernel内核子系统prebuilts编译器及工具链子系统test测试子系统third_party开源第三方组件utils常用的工具集vendor厂商提供的软件build.py编译脚本文件 编译
实行prebuilts
在源码根目录下实行prebuilts脚本,安装编译器及二进制工具。
bash build/prebuilts_download.sh
https://i-blog.csdnimg.cn/direct/a71fcc079005474e9cc17085980a76ef.png
安装编译工具
开发环境
Linux lab 6.8.0-40-generic #40~22.04.3-Ubuntu SMP PREEMPT_DYNAMIC
apt install xxx
sudo apt install libssl-dev
sudo apt install liblz4-tool
sudo apt install git-lfs
sudo apt install ccache
sudo apt install flex
sudo apt install bison
sudo apt install ruby
sudo apt install libncurses5-dev
sudo apt install default-jdk 或者 sudo apt install openjdk-17-jdk
sudo apt install mtd-utils
sudo apt install scons
sudo apt install gcc-arm-none-eabi
sudo apt install gcc-arm-linux-gnueabi
sudo apt-get install libxt-dev
sudo apt-get install libx11-dev
sudo apt install xorg-dev
sudo apt-get install liblz4-tool
sudo apt install dwarves
sudo apt install genext2fs
python环境
[*]安装pip库
sudo apt-get install python3-pip
pip install -i https://mirrors.ustc.edu.cn/pypi/web/simple pip -U
pip config set global.index-url https://mirrors.ustc.edu.cn/pypi/web/simple
mkdir -p $HOME/.env && python3 -m venv $HOME/.env/py3_env
$HOME/.env/py3_env/bin/python -m pip install --upgrade pip
# 可以把下面这句添加到.bashrc里面, 并执行 source ~/.bashrc
source $HOME/.env/py3_env/bin/activate
相关库依赖:
kconfiglib,pycryptodome,six ,ecdsa
pip install kconfiglib
pip install pycryptodome
pip install six --upgrade --ignore-installed six
pip install ecdsa
安装ninja
ERROR: Cannot find Ninja
sudo apt install ninja-build
安装hb
[*]在源码根目录运行如下命令安装hb并更新至最新版本。
hb安装(HarmonyOS编译构建命令行工具)
python3 -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple ohos-build
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Collecting ohos-build
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/29/69/c608439e63da8e7a63b4b672e311609c2866bbdf00739aa1ee3506ce4a39/ohos_build-0.4.6-py3-none-any.whl (9.4 kB)
Collecting PyYAML (from ohos-build)
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (751 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 751.2/751.2 kB 9.8 MB/s eta 0:00:00
[*]设置环境变量。
vim ~/.bashrc
将以下命令拷贝到.bashrc文件的最后一行,保存并退出。
export PATH=~/.local/bin:$PATH
实行如下命令更新环境变量。
source ~/.bashrc
实行编译
hb方式实行编译命令
这里不建议通过有些质料里说的 hb set
, 然后实行hb build构建, 如下图所示, 由于我这样实行并不顺遂。
hb是OpenHarmony的命令行工具,用来实行编译命令。以下对hb的常用命令进行分析。
hb set
设置要编译的产品
hb set
-husage: hb set
[-h] [-root ] [-p]optional arguments:-h, --help show this help message and exit-root , --root_path Set OHOS root path-p, --product Set OHOS board and kernel hb set
后无参数,进入默认设置流程, 如下图所示:
https://i-blog.csdnimg.cn/direct/aa38d349880d483198074871fbe5ea98.png
hb set
-root dir 可直接设置代码根目录
hb set
-p 设置要编译的产品
hb set
-root 代码根目录所在绝对路径 -p rk3568 再强调一次: 代码路径很容易设置错,建议通过命令行方式构建镜像。
使用命令行方式
代码根目录下实行全量版本的编译命令:
Release版本 :
./build.sh --product-name {product_name}
Debug版本 :
./build.sh --product-name {product_name} --gn-args is_debug=true
注意: Debug全版本因镜像巨细限制,全量编译可能无法烧录,建议单模块编译Debug二进制。使用如下命令单独编译模块:
./build.sh --product-name {product_name} --gn-args is_debug=true
--build-target {target_name} 这里以润和DAYU200尺度系统板为例, 选择rk3568产品镜像编译:
./build.sh --product-name=rk3568 --device-name=rk3568 --no-prebuilt-sdk --jobs=4 --ccache
# 没试过,在OpenHarmony/build仓的issue里看到的
echo 'start' && export NO_DEVTOOL=1 && export CCACHE_LOG_SUFFIX=\"dayu200-arm32\" && export CCACHE_NOHASHDIR=\"true\" && export CCACHE_SLOPPINESS=\"include_file_ctime\" && ./build.sh --product-name rk3568 --ccache --build-target make_all --build-target make_test --gn-arg
https://i-blog.csdnimg.cn/direct/cee938109e8d4ce29e75ad2dfe2cd117.png
可以看到笔者本次编译过程中,有编译目的比力多, 首次编译必要花很长时间。
如果顺遂, 在路径 out/rk3568/packages/phone/images 目录里包罗源码构建出来的镜像, 下一步将用于烧录。
编译乐成
All rules passed
rk3568 build success
Cost time:4:08:02
=====buildsuccessful=====
2024-08-17 03:49:53
++++++++++++++++++++++++++++++++++++++++
使用瑞芯微开发工具烧录
镜像预备
逐日构建下载
https://i-blog.csdnimg.cn/direct/b293857c33de4c59bdc13b32948c8f71.png
下载源码编译镜像
将out/rk3568/packages/phone/images目录下载到本地磁盘。
https://i-blog.csdnimg.cn/direct/684921495a134a13bdb1ee23324909c0.png
工具下载安装
https://i-blog.csdnimg.cn/direct/243fe9287d67477a9518a7ca316d1ed6.png
详细烧录指南参考: HiHope_DAYU200/烧写工具及指南
安装USB驱动
双击 windows\DriverAssitant\ DriverInstall.exe 打开安装步伐, 点击下图所示的“驱动安 装” 按钮:
https://i-blog.csdnimg.cn/direct/42683684b9c644d194788d1990cf08f3.png#pic_center
开发板连接
https://i-blog.csdnimg.cn/direct/272f2777534f4116a366fd6347e673f5.png#pic_center
实行烧录
默认打开是截图所示样子:
https://i-blog.csdnimg.cn/direct/abcf82bfd75747b4a253dfe6463fe047.png
[*] 导入 images 内里的config.cfg文件
https://i-blog.csdnimg.cn/direct/db755de660544121a02854d4e51d34ef.png
[*] 导入设置乐成
https://i-blog.csdnimg.cn/direct/4f6ee5f6658d4ea38393f81d19054d14.png
[*] 则必要导入镜像包中的config.cfg设置才能选择烧写该文件。 导入新设置后,misc,sys-prod,chip-prod三个分区不存在镜像(预留位置),烧写时不能勾选。
内容鼠标双机清空这三项内容,同时取消方框选中即可。
https://i-blog.csdnimg.cn/direct/0a861cf7c1154634b89300ac47512196.png
[*] 双击后面的白色按钮,勾选必要烧写的固件
https://i-blog.csdnimg.cn/direct/d68e3b6bd1ed453b9f0f9ed33833b81d.png
[*] 确认开发板是否进入烧写模式
① 如果界面表现"发现一个 LOADER 设备", 分析开发板进入 Loader 模式期待烧写固件。
② 如果界面表现"发现一个 MASKROM 设备", 分析开发板进入 Maskrom 模式期待烧写固 件。
③ 如果界面表现"没有发现设备", 分析开发板没有进入烧写模式, 请按以下利用步调让开发板进入烧写模式
a、 按住VOL-/RECOVERY 按键(图中标注的①号键) 和 RESET 按钮(图中标注的②号键)不松开, 烧录工具此时表现“没有发现设备” ;
https://i-blog.csdnimg.cn/direct/8e71277a407c47409aeae279ab442ebb.png
https://i-blog.csdnimg.cn/direct/b91e5ac845ef4d04991898a813efa387.png
b、松开 RESET 键, 烧录工具表现“发现一个 LOADER 设备” , 分析此时已经进入烧写模式
https://i-blog.csdnimg.cn/direct/05e99b1698e0462cb505e29ec001dc9a.png
c、松开RESET按键, 稍等几秒后点击实行进行烧录,此时可以将RECOVERY键也松开了。
https://i-blog.csdnimg.cn/direct/1a3af1cb50d640f085646d203fd32a0a.png
分析:
如果烧写乐成, 在工具界面右侧会表现下载完成
如果烧写失败, 在工具界面右侧会用红色的字体表现烧写错误信息, 更多堕落信息检察:
Log 目录下的文件。
烧录乐成
https://i-blog.csdnimg.cn/direct/bc8f7204e3944a02b8124758755d50ad.png
运行结果
https://i-blog.csdnimg.cn/direct/e0b1138e557c440ab0abb14923bc1c13.png
FAQ
ImportError: cannot import name ‘Mapping’ from ‘collections’
➜openHarmony hb -h
Traceback (most recent call last):
File "/home/your_name/.local/bin/hb", line 8, in <module>
sys.exit(main())
File "/home/your_name/.local/lib/python3.10/site-packages/hb/__main__.py", line 71, in main
module = importlib.import_module('.{}'.format(each.get('name')),
xxxxxxx
from collections import Mapping
ImportError: cannot import name 'Mapping' from 'collections' (/usr/lib/python3.10/collections/__init__.py)
其python版本为3.8.x,而Ubuntu22.04的python版本是3.10.x,由于hb命令是用python写的,故推测这是由于python版本导致的问题。
[*]解决办法
修改报错的python脚本,将from collections import Mapping修改为from collections.abc import Mapping即可:
vim ~/.local/lib/python3.10/site-packages/prompt_toolkit/styles/from_dict.py
https://i-blog.csdnimg.cn/direct/51ed45582962472e93df2275ef1ff4d7.png
ModuleNotFoundError: No module named ‘hb.util’
重要是由于版本兼容性导致的,先卸载hb模块,然后重新实行编译。
➜openHarmony pip uninstall ohos-build
Found existing installation: ohos-build 0.4.3
please call hb utilities inside source root directory
注意:如果前面安装hb的时间出现错误: “please call hb utilities inside source root directory”
1.卸载当前版本的hb
python3 -m pip uninstall ohos-build
error: unknown type name ‘uint8_t’
In file included from ../../arkcompiler/ets_runtime/ecmascript/compiler/codegen/maple/maple_driver/src/triple.cpp:16:
In file included from ../../arkcompiler/ets_runtime/ecmascript/compiler/codegen/maple/maple_driver/include/triple.h:20:
../../arkcompiler/ets_runtime/ecmascript/compiler/codegen/maple/maple_util/include/utils.h:52:11: error: unknown type name 'uint8_t'
template <uint8_t Scale, typename T>
^
../../arkcompiler/ets_runtime/ecmascript/compiler/codegen/maple/maple_util/include/utils.h:56:11: error: unknown type name 'uint8_t'
constexpr uint8_t kOctalNum = 8;
^
../../arkcompiler/ets_runtime/ecmascript/compiler/codegen/maple/maple_util/include/utils.h:57:11: error: unknown type name 'uint8_t'
constexpr uint8_t kDecimalNum = 10;
^
../../arkcompiler/ets_runtime/ecmascript/compiler/codegen/maple/maple_util/include/utils.h:58:11: error: unknown type name 'uint8_t'
constexpr uint8_t kHexadecimalNum = 16;
^
../../arkcompiler/ets_runtime/ecmascript/compiler/codegen/maple/maple_util/include/utils.h:61:20: error: type of specialized non-type template argument depends on a template parameter of the partial specialization
vim ./Develop/openHarmony/arkcompiler/ets_runtime/ecmascript/compiler/codegen/maple/maple_util/include/utils.h
增加头文件
#inlcude <stdint.h>
developtools/packing_tool/haptobin.sh: line 65: javac: command not found
安装java环境,参考前文编译环境预备章节。
fatal error: ‘bits/libc-header-start.h’ file not found
/usr/include/stdint.h:26:10: fatal error: 'bits/libc-header-start.h' file not found
#include <bits/libc-header-start.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
缘故原由是环境没有完善造成的,解决方案:
sudo apt install gcc-multilib
clang++: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory
CXX mingw_x86_64/obj/base/hiviewdfx/faultloggerd/interfaces/innerkits/unwinder/unwinder_host/dfx_elf.o
FAILED: mingw_x86_64/obj/base/hiviewdfx/faultloggerd/interfaces/innerkits/unwinder/unwinder_host/dfx_elf.o
......
../../prebuilts/mingw-w64/ohos/linux-x86_64/clang-mingw/bin/clang++: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory
解决方案:
# Install missing dependency
sudo apt update && sudo apt install -y libtinfo5
没有显着错误,必要通过加虚拟机大内存解决的场景
报错内容
FAILED: obj/foundation/arkui/ace_engine/adapter/ohos/entrance/ace_ohos_standard_entrance_ohos/dialog_container.o
/usr/bin/ccache ../../prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang++ -MMD -MF obj/foundation/arkui/ace_engine/adapter/ohos/entrance/ace_ohos_standard_entrance_ohos/dialog_container.o.d
排查错误日记,没有显着错误, 又由于ccache开头, 怀疑内存不敷导致,在编译过程中观察内存的使用情况,就能验证这一点。
BTF相关编译报错
ld.lld: error: .btf.vmlinux.bin.o: unknown file type
Code: 4000
https://i-blog.csdnimg.cn/direct/765d918b7a6144f29641177cef41933c.png
如果搜索" error: " 关键字,还可以看到 ld.lld: error: .btf.vmlinux.bin.o: unknown file type
error: write on a pipe with no reader
DESCENDbpf/resolve_btfids
error: write on a pipe with no reader
另有
>>> referenced 1 more times
BTF .btf.vmlinux.bin.o
pahole: .tmp_vmlinux.btf: No such file or directory
LD .tmp_vmlinux.kallsyms1
ld.lld: error: .btf.vmlinux.bin.o: unknown file type
参考社区issue:
https://gitee.com/openharmony/build/issues/I8IDZ4?from=project-issue
https://gitee.com/openharmony/build/issues/I8H6VK?from=project-issue
https://gitee.com/openharmony/build/issues/I8YLK7?from=project-issue
https://gitee.com/openharmony/build/issues/I8DMPP?from=project-issue
https://gitee.com/openharmony/build/issues/I8H6VK?from=project-issue
[*]解决方法
vim kernel/linux/config/linux-5.10/rk3568/arch/arm64_defconfig
找到CONFIG_DEBUG_INFO_BTF=y这一行, 修改为:
# CONFIG_DEBUG_INFO_BTF is not set
https://i-blog.csdnimg.cn/direct/42e5e2486e204418a771ad6274455bdb.png
清除out目录后,再次编译
➜openHarmony rm -rf ./out && ./build.sh --product-name=rk3568 --device-name=rk3568 --no-prebuilt-sdk --jobs=4 --ccache
error: Cannot resolve BTF IDs for CONFIG_DEBUG_INFO_BTF, please install libelf-dev, libelf-devel or elfutils-libelf-devel
sudo apt install dwarves
修改文件路径:
vim kernel/linux/config/linux-5.10/arch/arm64/configs/rk3568_standard_defconfig
CONFIG_DEBUG_INFO_BTF=y
修改为 :
# CONFIG_DEBUG_INFO_BTF is not set
https://i-blog.csdnimg.cn/direct/662135c4619842f990d19de4e643b1e3.png
fatal error: ‘bpf_helper_defs.h’ file not found
In file included from ../../foundation/communication/netmanager_base/services/netmanagernative/bpf/src/netsys.c:24:
obj/build/templates/bpf/arm-linux-ohos/bpf/bpf_helpers.h:11:10: fatal error: 'bpf_helper_defs.h' file not found
#include "bpf_helper_defs.h"
^~~~~~~~~~~~~~~~~~~
1 error generated.
如果上面方法都试过了,可以先把linux
涉及BTF相关报错修改总结
(py3_env) ➜config git:(OpenHarmony-4.1-Release) ✗ git status
On branch OpenHarmony-4.1-Release
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: linux-5.10/arch/arm64/configs/rk3568_standard_defconfig
modified: linux-5.10/rk3568/arch/arm64_defconfig
修改内容:
diff --git a/linux-5.10/arch/arm64/configs/rk3568_standard_defconfig b/linux-5.10/arch/arm64/configs/rk3568_standard_defconfig
index 738ac9b..f4ac99b 100644
--- a/linux-5.10/arch/arm64/configs/rk3568_standard_defconfig
+++ b/linux-5.10/arch/arm64/configs/rk3568_standard_defconfig
@@ -6605,7 +6605,7 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_INFO_COMPRESSED is not set
# CONFIG_DEBUG_INFO_SPLIT is not set
# CONFIG_DEBUG_INFO_DWARF4 is not set
-CONFIG_DEBUG_INFO_BTF=y
+# CONFIG_DEBUG_INFO_BTF=y is not set
# CONFIG_GDB_SCRIPTS is not set
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=2048
diff --git a/linux-5.10/rk3568/arch/arm64_defconfig b/linux-5.10/rk3568/arch/arm64_defconfig
index 1ba71ac..ba31a68 100644
--- a/linux-5.10/rk3568/arch/arm64_defconfig
+++ b/linux-5.10/rk3568/arch/arm64_defconfig
@@ -5907,7 +5907,7 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_INFO_COMPRESSED is not set
# CONFIG_DEBUG_INFO_SPLIT is not set
# CONFIG_DEBUG_INFO_DWARF4 is not set
-CONFIG_DEBUG_INFO_BTF=y
+# CONFIG_DEBUG_INFO_BTF is not set
# CONFIG_GDB_SCRIPTS is not set
CONFIG_FRAME_WARN=2048
# CONFIG_STRIP_ASM_SYMS is not set
(END)
参考资料
[*]https://gitee.com/openharmony/manifest
[*]https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%BA%90%E7%A0%81
[*]https://blog.csdn.net/nanzhanfei/article/details/115409538
[*]https://mirrors.tuna.tsinghua.edu.cn/help/homebrew/
[*]https://docs.openharmony.cn/pages/v4.0/zh-cn/device-dev/quick-start/quickstart-pkg-sourcecode.md
[*]https://blog.csdn.net/CrazyMo_/article/details/134183151
[*]https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/subsystems/subsys-build-all.md
[*]https://doc.embedfire.com/linux/rk356x/OpenHarmony_manual/zh/latest/doc/linux_introduce/ohos-compile.html
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]