提交 5c2fa8c0 编写于 作者: D duangavin123

update 导入OpenHarmony工程

Signed-off-by: Nduangavin123 <duanxichao@huawei.com>
上级 b5ede3a9
# Copyright (c) 2020 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释 # 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse
......
# Copyright (c) 2020 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
FROM ubuntu:18.04 FROM ubuntu:18.04
WORKDIR /home/openharmony WORKDIR /home/openharmony
......
# Copyright (c) 2020 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#!/bin/bash #!/bin/bash
# 代码下载目录 # 代码下载目录
code_dir=/home/prebuilts code_dir=/home/prebuilts
......
# Copyright (c) 2020 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#!/bin/bash #!/bin/bash
WORKDIR=/home/openharmony WORKDIR=/home/openharmony
......
# Copyright (c) 2020 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
deb http://mirrors.ustc.edu.cn/ubuntu/ bionic main multiverse restricted universe deb http://mirrors.ustc.edu.cn/ubuntu/ bionic main multiverse restricted universe
deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-backports main multiverse restricted universe deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-backports main multiverse restricted universe
deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-proposed main multiverse restricted universe deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-proposed main multiverse restricted universe
......
此差异已折叠。
...@@ -63,11 +63,6 @@ ...@@ -63,11 +63,6 @@
<td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p1140814471274"><a name="p1140814471274"></a><a name="p1140814471274"></a>停止播放。</p> <td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p1140814471274"><a name="p1140814471274"></a><a name="p1140814471274"></a>停止播放。</p>
</td> </td>
</tr> </tr>
<tr id="row93063645415"><td class="cellrowborder" valign="top" width="42.980000000000004%" headers="mcps1.2.3.1.1 "><p id="p230715618541"><a name="p230715618541"></a><a name="p230715618541"></a>reset()<sup id="sup15868135520538"><a name="sup15868135520538"></a><a name="sup15868135520538"></a><span>7+</span></sup></p>
</td>
<td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p530714615545"><a name="p530714615545"></a><a name="p530714615545"></a>重置播放音频源。</p>
</td>
</tr>
<tr id="row36221450105715"><td class="cellrowborder" valign="top" width="42.980000000000004%" headers="mcps1.2.3.1.1 "><p id="p162210506572"><a name="p162210506572"></a><a name="p162210506572"></a>setVolume(vol: number)</p> <tr id="row36221450105715"><td class="cellrowborder" valign="top" width="42.980000000000004%" headers="mcps1.2.3.1.1 "><p id="p162210506572"><a name="p162210506572"></a><a name="p162210506572"></a>setVolume(vol: number)</p>
</td> </td>
<td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p166221550165720"><a name="p166221550165720"></a><a name="p166221550165720"></a>改变音频播放音量</p> <td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p166221550165720"><a name="p166221550165720"></a><a name="p166221550165720"></a>改变音频播放音量</p>
...@@ -83,12 +78,17 @@ ...@@ -83,12 +78,17 @@
<td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p1040814782716"><a name="p1040814782716"></a><a name="p1040814782716"></a>音频播放的媒体URI。</p> <td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p1040814782716"><a name="p1040814782716"></a><a name="p1040814782716"></a>音频播放的媒体URI。</p>
</td> </td>
</tr> </tr>
<tr id="row155026127182"><td class="cellrowborder" valign="top" width="42.980000000000004%" headers="mcps1.2.3.1.1 "><p id="p633012347"><a name="p633012347"></a><a name="p633012347"></a>state:AudioState</p> <tr id="row155026127182"><td class="cellrowborder" valign="top" width="42.980000000000004%" headers="mcps1.2.3.1.1 "><p id="p5503812121819"><a name="p5503812121819"></a><a name="p5503812121819"></a>state:string</p>
</td> </td>
<td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p105031612141811"><a name="p105031612141811"></a><a name="p105031612141811"></a>播放的状态属性。</p> <td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p105031612141811"><a name="p105031612141811"></a><a name="p105031612141811"></a>播放的状态属性。</p>
</td> </td>
</tr> </tr>
<tr id="row340854714273"><td class="cellrowborder" valign="top" width="42.980000000000004%" headers="mcps1.2.3.1.1 "><p id="p16234263330"><a name="p16234263330"></a><a name="p16234263330"></a>currentTime:number</p> <tr id="row19408114732719"><td class="cellrowborder" valign="top" width="42.980000000000004%" headers="mcps1.2.3.1.1 "><p id="p12209729141817"><a name="p12209729141817"></a><a name="p12209729141817"></a>autoplay:boolean</p>
</td>
<td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p19189929171811"><a name="p19189929171811"></a><a name="p19189929171811"></a>音频的自动播放属性。</p>
</td>
</tr>
<tr id="row340854714273"><td class="cellrowborder" valign="top" width="42.980000000000004%" headers="mcps1.2.3.1.1 "><p id="p1840914712277"><a name="p1840914712277"></a><a name="p1840914712277"></a>currenttime:number</p>
</td> </td>
<td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p3409174762710"><a name="p3409174762710"></a><a name="p3409174762710"></a>音频的当前播放位置。</p> <td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p3409174762710"><a name="p3409174762710"></a><a name="p3409174762710"></a>音频的当前播放位置。</p>
</td> </td>
...@@ -103,6 +103,11 @@ ...@@ -103,6 +103,11 @@
<td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p94091847102711"><a name="p94091847102711"></a><a name="p94091847102711"></a>音频的循环播放属性。</p> <td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p94091847102711"><a name="p94091847102711"></a><a name="p94091847102711"></a>音频的循环播放属性。</p>
</td> </td>
</tr> </tr>
<tr id="row19915911171916"><td class="cellrowborder" valign="top" width="42.980000000000004%" headers="mcps1.2.3.1.1 "><p id="p20915111121918"><a name="p20915111121918"></a><a name="p20915111121918"></a>muted:boolean</p>
</td>
<td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p12915211131910"><a name="p12915211131910"></a><a name="p12915211131910"></a>音频的静音属性。</p>
</td>
</tr>
<tr id="row44091647192718"><td class="cellrowborder" valign="top" width="42.980000000000004%" headers="mcps1.2.3.1.1 "><p id="p18937155862412"><a name="p18937155862412"></a><a name="p18937155862412"></a>on('play', function callback)</p> <tr id="row44091647192718"><td class="cellrowborder" valign="top" width="42.980000000000004%" headers="mcps1.2.3.1.1 "><p id="p18937155862412"><a name="p18937155862412"></a><a name="p18937155862412"></a>on('play', function callback)</p>
</td> </td>
<td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p13409164722717"><a name="p13409164722717"></a><a name="p13409164722717"></a>监听音频播放开始事件。</p> <td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p13409164722717"><a name="p13409164722717"></a><a name="p13409164722717"></a>监听音频播放开始事件。</p>
...@@ -118,12 +123,7 @@ ...@@ -118,12 +123,7 @@
<td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p1409164772714"><a name="p1409164772714"></a><a name="p1409164772714"></a>监听音频播放停止事件。</p> <td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p1409164772714"><a name="p1409164772714"></a><a name="p1409164772714"></a>监听音频播放停止事件。</p>
</td> </td>
</tr> </tr>
<tr id="row712184163016"><td class="cellrowborder" valign="top" width="42.980000000000004%" headers="mcps1.2.3.1.1 "><p id="p1167517115311"><a name="p1167517115311"></a><a name="p1167517115311"></a>on('reset', function callback)</p> <tr id="row11409747202711"><td class="cellrowborder" valign="top" width="42.980000000000004%" headers="mcps1.2.3.1.1 "><p id="p189901420102514"><a name="p189901420102514"></a><a name="p189901420102514"></a>on('ended',function callback)</p>
</td>
<td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p1113134115301"><a name="p1113134115301"></a><a name="p1113134115301"></a>监听音频播放重置事件。</p>
</td>
</tr>
<tr id="row11409747202711"><td class="cellrowborder" valign="top" width="42.980000000000004%" headers="mcps1.2.3.1.1 "><p id="p189901420102514"><a name="p189901420102514"></a><a name="p189901420102514"></a>on('finish',function callback)</p>
</td> </td>
<td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p8410124742713"><a name="p8410124742713"></a><a name="p8410124742713"></a>监听音频播放结束事件。</p> <td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p8410124742713"><a name="p8410124742713"></a><a name="p8410124742713"></a>监听音频播放结束事件。</p>
</td> </td>
...@@ -133,7 +133,7 @@ ...@@ -133,7 +133,7 @@
<td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p54101047102712"><a name="p54101047102712"></a><a name="p54101047102712"></a>监听音频播放错误事件。</p> <td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p54101047102712"><a name="p54101047102712"></a><a name="p54101047102712"></a>监听音频播放错误事件。</p>
</td> </td>
</tr> </tr>
<tr id="row1410154715273"><td class="cellrowborder" valign="top" width="42.980000000000004%" headers="mcps1.2.3.1.1 "><p id="p135217361257"><a name="p135217361257"></a><a name="p135217361257"></a>on('dataload', function callback)</p> <tr id="row1410154715273"><td class="cellrowborder" valign="top" width="42.980000000000004%" headers="mcps1.2.3.1.1 "><p id="p135217361257"><a name="p135217361257"></a><a name="p135217361257"></a>on('loaderdata', function callback)</p>
</td> </td>
<td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p1541054719271"><a name="p1541054719271"></a><a name="p1541054719271"></a>监听音频播放加载数据事件。</p> <td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p1541054719271"><a name="p1541054719271"></a><a name="p1541054719271"></a>监听音频播放加载数据事件。</p>
</td> </td>
...@@ -143,7 +143,7 @@ ...@@ -143,7 +143,7 @@
<td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p116527483584"><a name="p116527483584"></a><a name="p116527483584"></a>监听音频播放音量变化事件。</p> <td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p116527483584"><a name="p116527483584"></a><a name="p116527483584"></a>监听音频播放音量变化事件。</p>
</td> </td>
</tr> </tr>
<tr id="row1410124732711"><td class="cellrowborder" valign="top" width="42.980000000000004%" headers="mcps1.2.3.1.1 "><p id="p942310426254"><a name="p942310426254"></a><a name="p942310426254"></a>on('timeUpdate', function callback)</p> <tr id="row1410124732711"><td class="cellrowborder" valign="top" width="42.980000000000004%" headers="mcps1.2.3.1.1 "><p id="p942310426254"><a name="p942310426254"></a><a name="p942310426254"></a>on('timeupdate', function callback)</p>
</td> </td>
<td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p18410144715271"><a name="p18410144715271"></a><a name="p18410144715271"></a>监听音频播放进度改变事件。</p> <td class="cellrowborder" valign="top" width="57.02%" headers="mcps1.2.3.1.2 "><p id="p18410144715271"><a name="p18410144715271"></a><a name="p18410144715271"></a>监听音频播放进度改变事件。</p>
</td> </td>
...@@ -162,70 +162,73 @@ ...@@ -162,70 +162,73 @@
``` ```
player.on('play', (err, action) => { player.on('play', (err, action) => {
if (err) { if (err) {
console.error('Error returned in the play() callback.'); console.log(`err returned in play() callback`);
return; return;
} }
console.info('Current player duration: '+ player.duration); console.info('Current Song duration: '+duration);
console.info('Current player time: ' + player.currentTime); console.log(`In play callback current time: ${player.currentTime}`);
console.info('Current player status: '+player.state); console.info('Current Player Status: '+player.state);
console.info('Pause MP3'); console.info('Pause Mp3');
player.pause(); player.pause();
}); });
player.on('pause', (err, action) => { player.on('pause', (err, action) => {
if (err) { if (err) {
console.error('Error returned in the pause() callback.'); console.log(`err returned in pause() callback`);
return; return;
} }
console.info('Current player status: ' + player.state); console.log(`pause callback, state: ${player.state}`);
console.info('Current player time: ' + player.currentTime); console.info('Current Player Status: '+player.state);
player.seek(30000); // Seek for 30 seconds. var currentTime = player.currenTime;
console.info('Current Player Time: '+currentTime);
player.seek(30000); //seek for 30 seconds
}); });
player.on('stop', (err, action) => { player.on('stop', (err, action) => {
if (err) { if (err) {
console.error('Error returned in the stop() callback.'); console.log(`err returned in stop() callback`);
return; return;
} }
console.info('stop callback invoked. State:' + player.state); console.log(`stop callback, state: ${player.state}`);
player.reset();
}); });
player.on('dataLoad', (err, action) => { player.on('dataLoad', (err, action) => {
if (err) { if (err) {
console.error('Error returned in the dataLoad() callback.'); console.log(`err returned in dataLoad() callback`);
return; return;
} }
console.info('dataLoad callback invoked. Current time: ' + player.currentTime); console.log(`dataLoad callback is called, cuurent time: ${player.currentTime}`);
console.info('Duration of the source:' + player.duration); console.log(`Duration of the source: ${player.duration}`);
player.play();
});
player.on('reset', (err, action) => {
if (err) {
console.error('Error returned in the reset() callback.');
return;
}
console.info('reset callback invoked.');
player.release();
}); });
player.on('finish', (err, action) => { player.on('finish', (err, action) => {
if (err) { if (err) {
console.error('Error returned in the finish() callback.'); console.log(`err returned in finish() callback`);
return; return;
} }
console.info('finish callback invoked.'); console.log(`Player finish callback is called`);
}); });
player.on('timeUpdate', (seekTime, action) => { player.on('timeUpdate', (err, action) => {
console.info('Seek time: ' + seekTime); if (err) {
console.info('Current player time: ' + player.currentTime); console.log(`err returned in timeUpdate() callback`);
var newTime = player.currentTime; return;
if(newTime == 30000) { }
console.info('Seek succeeded. New time: ' + newTime); console.log(`In timeupdate callback current time: ${player.currentTime}`);
var newTime = player.currenTime;
if(newTime = 30000) {
console.info('Seek success, new time : '+newTime);
} else { } else {
console.error('Seek failed: ', + newTime); console.info('Seek Failed');
} }
player.stop(); player.stop();
}); });
player.on('durationchange', (err, action) => {
if (err) {
console.log(`err returned in durationchange callback`);
return;
}
console.log(`Durationchange callback is called`);
});
player.on('error', (err) => { player.on('error', (err) => {
console.error('Player error: ${err.message}'); console.error(`player error: ${err.message}`);
}); });
``` ```
3. 启动播放。 3. 启动播放。
...@@ -234,6 +237,7 @@ ...@@ -234,6 +237,7 @@
var audioSourceMp3 = 'file://test.mp3'; var audioSourceMp3 = 'file://test.mp3';
player.src = audioSourceMp3; player.src = audioSourceMp3;
player.loop = true; player.loop = true;
player.play();
``` ```
...@@ -4,17 +4,11 @@ OpenHarmony使用了如下第三方开源软件,下表对各开源软件采用 ...@@ -4,17 +4,11 @@ OpenHarmony使用了如下第三方开源软件,下表对各开源软件采用
| :----- | :----- | :----- | | :----- | :----- | :----- |
| third_party_bounds_checking_function | Mulan Permissive Software License,Version 2 | 该License无强制开放源码义务条款。 | | third_party_bounds_checking_function | Mulan Permissive Software License,Version 2 | 该License无强制开放源码义务条款。 |
| third_party_cJSON | MIT License | 该License无强制开放源码义务条款。 | | third_party_cJSON | MIT License | 该License无强制开放源码义务条款。 |
| third_party_JSON-C | MIT License | 该License无强制开放源码义务条款。 |
| third_party_libuuid | BSD 3-Clause License | 该License无强制开放源码义务条款。 |
| third_party_popt | MIT License | 该License无强制开放源码义务条款。 |
| third_party_LVM2 | GPL V2.0 | 独立进程,不会导致受到GPL许可的影响。 |
| third_party_cryptsetup | GPL V2.0 | 独立进程,不会导致受到GPL许可的影响。|
| third_party_cmsis | Apache License V2.0 | 该License无强制开放源码义务条款。 | | third_party_cmsis | Apache License V2.0 | 该License无强制开放源码义务条款。 |
| third_party_curl | Curl License | 该License无强制开放源码义务条款。 | | third_party_curl | Curl License | 该License无强制开放源码义务条款。 |
| third_party_FatFs | FatFs license(BSD-style licenses) | 该License无强制开放源码义务条款。 | | third_party_FatFs | FatFs license(BSD-style licenses) | 该License无强制开放源码义务条款。 |
| third_party_FreeBSD | BSD 2-Clause License | 该License无强制开放源码义务条款。 | | third_party_FreeBSD | BSD 2-Clause License | 该License无强制开放源码义务条款。 |
| third_party_freetype | The FreeType Project License | 该License无强制开放源码义务条款。 | | third_party_freetype | The FreeType Project License | 该License无强制开放源码义务条款。 |
| third_party_giflib | MIT License | 该License无强制开放源码义务条款。 |
| third_party_googletest | BSD 3-Clause License | 该License无强制开放源码义务条款。 | | third_party_googletest | BSD 3-Clause License | 该License无强制开放源码义务条款。 |
| third_party_harfbuzz | MIT License | 该License无强制开放源码义务条款。 | | third_party_harfbuzz | MIT License | 该License无强制开放源码义务条款。 |
| third_party_iniparser | MIT License | 该License无强制开放源码义务条款。 | | third_party_iniparser | MIT License | 该License无强制开放源码义务条款。 |
...@@ -29,7 +23,6 @@ OpenHarmony使用了如下第三方开源软件,下表对各开源软件采用 ...@@ -29,7 +23,6 @@ OpenHarmony使用了如下第三方开源软件,下表对各开源软件采用
| third_party_musl | BSD 2-Clause License | 该License无强制开放源码义务条款。 | | third_party_musl | BSD 2-Clause License | 该License无强制开放源码义务条款。 |
| third_party_NuttX | BSD 3-Clause License | 该License无强制开放源码义务条款。 | | third_party_NuttX | BSD 3-Clause License | 该License无强制开放源码义务条款。 |
| third_party_openssl | OpenSSL License and Original SSLeay License | 该License无强制开放源码义务条款。 | | third_party_openssl | OpenSSL License and Original SSLeay License | 该License无强制开放源码义务条款。 |
| third_party_qrcodegen| MIT License | 该License无强制开放源码义务条款。 |
| third_party_unity | MIT License | 该License无强制开放源码义务条款。 | | third_party_unity | MIT License | 该License无强制开放源码义务条款。 |
| third_party_wpa_supplicant | BSD 3-Clause License | 该License无强制开放源码义务条款。 | | third_party_wpa_supplicant | BSD 3-Clause License | 该License无强制开放源码义务条款。 |
| third_party_zlib | zlib/libpng License | 该License无强制开放源码义务条款。 | | third_party_zlib | zlib/libpng License | 该License无强制开放源码义务条款。 |
...@@ -85,11 +78,3 @@ OpenHarmony使用了如下第三方开源软件,下表对各开源软件采用 ...@@ -85,11 +78,3 @@ OpenHarmony使用了如下第三方开源软件,下表对各开源软件采用
| third_party_weston | MIT license | 该License无强制开放源码义务条款。 | | third_party_weston | MIT license | 该License无强制开放源码义务条款。 |
| third_party_lz4 | BSD 2-Clause License | 该License无强制开放源码义务条款。 | | third_party_lz4 | BSD 2-Clause License | 该License无强制开放源码义务条款。 |
| third_party_bzip2 | bzip2 and libbzip2 License | 该License无强制开放源码义务条款。 | | third_party_bzip2 | bzip2 and libbzip2 License | 该License无强制开放源码义务条款。 |
| third_party_mksh | MirOS License | 该License无强制开放源码义务条款。 |
| third_party_toybox | Public Domain License | 该License无强制开放源码义务条款。 |
| third_party_optimized_routines | MIT License | 该License无强制开放源码义务条款。 |
| third_party_libsnd | LGPL v2.1 | 该License无强制开放源码义务条款。部分测试代码使用GPL-3.0-or-later协议,部分测试代码使用GPL-2.0-or-later协议 |
| third_party_pulseaudio | LGPL v2.1 | 该License无强制开放源码义务条款。 |
| third_party_ffmpeg | LGPL v2.1 | OpenHarmony采用动态链接方式使用LGPL许可证下的ffmpeg库,不会导致该项目其它代码受到LGPL许可证的影响。 |
| third_party_quickjs | MIT licence | 该License无强制开放源码义务条款。|
| third_party_icu | BSD 3-Clause License, ICU License, UNICODE INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE | License无强制开放源码义务条款。 |
...@@ -69,28 +69,28 @@ OpenHarmony也提供了一系列可选的系统组件,方便设备开发者按 ...@@ -69,28 +69,28 @@ OpenHarmony也提供了一系列可选的系统组件,方便设备开发者按
</td> </td>
<td class="cellrowborder" valign="top" width="35.61356135613561%" headers="mcps1.2.4.1.2 "><p id="p857711379158"><a name="p857711379158"></a><a name="p857711379158"></a>使用<span id="text5577237181514"><a name="text5577237181514"></a><a name="text5577237181514"></a>OpenHarmony</span>提供的基础能力</p> <td class="cellrowborder" valign="top" width="35.61356135613561%" headers="mcps1.2.4.1.2 "><p id="p857711379158"><a name="p857711379158"></a><a name="p857711379158"></a>使用<span id="text5577237181514"><a name="text5577237181514"></a><a name="text5577237181514"></a>OpenHarmony</span>提供的基础能力</p>
</td> </td>
<td class="cellrowborder" valign="top" width="35.91359135913591%" headers="mcps1.2.4.1.3 "><a name="ul1577103716159"></a><a name="ul1577103716159"></a><ul id="ul1577103716159"><li><a href="kernel/kernel.md">内核开发指南</a></li><li><a href="driver/Readme-CN.md">驱动开发指南</a></li><li><a href="subsystems/Readme-CN.md">子系统开发指南</a></li><li><a href="security/safety-safeguide-security.md">安全指南</a></li><li><a href="security/safety-protection-privacyguide.md">隐私保护</a></li></ul> <td class="cellrowborder" valign="top" width="35.91359135913591%" headers="mcps1.2.4.1.3 "><a name="ul1577103716159"></a><a name="ul1577103716159"></a><ul id="ul1577103716159"><li><a href="kernel/kernel.md">内核开发指南</a></li><li><a href="driver/Readme-CN.md">驱动开发指南</a></li><li><a href="subsystems/Readme-CN.md">子系统开发指南</a></li><li><a href="security/security-guidelines-overall.md">安全指南</a></li><li><a href="security/security-privacy-protection.md">隐私保护</a></li></ul>
</td> </td>
</tr> </tr>
<tr id="row10602193719152"><td class="cellrowborder" valign="top" width="28.472847284728473%" headers="mcps1.2.4.1.1 "><p id="p857873713152"><a name="p857873713152"></a><a name="p857873713152"></a>进阶开发</p> <tr id="row10602193719152"><td class="cellrowborder" valign="top" width="28.472847284728473%" headers="mcps1.2.4.1.1 "><p id="p857873713152"><a name="p857873713152"></a><a name="p857873713152"></a>进阶开发</p>
</td> </td>
<td class="cellrowborder" valign="top" width="35.61356135613561%" headers="mcps1.2.4.1.2 "><p id="p155782037201518"><a name="p155782037201518"></a><a name="p155782037201518"></a>结合系统能力开发智能设备</p> <td class="cellrowborder" valign="top" width="35.61356135613561%" headers="mcps1.2.4.1.2 "><p id="p155782037201518"><a name="p155782037201518"></a><a name="p155782037201518"></a>结合系统能力开发智能设备</p>
</td> </td>
<td class="cellrowborder" valign="top" width="35.91359135913591%" headers="mcps1.2.4.1.3 "><a name="ul257883731519"></a><a name="ul257883731519"></a><ul id="ul257883731519"><li><a href="guide/device-wifi.md">WLAN连接类产品</a></li><li><a href="guide/device-iotcamera-control.md">无屏摄像头类产品</a></li><li><a href="guide/device-camera.md">带屏摄像头类产品</a></li></ul> <td class="cellrowborder" valign="top" width="35.91359135913591%" headers="mcps1.2.4.1.3 "><a name="ul257883731519"></a><a name="ul257883731519"></a><ul id="ul257883731519"><li><a href="guide/device-wlan.md">WLAN连接类产品</a></li><li><a href="guide/device-iotcamera-control.md">无屏摄像头类产品</a></li><li><a href="guide/device-camera.md">带屏摄像头类产品</a></li></ul>
</td> </td>
</tr> </tr>
<tr id="row360273716155"><td class="cellrowborder" valign="top" width="28.472847284728473%" headers="mcps1.2.4.1.1 "><p id="p12579163711513"><a name="p12579163711513"></a><a name="p12579163711513"></a>移植适配</p> <tr id="row360273716155"><td class="cellrowborder" valign="top" width="28.472847284728473%" headers="mcps1.2.4.1.1 "><p id="p12579163711513"><a name="p12579163711513"></a><a name="p12579163711513"></a>移植适配</p>
</td> </td>
<td class="cellrowborder" valign="top" width="35.61356135613561%" headers="mcps1.2.4.1.2 "><a name="ul12579137121512"></a><a name="ul12579137121512"></a><ul id="ul12579137121512"><li>针对特定芯片做移植适配</li><li>对三方库进行移植适配</li></ul> <td class="cellrowborder" valign="top" width="35.61356135613561%" headers="mcps1.2.4.1.2 "><a name="ul12579137121512"></a><a name="ul12579137121512"></a><ul id="ul12579137121512"><li>针对特定芯片做移植适配</li><li>对三方库进行移植适配</li></ul>
</td> </td>
<td class="cellrowborder" valign="top" width="35.91359135913591%" headers="mcps1.2.4.1.3 "><a name="ul157903731520"></a><a name="ul157903731520"></a><ul id="ul157903731520"><li><a href="porting/transplant-minichip.md">轻量系统芯片移植指导</a></li><li><a href="porting/transplant-smallchip.md">小型系统芯片移植指导</a></li><li><a href="porting/transplant-thirdparty.md">三方库移植指导</a></li></ul> <td class="cellrowborder" valign="top" width="35.91359135913591%" headers="mcps1.2.4.1.3 "><a name="ul157903731520"></a><a name="ul157903731520"></a><ul id="ul157903731520"><li><a href="porting/porting-minichip.md">轻量系统芯片移植指导</a></li><li><a href="porting/porting-smallchip.md">小型系统芯片移植指导</a></li><li><a href="porting/porting-thirdparty.md">三方库移植指导</a></li></ul>
</td> </td>
</tr> </tr>
<tr id="row9601737181517"><td class="cellrowborder" valign="top" width="28.472847284728473%" headers="mcps1.2.4.1.1 "><p id="p25791037131519"><a name="p25791037131519"></a><a name="p25791037131519"></a>贡献组件</p> <tr id="row9601737181517"><td class="cellrowborder" valign="top" width="28.472847284728473%" headers="mcps1.2.4.1.1 "><p id="p25791037131519"><a name="p25791037131519"></a><a name="p25791037131519"></a>贡献组件</p>
</td> </td>
<td class="cellrowborder" valign="top" width="35.61356135613561%" headers="mcps1.2.4.1.2 "><p id="p45798376158"><a name="p45798376158"></a><a name="p45798376158"></a><span id="text16579133741518"><a name="text16579133741518"></a><a name="text16579133741518"></a>OpenHarmony</span>贡献功能组件</p> <td class="cellrowborder" valign="top" width="35.61356135613561%" headers="mcps1.2.4.1.2 "><p id="p45798376158"><a name="p45798376158"></a><a name="p45798376158"></a><span id="text16579133741518"><a name="text16579133741518"></a><a name="text16579133741518"></a>OpenHarmony</span>贡献功能组件</p>
</td> </td>
<td class="cellrowborder" valign="top" width="35.91359135913591%" headers="mcps1.2.4.1.3 "><a name="ul957919379156"></a><a name="ul957919379156"></a><ul id="ul957919379156"><li><a href="bundles/bundles-standard-rules.md">组件开发规范</a></li><li><a href="bundles/bundles-guide.md">组件开发指南</a></li><li><a href="bundles/bundles-demo.md">组件开发示例</a></li></ul> <td class="cellrowborder" valign="top" width="35.91359135913591%" headers="mcps1.2.4.1.3 "><a name="ul957919379156"></a><a name="ul957919379156"></a><ul id="ul957919379156"><li><a href="bundles/oem_bundle_standard_des.md">组件开发规范</a></li><li><a href="bundles/bundles-guide.md">组件开发指南</a></li><li><a href="bundles/bundles-demo.md">组件开发示例</a></li></ul>
</td> </td>
</tr> </tr>
<tr id="row260193701512"><td class="cellrowborder" valign="top" width="28.472847284728473%" headers="mcps1.2.4.1.1 "><p id="p95794372155"><a name="p95794372155"></a><a name="p95794372155"></a>参考</p> <tr id="row260193701512"><td class="cellrowborder" valign="top" width="28.472847284728473%" headers="mcps1.2.4.1.1 "><p id="p95794372155"><a name="p95794372155"></a><a name="p95794372155"></a>参考</p>
...@@ -139,7 +139,7 @@ OpenHarmony也提供了一系列可选的系统组件,方便设备开发者按 ...@@ -139,7 +139,7 @@ OpenHarmony也提供了一系列可选的系统组件,方便设备开发者按
</td> </td>
<td class="cellrowborder" valign="top" width="36.053605360536054%" headers="mcps1.2.4.1.2 "><p id="p136812535511"><a name="p136812535511"></a><a name="p136812535511"></a>使用<span id="text1068553195119"><a name="text1068553195119"></a><a name="text1068553195119"></a>OpenHarmony</span>提供的基础能力</p> <td class="cellrowborder" valign="top" width="36.053605360536054%" headers="mcps1.2.4.1.2 "><p id="p136812535511"><a name="p136812535511"></a><a name="p136812535511"></a>使用<span id="text1068553195119"><a name="text1068553195119"></a><a name="text1068553195119"></a>OpenHarmony</span>提供的基础能力</p>
</td> </td>
<td class="cellrowborder" valign="top" width="36.07360736073608%" headers="mcps1.2.4.1.3 "><a name="ul1954915235272"></a><a name="ul1954915235272"></a><ul id="ul1954915235272"><li><a href="kernel/kernel.md">内核开发指南</a></li><li><a href="driver/Readme-CN.md">驱动开发指南</a></li><li><a href="subsystems/Readme-CN.md">子系统开发指南</a></li><li><a href="security/safety-safeguide-security.md">安全指南</a></li><li><a href="security/safety-protection-privacyguide.md">隐私保护</a></li></ul> <td class="cellrowborder" valign="top" width="36.07360736073608%" headers="mcps1.2.4.1.3 "><a name="ul1954915235272"></a><a name="ul1954915235272"></a><ul id="ul1954915235272"><li><a href="kernel/kernel.md">内核开发指南</a></li><li><a href="driver/Readme-CN.md">驱动开发指南</a></li><li><a href="subsystems/Readme-CN.md">子系统开发指南</a></li><li><a href="security/security-guidelines-overall.md">安全指南</a></li><li><a href="security/security-privacy-protection.md">隐私保护</a></li></ul>
</td> </td>
</tr> </tr>
<tr id="row1368195345111"><td class="cellrowborder" valign="top" width="27.872787278727873%" headers="mcps1.2.4.1.1 "><p id="p16681853145115"><a name="p16681853145115"></a><a name="p16681853145115"></a>进阶开发</p> <tr id="row1368195345111"><td class="cellrowborder" valign="top" width="27.872787278727873%" headers="mcps1.2.4.1.1 "><p id="p16681853145115"><a name="p16681853145115"></a><a name="p16681853145115"></a>进阶开发</p>
...@@ -153,14 +153,14 @@ OpenHarmony也提供了一系列可选的系统组件,方便设备开发者按 ...@@ -153,14 +153,14 @@ OpenHarmony也提供了一系列可选的系统组件,方便设备开发者按
</td> </td>
<td class="cellrowborder" valign="top" width="36.053605360536054%" headers="mcps1.2.4.1.2 "><p id="p185185615284"><a name="p185185615284"></a><a name="p185185615284"></a>对三方库进行移植适配</p> <td class="cellrowborder" valign="top" width="36.053605360536054%" headers="mcps1.2.4.1.2 "><p id="p185185615284"><a name="p185185615284"></a><a name="p185185615284"></a>对三方库进行移植适配</p>
</td> </td>
<td class="cellrowborder" valign="top" width="36.07360736073608%" headers="mcps1.2.4.1.3 "><a name="ul14724164204819"></a><a name="ul14724164204819"></a><ul id="ul14724164204819"><li><a href="porting/transplant-thirdparty.md">三方库移植指导</a></li><li><a href="porting/standard-system-porting-guide.md">标准系统芯片移植指导</a></li></ul> <td class="cellrowborder" valign="top" width="36.07360736073608%" headers="mcps1.2.4.1.3 "><a name="ul14724164204819"></a><a name="ul14724164204819"></a><ul id="ul14724164204819"><li><a href="porting/porting-thirdparty.md">三方库移植指导</a></li><li><a href="porting/standard-system-porting-guide.md">标准系统芯片移植指导</a></li></ul>
</td> </td>
</tr> </tr>
<tr id="row869853125119"><td class="cellrowborder" valign="top" width="27.872787278727873%" headers="mcps1.2.4.1.1 "><p id="p3691530511"><a name="p3691530511"></a><a name="p3691530511"></a>贡献组件</p> <tr id="row869853125119"><td class="cellrowborder" valign="top" width="27.872787278727873%" headers="mcps1.2.4.1.1 "><p id="p3691530511"><a name="p3691530511"></a><a name="p3691530511"></a>贡献组件</p>
</td> </td>
<td class="cellrowborder" valign="top" width="36.053605360536054%" headers="mcps1.2.4.1.2 "><p id="p1469115335113"><a name="p1469115335113"></a><a name="p1469115335113"></a><span id="text6691253155112"><a name="text6691253155112"></a><a name="text6691253155112"></a>OpenHarmony</span>贡献功能组件</p> <td class="cellrowborder" valign="top" width="36.053605360536054%" headers="mcps1.2.4.1.2 "><p id="p1469115335113"><a name="p1469115335113"></a><a name="p1469115335113"></a><span id="text6691253155112"><a name="text6691253155112"></a><a name="text6691253155112"></a>OpenHarmony</span>贡献功能组件</p>
</td> </td>
<td class="cellrowborder" valign="top" width="36.07360736073608%" headers="mcps1.2.4.1.3 "><a name="ul87045395116"></a><a name="ul87045395116"></a><ul id="ul87045395116"><li><a href="bundles/bundles-standard-rules.md">组件开发规范</a></li><li><a href="bundles/bundles-guide.md">组件开发指南</a></li><li><a href="bundles/bundles-demo.md">组件开发示例</a></li></ul> <td class="cellrowborder" valign="top" width="36.07360736073608%" headers="mcps1.2.4.1.3 "><a name="ul87045395116"></a><a name="ul87045395116"></a><ul id="ul87045395116"><li><a href="bundles/oem_bundle_standard_des.md">组件开发规范</a></li><li><a href="bundles/bundles-guide.md">组件开发指南</a></li><li><a href="bundles/bundles-demo.md">组件开发示例</a></li></ul>
</td> </td>
</tr> </tr>
<tr id="row1170153125110"><td class="cellrowborder" valign="top" width="27.872787278727873%" headers="mcps1.2.4.1.1 "><p id="p16701253195118"><a name="p16701253195118"></a><a name="p16701253195118"></a>参考</p> <tr id="row1170153125110"><td class="cellrowborder" valign="top" width="27.872787278727873%" headers="mcps1.2.4.1.1 "><p id="p16701253195118"><a name="p16701253195118"></a><a name="p16701253195118"></a>参考</p>
......
# 组件开发指南 # 组件开发指南
- [组件开发规范](bundles-standard-rules.md) - [组件开发规范](oem_bundle_standard_des.md)
- [组件开发指南](bundles-guide.md) - [开发指南](bundles-guide.md)
- [组件开发指南](bundles-guide-overview.md) - [概述](bundles-guide-overview.md)
- [准备工作](bundles-guide-prepare.md) - [安装hpm命令行工具](bundles-guide-prepare.md)
- [组件开发](bundles-guide-develop.md) - [开发Bundle](bundles-guide-develop.md)
- [组件开发示例](bundles-demo.md) - [开发示例](bundles-demo.md)
- [HPM介绍](bundles-demo-hpmdescription.md) - [HPM介绍](bundles-demo-hpmdescription.md)
- [环境准备](bundles-demo-environment.md) - [编译环境准备](bundles-demo-environment.md)
- [操作实例](bundles-demo-devsample.md) - [操作实例](bundles-demo-devsample.md)
# 操作实例<a name="ZH-CN_TOPIC_0000001072143838"></a> # 操作实例<a name="ZH-CN_TOPIC_0000001072143838"></a>
环境准备好后,接下来本文以Hi3861平台为例,演示如何利用HPM进行组件的安装、编译和打包 环境准备好后,接下来本文以Hi3861平台为例,演示如何利用hpm进行发行版的安装、编译
1. 执行以下命令,初始化安装目录(目录名可自行设置): 1. 执行以下命令,创建目录,并根据模板dist创建一个默认工程(目录名可自行设置):
``` ```
mkdir test3861 mkdir test3861
cd test3861 cd test3861
hpm init -t dist hpm init -t dist myproduct
``` ```
初始化成功则显示: 创建成功则显示:
``` ```
Initialization finished. Initialization finished.
``` ```
2. 安装wifi\_iot发行版。 2. 安装hispark\_pegasus发行版。
``` ```
hpm install @ohos/wifi_iot hpm install @ohos/hispark_pegasus
``` ```
安装成功则显示: 安装成功则显示:
...@@ -31,11 +31,11 @@ ...@@ -31,11 +31,11 @@
>![](../public_sys-resources/icon-note.gif) **说明:** >![](../public_sys-resources/icon-note.gif) **说明:**
>Hi3516平台采用下述命令: >Hi3516平台采用下述命令:
>``` >```
>hpm install @ohos/ip_camera_hi3516dv300 >hpm install @ohos/hispark_taurus
>``` >```
>Hi3518平台采用下述命令: >Hi3518平台采用下述命令:
>``` >```
>hpm install @ohos/ip_camera_hi3518ev300 >hpm install @ohos/hispark_aries
>``` >```
3. 编译打包 3. 编译打包
......
# 环境准备<a name="ZH-CN_TOPIC_0000001071315859"></a> # 编译环境准备<a name="ZH-CN_TOPIC_0000001071315859"></a>
- [linux服务器](#section20979554791) - [linux服务器](#section20979554791)
- [安装Node.js](#section9954105413153) - [安装Node.js](#section9954105413153)
- [安装HPM](#section15937194904819) - [安装HPM命令行工具](#section15937194904819)
- [安装python环境](#section1621819180417) - [安装python环境](#section1621819180417)
- [安装文件打包工具](#section77617165913) - [安装文件打包工具](#section77617165913)
- [安装SCons](#section20558439191516) - [安装SCons](#section873135716233)
![](figure/3516dv300.png)
## linux服务器<a name="section20979554791"></a> ## linux服务器<a name="section20979554791"></a>
准备一台装有Ubuntu 16.04 及以上 64 位系统的linux服务器(hpm是支持windows的,但是目前OpenHarmony开源的Hi3861、Hi3516、Hi3518三个解决方案都只支持Ubuntu)。 准备一台装有Ubuntu 16.04 及以上 64 位系统的linux服务器(当前未完全支持window环境下的编译)。
将linux shell改为bash: 将linux shell改为bash:
...@@ -25,12 +27,6 @@ ln -s bash /bin/sh ...@@ -25,12 +27,6 @@ ln -s bash /bin/sh
## 安装Node.js<a name="section9954105413153"></a> ## 安装Node.js<a name="section9954105413153"></a>
>![](../public_sys-resources/icon-note.gif) **说明:**
>如果配置的源的nodejs版本太低,可以执行以下语句后再执行apt-get install:
>```
>curl -L https://deb.nodesource.com/setup_12.x | bash
>```
推荐安装 Node.js 12.x (包含 npm 6.14.4)或更高版本(推荐 12.13.0+): 推荐安装 Node.js 12.x (包含 npm 6.14.4)或更高版本(推荐 12.13.0+):
``` ```
...@@ -45,7 +41,7 @@ node --version # 查看nodejs版本 ...@@ -45,7 +41,7 @@ node --version # 查看nodejs版本
npm --version # 查看npm版本 npm --version # 查看npm版本
``` ```
## 安装HPM<a name="section15937194904819"></a> ## 安装HPM命令行工具<a name="section15937194904819"></a>
通过 Node.js 自带的 npm(使用默认的源 https://registry.npmjs.org/ )安装 hpm-cli 命令行工具: 通过 Node.js 自带的 npm(使用默认的源 https://registry.npmjs.org/ )安装 hpm-cli 命令行工具:
...@@ -59,7 +55,7 @@ npm install -g @ohos/hpm-cli ...@@ -59,7 +55,7 @@ npm install -g @ohos/hpm-cli
hpm config hpm config
``` ```
上述命令执行后将会显示hpm的默认配置,您可以根据自己的喜好对默认配置进行修改,以下是hpm的常用配置: 上述命令执行后将会显示hpm的默认配置,您可以根据实际情况对默认配置进行修改,以下是hpm的常用配置:
``` ```
registry = https://hpm.harmonyos.com # hpm注册中心地址,下载组件必须 registry = https://hpm.harmonyos.com # hpm注册中心地址,下载组件必须
...@@ -68,7 +64,7 @@ http_proxy = http://your-proxy-server:port # 配置HTTP代理 ...@@ -68,7 +64,7 @@ http_proxy = http://your-proxy-server:port # 配置HTTP代理
https_proxy = http://your-proxy-server:port # 配置HTTPS代理 https_proxy = http://your-proxy-server:port # 配置HTTPS代理
``` ```
hpm-cli的命令介绍可以参考:[hpm操作命令](bundles-standard-rules.md) hpm-cli的命令介绍可以参考:[hpm操作命令](oem_bundle_standard_des.md)
## 安装python环境<a name="section1621819180417"></a> ## 安装python环境<a name="section1621819180417"></a>
...@@ -115,7 +111,7 @@ sudo apt-get install mtools ...@@ -115,7 +111,7 @@ sudo apt-get install mtools
>![](../public_sys-resources/icon-note.gif) **说明:** >![](../public_sys-resources/icon-note.gif) **说明:**
>Hi3518和Hi3516两种平台需要安装打包工具,Hi3861平台不需要。 >Hi3518和Hi3516两种平台需要安装打包工具,Hi3861平台不需要。
## 安装SCons<a name="section20558439191516"></a> ## 安装SCons<a name="section873135716233"></a>
1. 打开Linux编译服务器终端。 1. 打开Linux编译服务器终端。
2. 运行如下命令,安装SCons安装包。 2. 运行如下命令,安装SCons安装包。
...@@ -131,7 +127,7 @@ sudo apt-get install mtools ...@@ -131,7 +127,7 @@ sudo apt-get install mtools
``` ```
**图 1** SCons安装成功界面,版本要求3.0.4以上<a name="fig235815252492"></a> **图 1** SCons安装成功界面,版本要求3.0.4以上<a name="fig235815252492"></a>
![](figure/SCons安装成功界面-版本要求3-0-4以上-21.png "SCons安装成功界面-版本要求3-0-4以上-21") ![](figure/SCons安装成功界面-版本要求3-0-4以上-26.png "SCons安装成功界面-版本要求3-0-4以上-26")
>![](../public_sys-resources/icon-note.gif) **说明:** >![](../public_sys-resources/icon-note.gif) **说明:**
......
# HPM介绍<a name="ZH-CN_TOPIC_0000001071487274"></a> # HPM介绍<a name="ZH-CN_TOPIC_0000001071487274"></a>
随着OpenHarmony正式开源,HPM包管理器也应运而生。HPM全称HarmonyOS Package Manager,是OpenHarmony组件包的管理和分发工具。HPM主要是面向设备开发者,用于获取/定制OpenHarmony源码,执行安装、编译、打包、升级等操作的工具集。本文档将向开发者介绍如何使用HPM工具进行OpenHarmony组件的安装、编译、打包等操作。 HPM全称HarmonyOS Package Manager,是OpenHarmonyBundle的管理和分发工具。HPM主要是面向HamronyOS开发者,用于获取/定制OpenHarmony源码,执行安装依赖、编译、打包、升级等操作的工具集。本文档将向开发者介绍如何使用HPM工具进行OpenHarmonyBundle的安装、编译、打包等操作。
# 组件开发示例<a name="ZH-CN_TOPIC_0000001157479397"></a> # 开发示例<a name="ZH-CN_TOPIC_0000001157479397"></a>
- **[HPM介绍](bundles-demo-hpmdescription.md)** - **[HPM介绍](bundles-demo-hpmdescription.md)**
- **[环境准备](bundles-demo-environment.md)** - **[编译环境准备](bundles-demo-environment.md)**
- **[操作实例](bundles-demo-devsample.md)** - **[操作实例](bundles-demo-devsample.md)**
......
# 组件开发<a name="ZH-CN_TOPIC_0000001051690861"></a> # 开发Bundle<a name="ZH-CN_TOPIC_0000001051690861"></a>
- [创建OpenHarmony组件](#section1976410130540) - [创建Bundle](#section717481119145)
- [新建组件](#section717481119145) - [将现有工程定义为Bundle](#section102861955201410)
- [改造组件](#section102861955201410) - [发布Bundle到HPM平台](#section1318574233211)
- [从模板创建组件](#section15882846181510) - [引用Bundle](#section57959284315)
- [编译组件](#section136732148541) - [全局安装Bundle](#section647375516313)
- [编译Bundle](#section7972161715325)
- [定义编译脚本](#section10274147111610) - [定义编译脚本](#section10274147111610)
- [执行编译](#section879301916172) - [执行编译](#section879301916172)
- [定义发行版](#section413216495619) - [定义发行版](#section127388393326)
- [定义脚本](#section11503171219190) - [定义脚本](#section11503171219190)
- [发行](#section4694125521912) - [编译发行版](#section4694125521912)
- [烧录](#section1746331545413) - [烧录](#section2061514431039)
- [运行调试](#section6742131615549)
## 创建OpenHarmony组件<a name="section1976410130540"></a>
创建OpenHarmony组件有如下几种方式: 创建OpenHarmonyBundle有如下几种方式:
- 从头开发一个全新的组件。 - 从头创建一个全新的Bundle。
- 将一个现有的非组件的代码改造成组件。 - 将一个现有的源码项目定义为Bundle。
- hpm提供了一些组件模板方便快速创建组件。
## 新建组件<a name="section717481119145"></a> ## 创建Bundle<a name="section717481119145"></a>
通常情况下,[HPM网站](https://hpm.harmonyOS.com)上能找到您开发常用的组件,如果现有的组件不能完全满足开发,这时可以自己动手开发一个组件 通常情况下,[HPM网站](https://hpm.harmonyOS.com)上能找到您开发常用的Bundle,如果现有的Bundle不能完全满足开发,这时可以自己动手开发一个Bundle
如果您愿意,可以将组件发布到HPM的仓库中供其他用户使用。假设要在D:/source目录下新建一个全新的组件my-bundle: 如果您愿意,可以将Bundle发布到HPM的仓库中供其他用户使用。
可以使用hpm init 创建该组件的脚手架代码,例如,进入D:/source目录,执行如下命令: 假设要在D:/source目录下新建一个全新的Bundle:my-bundle,可以使用hpm init 创建该Bundle的脚手架代码,例如,进入D:/source目录,执行如下命令:
``` ```
hpm init -t default -d demo my-bundle hpm init -t default -d demo mybundle
``` ```
会在 source 目录下生成如下文件 将使用'default' 模板 在当前目录下的demo路径下,创建一个名为mybundle的Bundle
``` ```
mybundle demo
├── bundle.json # 组件元数据描述文件 ├── headers # 头文件(样例)
├── example # 测试组件功能的示例 │ └── main.h
│ └── main.c └── src # 源代码(样例)
├── include # 组件的内部头文件 │ └─ main.c
│ └── mybundle.h ├── bundle.json # 元数据声明文件
├── README.md # 组件的简要说明 └── LICENSE # 许可协议文本
└── src # 组件的源代码 └── Makefile # 编译描述文件(样例)
└─ mybundle.c └── README.md # Bundle的自述文件
``` ```
接下来根据您的业务需要,实现组件内部的功能代码,完成代码开发后,通过git将代码(包括bundle.json文件)提交到组件代码托管仓库中(如gitee)。 接下来根据您的业务需要,实现Bundle内部的功能代码,以及编译脚本,完成代码开发后,通过git将代码(包括bundle.json文件)提交到组件代码托管仓库中(如gitee)。
>![](../public_sys-resources/icon-note.gif) **说明:**
>```
>hpm init -t {templatename} -d {dir} {name}
>```
>- -t \{templatename\} :指的是模板名称。
>- -d \{dir\}:是要创建的Bundle所存放的路径。
>- name:为要创建的Bundle名称。
hpm 除了提供了少量默认模板之外,其他模板均存储在服务器端,可以使用命令hpm search -t template 从服务器端搜索模板。
## 改造组件<a name="section102861955201410"></a> ![](figure/zh-cn_image_0000001141641532.png)
如果您已经有了代码,只是还不满足OpenHarmony的组件结构,需要改造成为hpm的组件包,只需要在当前要改造的代码目录下(例如mybundle2),执行如下命令,会提示您输入组件名称和版本。 ## 将现有工程定义为Bundle<a name="section102861955201410"></a>
如果您已经有了代码工程,需要分发的HPM平台,只需要在当前工程目录下(例如mybundle2),执行如下命令,会引导您输入组件名称和版本等信息。
``` ```
hpm init hpm init
``` ```
1. 输入名称后回车(如mybundle2)。 1. 输入名称后回车(如mybundle2)。
2. 输入版本后(如1.0.0)回车,在当前组件目录下会生成一个bundle.json文件。 2. 接下来依次输入版本、描述等信息后,会在当前目录下会生成一个bundle.json文件。
3. 打开bundle.json文件再添加其他的描述,这时候他已经是一个具备可发布的组件了 3. 也可以打开bundle.json文件
``` ```
$ hpm init $ hpm init
Your bundle will be created in dirname E:\demo\mybundle2 Your bundle will be created in directory ~\demo\mybundle2
? bundle name mybundel2 ? bundle name mybundel2
? version 1.0.0 ? version 1.0.0
Init finished! ...
Initialization finished.
``` ```
1. 打开bundle.json文件修改其他信息(如作者,代码仓库,代码目录,命令脚本,依赖组件等),如下 1. 打开bundle.json文件修改其他信息(如作者,代码仓库,代码目录,命令脚本,依赖组件等),如下(仅示意)
``` ```
{ {
"name": "mybundle2", "name": "mybundle2",
"version": "1.0.0", "version": "1.0.0",
"publishAs": "source", "publishAs": "code-segment",
"dirs":{ "dirs":{
".":[ ".":["README.md"],
"README.md" "src":["test.c"],
], "header":["header/test.h" ],
"src":[ "src/common":["src/common/foobar.txt"]
"test.c"
],
"header":[
"header/test.h"
],
"src/common":[
"src/common/foobar.txt"
]
}, },
"scripts": { "scripts": {
"build": "make -${args}" "build": "make -${args}"
}, },
"dependencies": { "dependencies": {
"@ohos/cjson": "^1.0.0", "@ohos/cjson": "^1.0.0",
"@ohos/": "^1.2.0" "@ohos/foobar": "^1.2.0"
} }
} }
``` ```
## 从模板创建组件<a name="section15882846181510"></a> ## 发布Bundle到HPM平台<a name="section1318574233211"></a>
hpm 除了提供了默认模板 default和simple两个简单的模板之外,其他模板均存储在服务器端 要在发布Bundle到HPM,你需要先具备账号,并创建组织,创建组织的条件及详细步骤请参考hpm网站上的帮助说明
可以使用命令hpm search -t template 从服务器端搜索模板 完成账号申请和组织创建(或者加入一个现有的组织)后,您需要根据个人的邀请码(在HPM网站的个人中心页查看),在本机生成公钥,并在HPM网站的个人中心配置
![](figure/zh-cn_image_0000001051452177.png) ```
hpm config set loginUser {your-invitation-code}
hpm gen-keys
```
生成的文件将会存放在 \~\\Users\\yourname\\.hpm\\key 下,将公钥文件\(publicKey\_your-accout.pem\)中内容拷贝到 HPM 个人中心的 SSH 公钥中。
根据description简要中的描述,找到适合的模板,基于模板可以快速创建一个组件的脚手架,执行如下初始化命令(指定-t -d 参数)。 完成上述操作后,你就具备了在您的组织内发布Bundle的权限了。
在bundle所在目录,执行命令hpm publish,将会完成组件的打包发布操作。
``` ```
hpm init -t {templatename} -d dir name hpm publish
``` ```
- \{templatename\} :指的是模板名称。 >![](../public_sys-resources/icon-note.gif) **说明:**
- -d 后面的参数dir:是要创建的组件所存放的路径。 >- 为避免Bundle名称冲突,发布的Bundle的名称需限定在组织范围内,即命名为@org\_name/bundle\_name的格式。
- name:为要创建的组件名称。 >- 你的账号也必须是org\_name内的成员,才可以发布或更新组织内的Bundle。
>- 发布的组件,需要通过安全及内容审核,才能正式生效。
## 引用Bundle<a name="section57959284315"></a>
通常开发一个项目,需要引用其他的组件以加快特定功能的开发,可以采用安装依赖的方式。
首先去HPM网站,根据关键字去搜索满足您的需求的组件,找到合适的组件后,将其引入到您的工程。
## 编译组件<a name="section136732148541"></a> 在您的bundle工程中(工程目录中必须包含bundle.json文件)执行如下命令:
```
$ hpm install @scope/the_bundle
```
引用的bundle将会被安装到你的工程所在的目录的 ohos\_bundle下
```
project
├── ohos_bundle
│ └── scope
│ └─ the_bundle # <---引用的组件将会出现在这
└── src
│ └─ main.c
├── bundle.json # 元数据声明文件
└── LICENSE
└── Makefile
└── README.md
```
打开bundle.json文件,可以看到bundle已经被引入到您的工程的依赖中。
```
{
"dependencies": {
"@scope/the_bundle": "^1.0.0"
}
}
```
完成代码开发后,需要对组件进行编译。hpm提供了命令集成的能力,您可以选择任意的适合项目的编译工具(如make,gcc,gn等等)。只需在当前项目的bundle.json文件中定义scripts脚本中的build命令,就可以通过执行hpm build执行编译。 您也可以一次性在此文件中编辑多个Bundle的依赖
```
{
"dependencies": {
"@scope/the_bundle1": "^1.0.0",
"@scope/the_bundle2": "^2.0.0",
"@scope/the_bundle3": "^3.0.0",
"@scope/the_bundle4": "^1.1.0"
}
}
```
再执行hpm install命令,将会一次性将所有未安装的Bundle一次性全部下载并安装完成。
## 全局安装Bundle<a name="section647375516313"></a>
如果引用的Bundle是多个项目共用的组件(如编译工具链),你可以全局安装
在您的bundle工程中(工程目录中必须包含bundle.json文件)执行如下命令:
```
$ hpm install -g @scope/the_tool
```
引用的bundle将会被安装到你在hpm config中设置的globalRepo所指定的目录下:
```
~\.hpm\global
│ └── scope
│ └─ the_tool # <---引用的组件将会出现在这
```
>![](../public_sys-resources/icon-note.gif) **说明:**
>- 在项目安装的Bundle,在执行hpm编译命令时可以通过引用环境变量 DEP\_SCOPE\_bundle\_name,例如:
>通过 hpm i @opensource/gn 安装后,可以编辑bundle.json中的编译脚本,如下:
>```
>"scripts": {
> "build": "${DEP_OPENSOURCE_gn}/gn --version"
> },
>```
>然后就可以通过执行hpm build将调用gn的功能。
>- 在全局安装的Bundle,可以通过设置系统环境变量,直接调用,或者hpm config set key value的方式,通过 $\{key\}/tool\_name 的方式 引用,例如:
>```
>hpm i -g @ohos/opensource/gn
>hpm config BUILD_SYS_GN ~/.hpm/global/ohos_bundles/opensource/gn
>```
>可以编辑bundle.json中的编译脚本,如下:
>```
>"scripts": {
> "build": "${BUILD_SYS_GN}/gn --version"
> },
>```
>然后就可以通过执行hpm build将调用gn的功能。
## 编译Bundle<a name="section7972161715325"></a>
完成代码开发后,如果Bundle的代码是可以独立编译的,可以配置编译工具和脚本以完成二进制的生成。
hpm具备命令集成的能力,您可以选择任意的适合项目所采用的语言编译工具(如make,gcc,gn等等)。只需在当前项目的bundle.json文件中定义scripts脚本中的build命令,就可以通过执行hpm build执行编译。
## 定义编译脚本<a name="section10274147111610"></a> ## 定义编译脚本<a name="section10274147111610"></a>
...@@ -172,37 +277,54 @@ hpm build ...@@ -172,37 +277,54 @@ hpm build
在完成一系列的编译动作后,显示build succeed。检查编译的输出结果: 在完成一系列的编译动作后,显示build succeed。检查编译的输出结果:
![](figure/zh-cn_image_0000001051770876.png) ![](figure/zh-cn_image_0000001188041297.png)
## 定义发行版<a name="section127388393326"></a>
## 定义发行版<a name="section413216495619"></a> 发行版的元数据文件中定义了其依赖的Bundles,以及如何编译、链接这些bundles,生成镜像文件。
发行版是将一组组件组合起来的,编译生成可以运行的OpenHarmony解决方案,里面包含了较多依赖的组件,以及以脚本形式描述如何完整编译、链接这些组件。 示例如下(以下示例的编译命令dist,采用hb编译框架描述)
## 定义脚本<a name="section11503171219190"></a> ## 定义脚本<a name="section11503171219190"></a>
bundle.json中定义 bundle.json中定义如下(示例)
``` ```
{ {
"name": "my_dist", "name": "@your/dist_name",
"version": "1.0.0", "version": "2.2.0",
"publishAs": "distribution", "publishAs": "distribution",
"description": "describe it",
"scripts": { "scripts": {
"dist": "make -${args}" "config_hb": "hb set -root $DEP_BUNDLE_BASE",
}, "dist": "PATH=/root/.local/bin:${DEP_OHOS_gn}:${DEP_OHOS_ninja}/ninja:${DEP_OHOS_llvm}/llvm/bin:${DEP_OHOS_hc_gen}/hc-gen:${PATH} && ./scripts/dist.sh"
"base": { },
"name": "dist-bundle",
"version": "1.0.0"
},
"envs": { "envs": {
"args": "x86" "debug": false
}, },
"dirs": {
"scripts": "scripts/*"
},
"dependencies": { "dependencies": {
} "@ohos/build_lite": "2.2.0",
"@ohos/gn": "1.1.1",
"@ohos/llvm": "1.1.1",
"@ohos/hc_gen": "1.1.0",
"@ohos/ninja": "1.1.0",
......
},
"ohos": {
"os": "2.2-Beta",
"board": "hi3516",
"kernel": "liteos-a"
},
"keywords": [ "hispark", "hi3516" ],
"repository": "https://gitee.com/openharmony/your-project",
"license": "Apache V2"
} }
``` ```
## 发行<a name="section4694125521912"></a> ## 编译发行版<a name="section4694125521912"></a>
在当前发行版根目录下,执行如下命令。 在当前发行版根目录下,执行如下命令。
...@@ -210,7 +332,7 @@ bundle.json中定义 ...@@ -210,7 +332,7 @@ bundle.json中定义
hpm dist hpm dist
``` ```
hpm-cli工具会自动执行编译,打包操作,将根据scripts定义的dist脚本生成镜像文件,如: hpm-cli工具会自动执行编译,生成镜像文件,如:
``` ```
out out
...@@ -218,23 +340,23 @@ out ...@@ -218,23 +340,23 @@ out
|-xx.file |-xx.file
``` ```
## 烧录<a name="section1746331545413"></a> ## 烧录<a name="section2061514431039"></a>
发行版的编译结果可以烧录到设备中运行,例如使用hiburn工具进行烧录。在发行版的bundle.json文件配置烧录参数。 发行版的编译结果可以烧录到设备中运行,例如使用hiburn工具进行烧录。在发行版的bundle.json文件配置烧录参数。
``` ```
"scripts": { "scripts": {
"flash": "{$DEP_HIBURN}/hiburn" "flash": "{$DEP_HIBURN}/hiburn"
}, },
``` ```
配置烧录相关的参数(参考烧录工具的说明进行配置)。 设置烧录命令行工具的所在路径,配置烧录相关的参数(参考烧录工具的说明进行配置)。
``` ```
hpm config set DEP_HIBURN {hiburn_path}
hpm run flash hpm run flash
``` ```
## 运行调试<a name="section6742131615549"></a> >![](../public_sys-resources/icon-note.gif) **说明:**
>上述仅描述如何定义bundle.json的样例,烧录工具取决于实际开发板所需的工具。
将发行版的镜像烧录到设备中后,就可以启动运行调试了,由于运行调试和具体的开发板和IDE调试工具相关,此处不再详细描述。
# 概述<a name="ZH-CN_TOPIC_0000001051452100"></a> # 概述<a name="ZH-CN_TOPIC_0000001051452100"></a>
本章节将简要介绍如何开发OpenHarmony组件和发行版,并通过命令行工具方式完成组件创建、开发、编译、烧录、调试等开发过程。 - [Bundle](#section196713235514)
- [Distribution](#section155387501033)
- 一个组件(bundle)通常和一个代码仓库对应,在代码的基础上增加bundle.json、README文件、LICENSE描述文件。
- 一个发行版(distribution)是由多个组件构成的。发行版中集合了一个完整系统的各种组件(如驱动、内核、框架、应用),可以用于设备的烧录。 本章节将介绍HarmonyOS中的Bundle相关概念以及如何定义Bundle,并以一个示例说明如何使用hpm命令行工具完成Bundle的创建、开发、编译、发布、安装使用的全过程。
**表 1** 组件和发行版的差异对比 ## Bundle<a name="section196713235514"></a>
<a name="table6287133615412"></a> Bundle是HarmonyOS中一个用来表示分发单元的术语,等同于包,一个Bundle中通常包含以下内容:
<table><thead align="left"><tr id="row17288183614415"><th class="cellrowborder" valign="top" width="16.24162416241624%" id="mcps1.2.4.1.1"><p id="p528818361545"><a name="p528818361545"></a><a name="p528818361545"></a>异同点</p>
</th> - 被分发的二进制文件(二进制类型)
<th class="cellrowborder" valign="top" width="33.31333133313331%" id="mcps1.2.4.1.2"><p id="p1288836247"><a name="p1288836247"></a><a name="p1288836247"></a>组件</p> - 被分发的源代码文件(源代码/代码片段类型)
</th> - 编译脚本(发行版类型需要)
<th class="cellrowborder" valign="top" width="50.44504450445044%" id="mcps1.2.4.1.3"><p id="p112885362418"><a name="p112885362418"></a><a name="p112885362418"></a>发行版</p> - 自身的说明文件
</th> - bundle.json:元数据声明(名称,版本,依赖等)
</tr> - LICENSE:许可协议文本
</thead> - README.md:自述文件
<tbody><tr id="row1728813361848"><td class="cellrowborder" valign="top" width="16.24162416241624%" headers="mcps1.2.4.1.1 "><p id="p2010613564815"><a name="p2010613564815"></a><a name="p2010613564815"></a>应用场景</p> - CHANGELOG.md:变更日志(可选)
</td>
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p1910555184818"><a name="p1910555184818"></a><a name="p1910555184818"></a>面向功能特性开发</p>
</td> >![](../public_sys-resources/icon-note.gif) **说明:**
<td class="cellrowborder" valign="top" width="50.44504450445044%" headers="mcps1.2.4.1.3 "><p id="p13871955484"><a name="p13871955484"></a><a name="p13871955484"></a>面向系统开发</p> >Bundle的类型可以分为二进制,源代码,代码片段,模板,插件,发行版等。一个Bundle可以依赖其他的Bundles,依赖关系为有向无环图
</td>
</tr> 一个Bundle被发布到HPM服务器(https://hpm.harmonyos.com)后,另外一些开发者就可以通过hpm包管理器下载安装使用 。
<tr id="row676745614472"><td class="cellrowborder" valign="top" width="16.24162416241624%" headers="mcps1.2.4.1.1 "><p id="p1028816365414"><a name="p1028816365414"></a><a name="p1028816365414"></a>内容</p>
</td> 一个Bundle在命名空间内拥有唯一的名称(命名格式为:@scope/name),可以进行独立的版本演进。
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p428812361042"><a name="p428812361042"></a><a name="p428812361042"></a>功能或特性的实现代码或二进制库</p>
</td> ## Distribution<a name="section155387501033"></a>
<td class="cellrowborder" valign="top" width="50.44504450445044%" headers="mcps1.2.4.1.3 "><p id="p328817366417"><a name="p328817366417"></a><a name="p328817366417"></a>依赖的组件清单及编译构建脚本</p>
</td> Distribution是HarmonyOS的发行版,是一个完整的操作系统版本,集合了各种Bundle(驱动,内核,框架,应用等),也通过Bundle在HPM平台分发。
</tr>
<tr id="row95114356"><td class="cellrowborder" valign="top" width="16.24162416241624%" headers="mcps1.2.4.1.1 "><p id="p184894513517"><a name="p184894513517"></a><a name="p184894513517"></a>完整程度</p> >![](../public_sys-resources/icon-note.gif) **说明:**
</td> >发行版的元数据中仅描述了依赖的Bundles以及如何编译该发行版的编译脚本,并不包含发行版的二进制镜像。下载发行版后,需要在本地将依赖的Bundles下载下来,安装编译后才能得到可用于烧录的系统镜像文件。
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p1951741155"><a name="p1951741155"></a><a name="p1951741155"></a>操作系统的一部分</p> >发行版可以继承,即在一个既有的发行版的基础上,通过增加/删除Bundle形成新的发行版,以实现发行版的定制。
</td>
<td class="cellrowborder" valign="top" width="50.44504450445044%" headers="mcps1.2.4.1.3 "><p id="p20521542512"><a name="p20521542512"></a><a name="p20521542512"></a>一个完整操作系统版本</p> **图 1** 组Bundle和Distribution的关系<a name="fig85033524124"></a>
</td>
</tr>
<tr id="row13581419518"><td class="cellrowborder" valign="top" width="16.24162416241624%" headers="mcps1.2.4.1.1 "><p id="p859171059"><a name="p859171059"></a><a name="p859171059"></a>编译后结果</p> ![](figure/组件和发行版的构成-英文.png)
</td>
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p259201355"><a name="p259201355"></a><a name="p259201355"></a>组件包</p>
</td>
<td class="cellrowborder" valign="top" width="50.44504450445044%" headers="mcps1.2.4.1.3 "><p id="p459414519"><a name="p459414519"></a><a name="p459414519"></a>系统镜像</p>
</td>
</tr>
</tbody>
</table>
**图 1** 组件和发行版的构成<a name="fig85033524124"></a>
![](figure/组件0924.png)
# 准备工作<a name="ZH-CN_TOPIC_0000001051770836"></a> # 安装hpm命令行工具<a name="ZH-CN_TOPIC_0000001051770836"></a>
- [硬件要求](#section98535485518) - [安装](#section14480912380)
- [安装Node.js和hpm命令行工具](#section106591616205311) - [配置hpm(可选)](#section138983413013)
- [更改hpm的配置(可选)](#section71821165412) - [下载OpenHarmony代码](#section669905815300)
- [下载OpenHarmony代码](#section102338221707)
- [安装开发依赖的组件](#section19233183315020)
## 硬件要求<a name="section98535485518"></a> 要进行Bundle的开发,需要安装包管理器hpm(HarmonyOS Package Manager),这是一个基于Node.js开发的跨平台的命令行工具,所以要运行hpm,需要先安装Node.js,然后可以npm 来安装hpm。
- 准备设备开发的开发板(如Hi3861、Hi3516DV300、Hi3518EV300) ## 安装<a name="section14480912380"></a>
- 主机电脑(Windows工作台)
- Linux服务器
**图 1** 硬件环境连接关系<a name="fig113816181847"></a>
![](figure/硬件环境连接关系.png "硬件环境连接关系")
## 安装Node.js和hpm命令行工具<a name="section106591616205311"></a>
1. 安装Node.js。 1. 安装Node.js。
...@@ -42,43 +33,41 @@ ...@@ -42,43 +33,41 @@
``` ```
## 更改hpm的配置(可选)<a name="section71821165412"></a> ## 配置hpm(可选)<a name="section138983413013"></a>
安装完hpm-cli命令行工具后,执行以下命令可以查看hpm配置: 安装完hpm-cli命令行工具后,如果需要更改配置信息(如代理,shell),执行以下命令可以查看hpm配置:
``` ```
hpm config hpm config
``` ```
上述命令执行后将会显示hpm的默认配置,您可以根据自己的喜好对默认配置进行修改,以下是hpm的常用配置: 上述命令执行后将会显示hpm的默认配置,您可以根据自己需要对默认配置进行修改,以下是hpm的常用配置:
``` ```
registry = https://hpm.harmonyos.com/hpm/registry/api # hpm注册中心地址,下载组件必须 registry = https://hpm.harmonyos.com
login = https://hpm.harmonyos.com/hpm/auth/pk # hpm处理登录地址,发布组件必须 ### login Settings
loginUser = {your-account} # 配置hpm登录账号,发布组件必须 # loginUser = invitation_code
shellPath = C:\WINDOWS\System32\cmd.exe # hpm命令执行使用的shell
globalRepo = C:\Users\yourname\.global # 配置全局安装的组件存放路径 #### Path Settings
http_proxy = http://your-proxy-server:port # 配置HTTP代理 shellPath = C:\WINDOWS\System32\cmd.exe
https_proxy = http://your-proxy-server:port # 配置HTTPS代理 # shellPath = C:\Program Files\Git\bin\sh.exe
# globalRepo = C:\Users\username\.hpm\global
#### Network Settings
# no_proxy = *.server.com
# http_proxy = http://user:pwd@proxy_server:port
# https_proxy = http://user:pwd@proxy_server:port
# strictSsl = true
#### Other Settings
# privateSupport = true|false
# ignoreBundles = @ohos/llvm,@ohos/gn,
# OSPlatform = Auto|linux|darwin|win32
``` ```
hpm-cli的命令介绍可以参考:[hpm操作命令](bundles-guide-overview.md) hpm-cli的命令介绍可以参考:[hpm操作命令](bundles-guide-overview.md)
## 下载OpenHarmony代码<a name="section102338221707"></a> ## 下载OpenHarmony代码<a name="section669905815300"></a>
参考[《源码获取》](../get-code/sourcecode-acquire.md) 参考[《源码获取》](../get-code/sourcecode-acquire.md)
## 安装开发依赖的组件<a name="section19233183315020"></a>
hpm包管理器将常用开发开发工具(如烧录,编译,压缩等)也发布成了组件。可以通过如下命令方式进行安装,执行完该命令后,系统会自动将开发依赖的工具下载安装,且这些组件只需全局安装一次。
```
hpm i -g @ohos/llvm
hpm i -g @ohos/ninja
hpm i -g @ohos/gn
hpm i -g @ohos/hc_gen
hpm i -g @ohos/sysroot
```
这是一组开发工具的组件包(如包含gn,ninja等工具),有了这些开发态的组件,就可以进行常规的源码组件的开发了。
# 组件开发指南<a name="ZH-CN_TOPIC_0000001157319417"></a> # 开发指南<a name="ZH-CN_TOPIC_0000001157319417"></a>
- **[概述](bundles-guide-overview.md)** - **[概述](bundles-guide-overview.md)**
- **[准备工作](bundles-guide-prepare.md)** - **[安装hpm命令行工具](bundles-guide-prepare.md)**
- **[组件开发](bundles-guide-develop.md)** - **[开发Bundle](bundles-guide-develop.md)**
# 组件开发指南<a name="ZH-CN_TOPIC_0000001111039520"></a> # HPM bundle<a name="ZH-CN_TOPIC_0000001111039520"></a>
- **[组件开发规范](bundles-standard-rules.md)** - **[组件开发规范](oem_bundle_standard_des.md)**
- **[组件开发指南](bundles-guide.md)** - **[开发指南](bundles-guide.md)**
- **[组件开发示例](bundles-demo.md)** - **[开发示例](bundles-demo.md)**
# 驱动使用指南 # 驱动使用指南
- [HDF驱动框架](driver.md) - [HDF驱动框架](driver-hdf.md)
- [HDF开发概述](driver-hdf-overview.md) - [HDF开发概述](driver-hdf-overview.md)
- [驱动开发](driver-hdf-development.md) - [驱动开发](driver-hdf-development.md)
- [驱动服务管理](driver-hdf-servicemanage.md) - [驱动服务管理](driver-hdf-servicemanage.md)
......
...@@ -66,7 +66,6 @@ HDF框架以组件化的驱动模型作为核心设计思路,为开发者提 ...@@ -66,7 +66,6 @@ HDF框架以组件化的驱动模型作为核心设计思路,为开发者提
HDF_INIT(g_sampleDriverEntry); HDF_INIT(g_sampleDriverEntry);
``` ```
2. 驱动编译 2. 驱动编译
- 驱动代码的编译必须要使用HDF框架提供的Makefile模板进行编译。 - 驱动代码的编译必须要使用HDF框架提供的Makefile模板进行编译。
...@@ -86,7 +85,6 @@ HDF框架以组件化的驱动模型作为核心设计思路,为开发者提 ...@@ -86,7 +85,6 @@ HDF框架以组件化的驱动模型作为核心设计思路,为开发者提
LIB_SUBDIRS += #驱动代码Makefile的目录 LIB_SUBDIRS += #驱动代码Makefile的目录
``` ```
3. 驱动配置 3. 驱动配置
HDF使用HCS作为配置描述源码,HCS详细介绍参考[配置管理](driver-hdf-manage.md)介绍。 HDF使用HCS作为配置描述源码,HCS详细介绍参考[配置管理](driver-hdf-manage.md)介绍。
......
# HDF驱动框架<a name="ZH-CN_TOPIC_0000001157319419"></a>
- **[HDF开发概述](driver-hdf-overview.md)**
- **[驱动开发](driver-hdf-development.md)**
- **[驱动服务管理](driver-hdf-servicemanage.md)**
- **[驱动消息机制管理](driver-hdf-news.md)**
- **[配置管理](driver-hdf-manage.md)**
- **[HDF开发实例](driver-hdf-sample.md)**
...@@ -66,7 +66,6 @@ Display驱动模型基于HDF驱动框架、Platform接口及OSAL接口开发, ...@@ -66,7 +66,6 @@ Display驱动模型基于HDF驱动框架、Platform接口及OSAL接口开发,
根据LCD硬件接口,使用Platform接口层提供的I2C、SPI、MIPI等接口,下载LCD初始化序列,初始化参数序列可以参考LCD供应商提供的SPEC。 根据LCD硬件接口,使用Platform接口层提供的I2C、SPI、MIPI等接口,下载LCD初始化序列,初始化参数序列可以参考LCD供应商提供的SPEC。
4. 根据需求实现HDF框架其他接口,比如Release接口。 4. 根据需求实现HDF框架其他接口,比如Release接口。
5. 根据需求使用HDF框架可创建其他设备节点,用于业务逻辑或者调试功能。 5. 根据需求使用HDF框架可创建其他设备节点,用于业务逻辑或者调试功能。
......
...@@ -68,14 +68,13 @@ Touchscreen器件的硬件接口相对简单,根据PIN脚的属性,可以简 ...@@ -68,14 +68,13 @@ Touchscreen器件的硬件接口相对简单,根据PIN脚的属性,可以简
通常情况下,touchscreen驱动IC和LCD驱动IC是相互分离的,这种情况下,touchscreen驱动IC一般同时需要1.8v和3.3v两路供电。随着芯片演进,业内已有touchscreen驱动IC和LCD驱动IC集成在一颗IC中的芯片案例,对touchscreen而言,只需要关注1.8v供电即可,其内部需要的3.3v电源,会在驱动IC内部从LCD的VSP电源(典型值5.5V)中分出来。 通常情况下,touchscreen驱动IC和LCD驱动IC是相互分离的,这种情况下,touchscreen驱动IC一般同时需要1.8v和3.3v两路供电。随着芯片演进,业内已有touchscreen驱动IC和LCD驱动IC集成在一颗IC中的芯片案例,对touchscreen而言,只需要关注1.8v供电即可,其内部需要的3.3v电源,会在驱动IC内部从LCD的VSP电源(典型值5.5V)中分出来。
2. **IO控制接口** 2. **IO控制接口**
- Reset:reset管脚,用于在系统休眠、唤醒时,由主机侧对驱动IC进行复位操作。 - Reset:reset管脚,用于在系统休眠、唤醒时,由主机侧对驱动IC进行复位操作。
- INT:中断管脚,需要在驱动初始化时,配置为输入上拉状态。在驱动IC检测到外部触摸信号后,通过操作中断管脚来触发中断,器件驱动则会在中断处理函数中进行报点数据读取等操作。 - INT:中断管脚,需要在驱动初始化时,配置为输入上拉状态。在驱动IC检测到外部触摸信号后,通过操作中断管脚来触发中断,器件驱动则会在中断处理函数中进行报点数据读取等操作。
3. **通信接口** 3. **通信接口**
- I2C:由于touchscreen的报点数据量相对较少,所以一般选用I2C方式传输数据。I2C的具体协议及对应操作接口,可以参考Platform接口层中的[“I2C”使用指南](drive-platform-i2c-des.md#section1695201514281) - I2C:由于touchscreen的报点数据量相对较少,所以一般选用I2C方式传输数据。I2C的具体协议及对应操作接口,可以参考Platform接口层中的[“I2C”使用指南](driver-platform-i2c-des.md#section1695201514281)
- SPI:部分厂商,由于需要传递的数据不止报点坐标,而是需要获取基础容值,数据量较大,所以会选用SPI通信方式。SPI的具体协议及对应操作接口,可以参考Platform接口层中的[“SPI” 使用指南](drive-platform-spi-des.md#section71363452477) - SPI:部分厂商,由于需要传递的数据不止报点坐标,而是需要获取基础容值,数据量较大,所以会选用SPI通信方式。SPI的具体协议及对应操作接口,可以参考Platform接口层中的[“SPI” 使用指南](driver-platform-spi-des.md#section71363452477)
## 开发指导<a name="section65745222184"></a> ## 开发指导<a name="section65745222184"></a>
...@@ -109,7 +108,7 @@ Input驱动模型是基于HDF框架、Platform接口和OSAL接口开发,不区 ...@@ -109,7 +108,7 @@ Input驱动模型是基于HDF框架、Platform接口和OSAL接口开发,不区
3. 实现器件差异化适配接口 3. 实现器件差异化适配接口
根据硬件单板设计的通信接口,使用Platform接口层提供的管脚操作接口配置对应的复位管脚、中断管脚以及电源操作,对于GPIO的操作,可参考[GPIO操作接口指导](drive-platform-gpio-des.md#section259614242196) 根据硬件单板设计的通信接口,使用Platform接口层提供的管脚操作接口配置对应的复位管脚、中断管脚以及电源操作,对于GPIO的操作,可参考[GPIO操作接口指导](driver-platform-gpio-des.md#section259614242196)
## 开发实例<a name="section263714411191"></a> ## 开发实例<a name="section263714411191"></a>
......
...@@ -405,7 +405,7 @@ static int32_t TestCaseI2c(void) ...@@ -405,7 +405,7 @@ static int32_t TestCaseI2c(void)
} }
OsalMSleep(10); OsalMSleep(10);
/* 从TP-IC的0xDO寄存器连续读7字节数据 */ /* 从TP-IC的0xD5寄存器连续读7字节数据 */
ret = TpI2cReadReg(&tpDevice, 0xD5, bufRead, 7); ret = TpI2cReadReg(&tpDevice, 0xD5, bufRead, 7);
if (ret != HDF_SUCCESS) { if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: tp i2c read reg fail!:%d", __func__, ret); HDF_LOGE("%s: tp i2c read reg fail!:%d", __func__, ret);
......
...@@ -224,7 +224,7 @@ int32\_t SpiGetCfg\(DevHandle handle, struct SpiCfg \*cfg\); ...@@ -224,7 +224,7 @@ int32\_t SpiGetCfg\(DevHandle handle, struct SpiCfg \*cfg\);
``` ```
int32_t ret; int32_t ret;
struct SpiCfg cfg = {0}; /* SPI配置信息*/ struct SpiCfg cfg = {0}; /* SPI配置信息*/
ret = SpiGetCfg(spiHandle, &cfg); /* 配置SPI设备属性 */ ret = SpiGetCfg(spiHandle, &cfg); /* 获取SPI设备属性 */
if (ret != 0) { if (ret != 0) {
HDF_LOGE("SpiGetCfg: failed, ret %d\n", ret); HDF_LOGE("SpiGetCfg: failed, ret %d\n", ret);
} }
......
# 驱动使用指南<a name="ZH-CN_TOPIC_0000001111039544"></a> # 驱动使用指南<a name="ZH-CN_TOPIC_0000001111039544"></a>
- **[HDF开发概述](driver-hdf-overview.md)** - **[HDF驱动框架](driver-hdf.md)**
- **[驱动开发](driver-hdf-development.md)**
- **[驱动服务管理](driver-hdf-servicemanage.md)**
- **[驱动消息机制管理](driver-hdf-news.md)**
- **[配置管理](driver-hdf-manage.md)**
- **[HDF开发实例](driver-hdf-sample.md)**
- **[平台驱动](driver-platform.md)** - **[平台驱动](driver-platform.md)**
......
# 获取源码 # 获取源码
- [获取源码](sourcecode.md) - [获取源码](sourcecode.md)
- [源码获取](sourcecode-acquire.md) - [源码获取](sourcecode-acquire.md)
- [获取工具](gettools.md)
- [获取工具](gettools.md) - [Docker编译环境](gettools-acquire.md)
- [Docker编译环境](gettools-acquire.md) - [IDE](gettools-ide.md)
- [IDE](gettools-ide.md) \ No newline at end of file
...@@ -287,7 +287,6 @@ docker\_dist是一个[HPM](https://hpm.harmonyos.com/)系统中的模板组件 ...@@ -287,7 +287,6 @@ docker\_dist是一个[HPM](https://hpm.harmonyos.com/)系统中的模板组件
hpm run docker hpm run docker
``` ```
以上两种方式以@ohos/hispark\_taurus为例,执行成功结果如下: 以上两种方式以@ohos/hispark\_taurus为例,执行成功结果如下:
``` ```
......
...@@ -9,7 +9,7 @@ HUAWEI DevEco Device Tool是OpenHarmony面向智能设备开发者提供的一 ...@@ -9,7 +9,7 @@ HUAWEI DevEco Device Tool是OpenHarmony面向智能设备开发者提供的一
Huawei DevEco Device Tool支持 OpenHarmony设备开发的演进路标如下: Huawei DevEco Device Tool支持 OpenHarmony设备开发的演进路标如下:
![](figure/3-20.png) ![](figure/3-27.png)
## 获取应用开发工具(HUAWEI DevEco Studio)<a name="section0904101019258"></a> ## 获取应用开发工具(HUAWEI DevEco Studio)<a name="section0904101019258"></a>
......
...@@ -21,12 +21,9 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及 ...@@ -21,12 +21,9 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及
开源代码仓库地址:[https://openharmony.gitee.com](https://openharmony.gitee.com) 开源代码仓库地址:[https://openharmony.gitee.com](https://openharmony.gitee.com)
>![](../public_sys-resources/icon-note.gif) **说明:**
>当前的OpenHarmony源代码仅支持在Linux环境下编译。
## 源码获取概述<a name="section12763342204"></a> ## 源码获取概述<a name="section12763342204"></a>
本文档将介绍如何获取OpenHarmony源码并说明OpenHarmony的源码目录结构。OpenHarmony的代码以[组件](../bundles/bundles-standard-rules.md)的形式开放,开发者可以通过如下其中一种方式获取: 本文档将介绍如何获取OpenHarmony源码并说明OpenHarmony的源码目录结构。OpenHarmony的代码以[组件](../bundles/oem_bundle_standard_des.md)的形式开放,开发者可以通过如下其中一种方式获取:
- **获取方式1**:从代码仓库获取。通过repo或git工具从代码仓库中下载,此方式可获取最新代码。 - **获取方式1**:从代码仓库获取。通过repo或git工具从代码仓库中下载,此方式可获取最新代码。
- **获取方式2**:通过HPM包管理器获取。在[HPM](https://hpm.harmonyos.com)网站,查找满足需求的开源发行版,直接下载(或者定制后下载),再通过hpm-cli命令工具将所需的组件及工具链下载、安装到本地。 - **获取方式2**:通过HPM包管理器获取。在[HPM](https://hpm.harmonyos.com)网站,查找满足需求的开源发行版,直接下载(或者定制后下载),再通过hpm-cli命令工具将所需的组件及工具链下载、安装到本地。
...@@ -159,7 +156,6 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及 ...@@ -159,7 +156,6 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及
![](figure/zh-cn_image_0000001119915556.png) ![](figure/zh-cn_image_0000001119915556.png)
2. 了解发行版详情。 2. 了解发行版详情。
1. 仔细阅读发行版的说明信息,以了解使用场景、特性、组件构成、使用方法以及如何进行定制化,如下图所示。 1. 仔细阅读发行版的说明信息,以了解使用场景、特性、组件构成、使用方法以及如何进行定制化,如下图所示。
...@@ -182,7 +178,6 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及 ...@@ -182,7 +178,6 @@ OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及
![](figure/zh-cn_image_0000001166715379.png) ![](figure/zh-cn_image_0000001166715379.png)
4. 下载安装组件。 4. 下载安装组件。
1. 解压下载的压缩文件,用命令行工具CMD(Linux下的Shell终端) 1. 解压下载的压缩文件,用命令行工具CMD(Linux下的Shell终端)
2. 在解压后的文件目录下执行hpm install指令 2. 在解压后的文件目录下执行hpm install指令
......
# 术语 # 术语
- [术语](glossary.md) [术语](glossary.md)
\ No newline at end of file
...@@ -97,3 +97,6 @@ ...@@ -97,3 +97,6 @@
- Standard System,标准系统:面向应用处理器,例如Arm Cortex-A的设备,参考内存≥128MiB,提供增强的交互能力,提供3D GPU以及硬件合成能力,提供更多控件以及动效更丰富的图形能力,提供完整的应用框架。典型产品有高端的冰箱显示屏等。 - Standard System,标准系统:面向应用处理器,例如Arm Cortex-A的设备,参考内存≥128MiB,提供增强的交互能力,提供3D GPU以及硬件合成能力,提供更多控件以及动效更丰富的图形能力,提供完整的应用框架。典型产品有高端的冰箱显示屏等。
- **[术语](glossary.md)**
# 设备开发指南 # 设备开发指南
- [WLAN连接类产品](device-wifi.md) - [轻量和小型系统设备](device-lite.md)
- [LED外设控制](device-wifi-led-outcontrol.md) - [WLAN连接类产品](device-wlan.md)
- [集成三方SDK](device-wifi-sdk.md) - [LED外设控制](oem_wifi_sdk_des.md)
- [集成三方SDK](device-wlan-sdk.md)
- [无屏摄像头类产品](device-iotcamera.md) - [无屏摄像头类产品](device-iotcamera.md)
- [概述](device-iotcamera-control-overview.md) - [摄像头控制](device-iotcamera-control.md)
- [示例开发](device-iotcamera-control-demo.md) - [概述](device-iotcamera-control-overview.md)
- [拍照开发指导](device-iotcamera-control-demo-photodevguide.md) - [示例开发](device-iotcamera-control-demo.md)
- [录像开发指导](device-iotcamera-control-demo-videodevguide.md) - [拍照开发指导](device-iotcamera-control-demo-photodevguide.md)
- [录像开发指导](device-iotcamera-control-demo-videodevguide.md)
- [应用实例](device-iotcamera-control-example.md) - [应用实例](device-iotcamera-control-example.md)
- [带屏摄像头类产品](device-camera.md)
- [带屏摄像头类产品](device-camera.md) - [屏幕和摄像头控制](device-camera-control.md)
- [屏幕和摄像头控制](device-camera-control.md) - [概述](device-camera-control-overview.md)
- [概述](device-camera-control-overview.md) - [示例开发](device-camera-control-demo.md)
- [示例开发](device-camera-control-demo.md) - [拍照开发指导](device-camera-control-demo-photoguide.md)
- [拍照开发指导](device-camera-control-demo-photoguide.md) - [录像开发指导](device-camera-control-demo-videoguide.md)
- [录像开发指导](device-camera-control-demo-videoguide.md) - [预览开发指导](device-camera-control-demo-previewguide.md)
- [预览开发指导](device-camera-control-demo-previewguide.md) - [应用实例](device-camera-control-example.md)
- [视觉应用开发](device-camera-visual.md)
- [应用实例](device-camera-control-example.md) - [概述](device-camera-visual-overview.md)
- [开发准备](device-camera-visual-prepare.md)
- [视觉应用开发](device-camera-visual.md) - [添加页面](device-camera-visual-addpage.md)
- [概述](device-camera-visual-overview.md) - [开发首页](device-camera-visual-firstpage.md)
- [开发准备](device-camera-visual-prepare.md) - [开发详情页](device-camera-visual-details.md)
- [添加页面](device-camera-visual-addpage.md) - [调试打包](device-camera-visual-debug.md)
- [开发首页](device-camera-visual-first-page.md) - [真机运行](device-camera-visual-run.md)
- [开发详情页](device-camera-visual-details.md) - [常见问题](device-camera-visual-faqs.md)
- [调试打包](device-camera-visual-debug.md) - [标准系统设备](device-standard.md)
- [真机运行](device-camera-visual-run.md) - [时钟应用开发指导](device-clock-guide.md)
- [常见问题](device-camera-visual-faqs.md) - [平台驱动开发示例](device-driver-demo.md)
- [外设驱动开发示例](device-outerdriver-demo.md)
- [时钟应用开发指导](device-clock-guide.md)
- [平台驱动开发示例](device-driver-demo.md)
- [外设驱动开发示例](device-outerdriver-demo.md)
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册