diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..b1cb82477ae27e5c870a155a7f87f3e39a22fd95 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,78 @@ +{ + "name": "napi_generator", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "@types/node": "^22.10.1", + "@types/tar": "^6.1.13", + "@types/typescript": "^2.0.0", + "@types/vscode": "^1.94.0" + } + }, + "node_modules/@types/node": { + "version": "22.10.1", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-22.10.1.tgz", + "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", + "dev": true, + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/@types/tar": { + "version": "6.1.13", + "resolved": "https://registry.npmmirror.com/@types/tar/-/tar-6.1.13.tgz", + "integrity": "sha512-IznnlmU5f4WcGTh2ltRu/Ijpmk8wiWXfF0VA4s+HPjHZgvFggk1YaIkbo5krX/zUCzWF8N/l4+W/LNxnvAJ8nw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "minipass": "^4.0.0" + } + }, + "node_modules/@types/typescript": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/@types/typescript/-/typescript-2.0.0.tgz", + "integrity": "sha512-WMEWfMISiJ2QKyk5/dSdgL0ZwP//PZj0jmDU0hMh51FmLq4WIYzjlngsUQZXejQL+QtkXJUOGjb3G3UCvgZuSQ==", + "deprecated": "This is a stub types definition for TypeScript (https://github.com/Microsoft/TypeScript). TypeScript provides its own type definitions, so you don't need @types/typescript installed!", + "dev": true, + "dependencies": { + "typescript": "*" + } + }, + "node_modules/@types/vscode": { + "version": "1.94.0", + "resolved": "https://registry.npmmirror.com/@types/vscode/-/vscode-1.94.0.tgz", + "integrity": "sha512-UyQOIUT0pb14XSqJskYnRwD2aG0QrPVefIfrW1djR+/J4KeFQ0i1+hjZoaAmeNf3Z2jleK+R2hv+EboG/m8ruw==", + "dev": true + }, + "node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmmirror.com/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/typescript": { + "version": "5.7.2", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000000000000000000000000000000000000..70b8227d26cea0f7f2563dc4a0a141fa2a26d628 --- /dev/null +++ b/package.json @@ -0,0 +1,8 @@ +{ + "devDependencies": { + "@types/node": "^22.10.1", + "@types/tar": "^6.1.13", + "@types/typescript": "^2.0.0", + "@types/vscode": "^1.94.0" + } +} diff --git a/src/vscode_plugin/docs/ohCrossCompile.md b/src/vscode_plugin/docs/ohCrossCompile.md new file mode 100644 index 0000000000000000000000000000000000000000..9bbd9cb0cb5d9fd11fc89f9eed77ea4448d677f3 --- /dev/null +++ b/src/vscode_plugin/docs/ohCrossCompile.md @@ -0,0 +1,189 @@ +# OpenHarmony 交叉编译功能 + +## 简介 + +OpenHarmony 交叉编译功能使开发者能够简单快速地调用 OpenHarmony SDK 中的 native 工具链工具,将三方库源码编译为 OpenHarmony 二进制文件和头文件。 + +用户只需简单操作,通过 vscode 交互界面确认编译方式、目标系统架构、 OpenHarmony SDK 中 native 工具链位置等信息后,本功能即可自动生成并拼接编译命令,送入终端执行编译与安装操作。对于所执行的具体命令,本功能还提供了清晰的配置文件,用户可根据实际情况对其进行灵活修改,以满足各种需求。 + +## 约束 + +**系统**:建议 Ubuntu 20.04 或 Windows 10 + +**依赖版本**:VS Code 1.62.0 + +------ + +若在 Windows 10 系统下使用本功能,则还需首先准备编译环境。本功能依赖于 mingw-w64 项目中 w64devkit 包所提供的 GCC 编译器来执行 make 操作,需下载并安装 w64devkit 工具: + +1. 下载 w64devkit 包。在链接 [Releases · skeeto/w64devkit](https://github.com/skeeto/w64devkit/releases) 中选择合适版本并下载; + +2. 安装 w64devkit 至合适路径,并将其安装目录下的 bin 目录加入系统环境变量 Path 中; + +3. 在 cmd 中执行命令`mingw32-make -v`以验证安装状态。若有如下输出则证明安装成功: + + ```cmd + Microsoft Windows [版本 10.0.19045.5247] + (c) Microsoft Corporation。保留所有权利。 + + C:\Users\Administrator>mingw32-make -v + GNU Make 4.4.1 + Built for x86_64-w64-mingw32 + Copyright (C) 1988-2023 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + ``` + + + +## 使用方法 + +### 初次使用 + +初次使用本功能时,使用流程为: + +1. 在 VSCode 资源管理器中,右键要编译的三方库源码目录,选择 **[OpenHarmony 交叉编译]** 选项以启动本功能:(以 cJSON 为例) + + ![](https://gitee.com/openharmony/napi_generator/raw/master/src/vscode_plugin/images/ohCrossCompile_menu.png) + +2. 本功能启动后,会自动检测所选目录中是否存在 Makefile 或 CMakeLists.txt 文件。若检测到只有二者其一存在,则会自动使用对应编译方式;若二者均存在,则需要用户指定具体编译方式:(以 cmake 方式为例) + + ![](https://gitee.com/openharmony/napi_generator/raw/master/src/vscode_plugin/images/ohCrossCompile_toolPick.png) + +3. 根据实际需求选择目标系统架构,可多选。若需编译64位二进制文件,则应勾选 **[arm64-v8a]** 架构;若需编译32位二进制文件,则应勾选 **[armeabi-v7a]** 架构。(以全选为例) + + ![](https://gitee.com/openharmony/napi_generator/raw/master/src/vscode_plugin/images/ohCrossCompile_archPick.png) + +4. 选择 OpenHarmony SDK 的来源是本地还是在线下载: + + ![](https://gitee.com/openharmony/napi_generator/raw/master/src/vscode_plugin/images/ohCrossCompile_sourcePick.png) + + - 若选择使用本地已有的 SDK ,则需选择本地 OpenHarmony SDK 目录下 native 文件夹所在路径: + + ![](https://gitee.com/openharmony/napi_generator/raw/master/src/vscode_plugin/images/ohCrossCompile_sourcePick_selectNative.png) + + - 若选择在线下载,则需选择所要下载 SDK 的具体版本: + + ![](https://gitee.com/openharmony/napi_generator/raw/master/src/vscode_plugin/images/ohCrossCompile_versionPick.png) + +5. 等待插件运行。若选择本地 SDK ,插件会自动拼接编译及安装命令,调起终端执行;若选择在线下载 SDK ,插件会在 SDK 下载解压完成后自动拼接编译及安装命令,调起终端执行。(以选择本地 SDK 为例) + + ![](https://gitee.com/openharmony/napi_generator/raw/master/src/vscode_plugin/images/ohCrossCompile_compilation.png) + +6. 查看安装文件。交叉编译完成后,所得二进制文件和头文件会自动安装在 `[三方库目录]/ohCrossCompile/[目标系统架构]/installed` 路径下: + + ![](https://gitee.com/openharmony/napi_generator/raw/master/src/vscode_plugin/images/ohCrossCompile_installedFiles.png) + +### 后续使用 + +后续再次使用本功能时,在 VSCode 资源管理器中右键要编译的三方库源码目录,选择 **[OpenHarmony 交叉编译]** 选项即可按以往配置直接开始交叉编译过程: + +![](https://gitee.com/openharmony/napi_generator/raw/master/src/vscode_plugin/images/ohCrossCompile_menu_2.png) + +### 高级配置 + +本功能的各有关配置存储在 `[三方库目录]/ohCrossCompile/config.json` 文件中,用户若有更高级的自定义需求,可以通过修改该配置文件来实现。如上例中,所生成的配置文件内容为: + +```json +{ + "settings": { + "compileTool": "cmake", + "nativePath": "D:/Public_sdk/11/ohos-sdk/windows/native", + "thirdPartyPath": "d:/TestWork/VariousTests/cJSON", + "ohArchitecture": [ + "arm64-v8a", + "armeabi-v7a" + ] + }, + "actions": [ + { + "compileTool": "cmake", + "ohArchitecture": "arm64-v8a", + "nativePath": "D:/Public_sdk/11/ohos-sdk/windows/native", + "thirdPartyPath": "d:/TestWork/VariousTests/cJSON", + "installPath": "d:/TestWork/VariousTests/cJSON/ohCrossCompile/arm64-v8a/installed", + "cwd": "d:/TestWork/VariousTests/cJSON/ohCrossCompile/arm64-v8a", + "commands": [ + { + "command": "cd d:/TestWork/VariousTests/cJSON/ohCrossCompile/arm64-v8a", + "arguments": [] + }, + { + "command": "D:/Public_sdk/11/ohos-sdk/windows/native/build-tools/cmake/bin/cmake.exe", + "arguments": [ + "-G \"MinGW Makefiles\"", + "-DCMAKE_SH=\"CMAKE_SH-NOTFOUND\"", + "-DCMAKE_TOOLCHAIN_FILE=D:/Public_sdk/11/ohos-sdk/windows/native/build/cmake/ohos.toolchain.cmake", + "-DCMAKE_INSTALL_PREFIX=d:/TestWork/VariousTests/cJSON/ohCrossCompile/arm64-v8a/installed", + "-DOHOS_ARCH=arm64-v8a", + "../..", + "-L" + ] + }, + { + "command": "mingw32-make", + "arguments": [] + }, + { + "command": "mingw32-make install", + "arguments": [] + } + ] + }, + { + "compileTool": "cmake", + "ohArchitecture": "armeabi-v7a", + "nativePath": "D:/Public_sdk/11/ohos-sdk/windows/native", + "thirdPartyPath": "d:/TestWork/VariousTests/cJSON", + "installPath": "d:/TestWork/VariousTests/cJSON/ohCrossCompile/armeabi-v7a/installed", + "cwd": "d:/TestWork/VariousTests/cJSON/ohCrossCompile/armeabi-v7a", + "commands": [ + { + "command": "cd d:/TestWork/VariousTests/cJSON/ohCrossCompile/armeabi-v7a", + "arguments": [] + }, + { + "command": "D:/Public_sdk/11/ohos-sdk/windows/native/build-tools/cmake/bin/cmake.exe", + "arguments": [ + "-G \"MinGW Makefiles\"", + "-DCMAKE_SH=\"CMAKE_SH-NOTFOUND\"", + "-DCMAKE_TOOLCHAIN_FILE=D:/Public_sdk/11/ohos-sdk/windows/native/build/cmake/ohos.toolchain.cmake", + "-DCMAKE_INSTALL_PREFIX=d:/TestWork/VariousTests/cJSON/ohCrossCompile/armeabi-v7a/installed", + "-DOHOS_ARCH=armeabi-v7a", + "../..", + "-L" + ] + }, + { + "command": "mingw32-make", + "arguments": [] + }, + { + "command": "mingw32-make install", + "arguments": [] + } + ] + } + ] +} +``` + +其中各字段含义为: + +- `settings`字段用以存储自动检测出的及与用户交互所获得的配置信息,包括编译方式`compileTool`、OpenHarmony SDK 中 native 工具目录位置`nativePath`、交叉编译的三方库目录位置`thirdPartyPath`、交叉编译的目标系统架构`ohArchitecture`。 +- `actions`字段用以存储交叉编译所执行的各动作(如编译64位三方库、编译32位三方库)。每个动作对象中的`installPath`字段存储了本次交叉编译动作的安装目录;`cwd`字段存储了在终端执行交叉编译命令时所处的路径;`commands`字段存储了各条按序执行的交叉编译命令,其下一级对应于各条命令的`arguments`字段则存储了该命令的附加参数。 + +当用户使用本功能时,插件会按序读取配置文件信息: + +1. 若`actions`字段为空,则会根据`settings`字段中信息,生成各动作对象的默认内容; +2. 若`actions`字段下,各动作对象中的`commands`字段为空,则会根据该动作对象`compileTool`、`ohArchitecture`、`nativePath`、`installPath`、`cwd`字段中信息,生成该动作对象的`commands`字段默认内容; +3. 最后根据各动作对象中的`commands`字段内容,拼接交叉编译命令,并送入终端执行。 + +在具体业务场景下,用户若有自定义需求,则既可以直接修改`commands`字段下的具体命令,也可以在修改上一级信息后删除`actions`字段或`commands`字段中的内容以使其重新生成,从而实现对不同实际需求的灵活适应。 + +## 测试 + +交叉编译完成后,用户可在 OpenHarmony 设备上自行测试所得二进制文件的可用性。 + +具体测试过程可参考链接 [make方式交叉编译后测试](https://gitee.com/openharmony-sig/tpc_c_cplusplus/blob/master/docs/make_portting.md#测试) 或 [cmake方式交叉编译后测试](https://gitee.com/openharmony-sig/tpc_c_cplusplus/blob/master/docs/cmake_portting.md#测试) \ No newline at end of file diff --git a/src/vscode_plugin/images/ohCrossCompile_archPick.png b/src/vscode_plugin/images/ohCrossCompile_archPick.png new file mode 100644 index 0000000000000000000000000000000000000000..c4488571c1824e692968bfaadc5d9c1aaa511df0 Binary files /dev/null and b/src/vscode_plugin/images/ohCrossCompile_archPick.png differ diff --git a/src/vscode_plugin/images/ohCrossCompile_compilation.png b/src/vscode_plugin/images/ohCrossCompile_compilation.png new file mode 100644 index 0000000000000000000000000000000000000000..ca25f661693b6bfc0e6567648154349416ce3fcc Binary files /dev/null and b/src/vscode_plugin/images/ohCrossCompile_compilation.png differ diff --git a/src/vscode_plugin/images/ohCrossCompile_installedFiles.png b/src/vscode_plugin/images/ohCrossCompile_installedFiles.png new file mode 100644 index 0000000000000000000000000000000000000000..20b2f1367c3a169fa5506d88e7ef3acce114deba Binary files /dev/null and b/src/vscode_plugin/images/ohCrossCompile_installedFiles.png differ diff --git a/src/vscode_plugin/images/ohCrossCompile_menu.png b/src/vscode_plugin/images/ohCrossCompile_menu.png new file mode 100644 index 0000000000000000000000000000000000000000..66939e39164f38ec323ed2576f6c0f3687e34268 Binary files /dev/null and b/src/vscode_plugin/images/ohCrossCompile_menu.png differ diff --git a/src/vscode_plugin/images/ohCrossCompile_menu_2.png b/src/vscode_plugin/images/ohCrossCompile_menu_2.png new file mode 100644 index 0000000000000000000000000000000000000000..d9b7cb456363fcf1c45607834fe44e1924cf988b Binary files /dev/null and b/src/vscode_plugin/images/ohCrossCompile_menu_2.png differ diff --git a/src/vscode_plugin/images/ohCrossCompile_sourcePick.png b/src/vscode_plugin/images/ohCrossCompile_sourcePick.png new file mode 100644 index 0000000000000000000000000000000000000000..693d7d522168ddd39ce7bbe7bf3b5e6efeb983c5 Binary files /dev/null and b/src/vscode_plugin/images/ohCrossCompile_sourcePick.png differ diff --git a/src/vscode_plugin/images/ohCrossCompile_sourcePick_selectNative.png b/src/vscode_plugin/images/ohCrossCompile_sourcePick_selectNative.png new file mode 100644 index 0000000000000000000000000000000000000000..bc58b77278e58a50becb73c756c1ad9a440bbee0 Binary files /dev/null and b/src/vscode_plugin/images/ohCrossCompile_sourcePick_selectNative.png differ diff --git a/src/vscode_plugin/images/ohCrossCompile_toolPick.png b/src/vscode_plugin/images/ohCrossCompile_toolPick.png new file mode 100644 index 0000000000000000000000000000000000000000..61c5402764b219d5dffce15311c0b520f912bb22 Binary files /dev/null and b/src/vscode_plugin/images/ohCrossCompile_toolPick.png differ diff --git a/src/vscode_plugin/images/ohCrossCompile_versionPick.png b/src/vscode_plugin/images/ohCrossCompile_versionPick.png new file mode 100644 index 0000000000000000000000000000000000000000..188f1161f5fe72c2a04cec55f41041fe4ad74280 Binary files /dev/null and b/src/vscode_plugin/images/ohCrossCompile_versionPick.png differ diff --git a/src/vscode_plugin/l10n/bundle.l10n.zh-cn.json b/src/vscode_plugin/l10n/bundle.l10n.zh-cn.json index 68db9450f3f92bfca145b1597e504beea7589989..78f92867253b43343023a678f465980bfe44881e 100644 --- a/src/vscode_plugin/l10n/bundle.l10n.zh-cn.json +++ b/src/vscode_plugin/l10n/bundle.l10n.zh-cn.json @@ -14,5 +14,46 @@ "Generation complete:": "生成完成", "You selected a directory:": "您选择了一个目录", "Please select a directory.": "请选择一个目录", - "No resource selected.": "未选择资源" + "No resource selected.": "未选择资源", + "Use Makefile for compilation.": "根据 Makefile 交叉编译", + "Use CMakeLists.txt for compilation.": "根据 CMakeLists.txt 交叉编译", + "Please select the way you want to compile: ": "请选择编译方式:", + "OpenHarmony Cross Compile": "OpenHarmony 交叉编译", + "Unable to comfirm the compilation method, compilation aborted.": "无法确认编译方式,编译过程终止", + "To compile 64-bit third-party library.": "编译64位的三方库", + "To compile 32-bit third-party library.": "编译32位的三方库", + "Please select the target system architecture for compilation: ": "请选择交叉编译的目标系统架构:", + "Unable to comfirm target system architecture, compilation aborted.": "无法确认目标系统架构,编译过程终止", + "Local": "本地", + "Please select the 'native' folder in local OpenHarmony SDK files.": "请选择本地 OpenHarmony SDK 文件中的 'native' 文件夹", + "Download": "下载", + "Download a specified version of OpenHarmony SDK from internet.": "从网络下载指定版本的 OpenHarmony SDK", + "Please select the SDK you want to use: ": "请选择你想使用的 SDK 来源:", + "Unable to verify the integrity of the native tools in OpenHarmony SDK, please try again and select a correct path of the 'native' folder.": "无法验证 OpenHarmony SDK 中 native 工具的完整性,请再试一遍并选择正确的 'native' 文件夹路径", + "No folder selected, compilation aborted.": "未选中文件夹,编译过程终止", + "API Version 9": "API 版本9", + "Please select a folder to install this SDK. It is compatible with OpenHarmony 3.2 Release.": "请选择 SDK 的安装路径。该版本 SDK 适用于 OpenHarmony 3.2 Release 版本", + "API Version 10": "API 版本10", + "Please select a folder to install this SDK. It is compatible with OpenHarmony 4.0 Release.": "请选择 SDK 的安装路径。该版本 SDK 适用于 OpenHarmony 4.0 Release 版本", + "API Version 11": "API 版本11", + "Please select a folder to install this SDK. It is compatible with OpenHarmony 4.1 Release.": "请选择 SDK 的安装路径。该版本 SDK 适用于 OpenHarmony 4.1 Release 版本", + "API Version 12": "API 版本12", + "Please select a folder to install this SDK. It is compatible with OpenHarmony 5.0.0 Release.": "请选择 SDK 的安装路径。该版本 SDK 适用于 OpenHarmony 5.0.0 Release 版本", + "Please specify the SDK version: ": "请选择 SDK 版本:", + "Downloading and installing SDK": "正在下载安装 SDK", + "Start downloading...": "开始下载...", + "Download complete. Extracting .tar.gz files... ": "下载完成。正在提取 .tar.gz 文件...", + "SDK installation complete.": "SDK 安装完成", + "Unable to specify the version of OpenHarmony SDK, compilation aborted.": "无法确认 OpenHarmony SDK 版本,编译过程终止", + "Unable to comfirm the source of OpenHarmony SDK, compilation aborted.": "无法确认 OpenHarmony SDK 来源,编译过程终止", + "Cannot detect CMakeLists.txt or Makefile!": "未检测到 CMakeLists.txt 或 Makefile !", + "Starting compilation on Windows.": "在 Windows 上开始编译", + "Starting compilation on Linux.": "在 Linux 上开始编译", + "SDK downloaded to: {0}": "SDK已下载至: {0}", + "Downloading SDK ... {0}%": "正在下载SDK... {0}%", + "Connection failed! Statuscode: {0}": "连接断开!状态码: {0}", + "Failed to get '{0}' ({1})": "从 {0} 下载失败。({1})", + "Error extracting file: {0}": "提取文件错误: {0}", + "Compiled files of {0} system will be installed at {1}. ": "{0} 架构经编译后的文件将被安装在 {1} 目录", + "Error occured while compiling. Error: {0}": "编译过程出现错误。错误: {0}" } \ No newline at end of file diff --git a/src/vscode_plugin/package.json b/src/vscode_plugin/package.json index a4c6613348364961a36b5f91dcaac82c0ac6daab..6cd37bc1bd713eb211aaeeef336109d167b864f4 100644 --- a/src/vscode_plugin/package.json +++ b/src/vscode_plugin/package.json @@ -7,7 +7,7 @@ "icon": "images/icon.png", "repository": "https://gitee.com/openharmony/napi_generator", "engines": { - "vscode": "^1.34.0" + "vscode": "^1.73.0" }, "categories": [ "Other", @@ -50,7 +50,7 @@ "command": "extension.ohcrosscompile", "title": "%extension.ohcrosscompile.title%" }, - { + { "command": "extension.ohGenerator", "title": "%extension.ohGenerator.title%" } @@ -103,16 +103,17 @@ }, { "command": "extension.ohcrosscompile", - "when": "resourceScheme == 'file'", + "when": "resourceScheme == 'file' && explorerResourceIsFolder", "group": "2_workspace" } ] + }, "snippets": [ { "language": "cpp", "path": "./snippets/napi_class_snippets.json" }, - { + { "language": "cpp", "path": "./snippets/napi_thread_snippets.json" }, @@ -174,7 +175,7 @@ }, "devDependencies": { "@types/node": "^16.17.0", - "@types/vscode": "^1.34.0", + "@types/vscode": "^1.73.0", "@typescript-eslint/eslint-plugin": "^5.30.0", "@typescript-eslint/parser": "^5.30.0", "eslint": "^8.13.0" @@ -182,6 +183,6 @@ "dependencies": { "vsce": "^2.15.0", "typescript": "^4.7.2", - "@vscode/l10n": "^0.0.10" + "@vscode/l10n": "^0.0.10" } } diff --git a/src/vscode_plugin/package.nls.json b/src/vscode_plugin/package.nls.json index 47b1df827c7eb924cd55bde092206f350c839301..477fe830f8f62abfd9375168a24826ab632bedc8 100644 --- a/src/vscode_plugin/package.nls.json +++ b/src/vscode_plugin/package.nls.json @@ -5,6 +5,6 @@ "extension.h2dtscpp.title": "h2dtscpp", "extension.dts2cpp.title": "dts2cpp", "extension.ohGenerator.title": "OHGenerator", - "extension.ohcrosscompile.title": "OH_CrossCompile", + "extension.ohcrosscompile.title": "OpenHarmony Cross Compile", "Generate NAPI definition code and framework code for OpenHarmony. \n[OHGenerator](command:extension.ohGenerator)": "Generate NAPI definition code and framework code for OpenHarmony. \n[OHGenerator](command:extension.ohGenerator)" } \ No newline at end of file diff --git a/src/vscode_plugin/package.nls.zh-cn.json b/src/vscode_plugin/package.nls.zh-cn.json index ebc93369a1db4f7fdd9307de3a2f28c7cd4e18e6..7c43d0616dc5b7d40e1e26b6da78c41ff38aefff 100644 --- a/src/vscode_plugin/package.nls.zh-cn.json +++ b/src/vscode_plugin/package.nls.zh-cn.json @@ -5,6 +5,6 @@ "extension.h2dtscpp.title": "h2dtscpp", "extension.dts2cpp.title": "dts2cpp", "extension.ohGenerator.title": "OHGenerator", - "extension.ohcrosscompile.title": "OH_CrossCompile", + "extension.ohcrosscompile.title": "OpenHarmony 交叉编译", "Generate NAPI definition code and framework code for OpenHarmony. \n[OHGenerator](command:extension.ohGenerator)": "为OpenHarmony生成NAPI定义和框架代码。 \n[OHGenerator](command:extension.ohGenerator)" } \ No newline at end of file diff --git a/src/vscode_plugin/readme.md b/src/vscode_plugin/readme.md index d7ca8f379062a1fbfccc1b142a80b8825a6b5832..3c4f617d33b5e24aad54268d6acfae4e8804baed 100644 --- a/src/vscode_plugin/readme.md +++ b/src/vscode_plugin/readme.md @@ -1,6 +1,6 @@ # 模板生成和语言转换工具 -napi-gen插件为OpenHarmony开发者提供模板生成(**sa**模板、**hdf**模板)和语言转换功能(依据**h**头文件转换生成**dts**接口文件 和 **native C++** 工程文件)。 +napi-gen插件为OpenHarmony开发者提供模板生成(**sa**模板、**hdf**模板)、语言转换功能(依据**h**头文件转换生成**dts**接口文件 和 **native C++** 工程文件)、交叉编译功能(使用OpenHarmony SDK所提供的工具链编译三方库源码)。 ## 功能: @@ -28,12 +28,18 @@ napi-gen插件为OpenHarmony开发者提供模板生成(**sa**模板、**hdf** | ------------- | ------------------------------------------------------------ | | DecEco Studio | 4.1 Release(Build Version: 4.1.0.400, built on April 9, 2024) | +- **OpenHarmony交叉编译**:根据三方库中Makefile或CmakeLists,调用OpenHarmony SDK中提供的工具链进行交叉编译,拼装 make 及 make install 命令并调用终端执行。生成对应于目标系统架构的二进制文件及头文件,默认安装至三方库路径下ohCrossCompile目录中。 + ## 使用: - **方式1**: 右键.h文件在弹出菜单里选择子菜单 **[OHOS_Gen]** 内的功能: ![](https://gitee.com/openharmony/napi_generator/raw/master/src/vscode_plugin/images/h2sa4-1.png) + 对于OpenHarmony交叉编译功能,可右键三方库文件夹,在菜单中选择 **[OpenHarmony 交叉编译]** 选项,以调用交叉编译功能。该功能的详细用法请参考:[OpenHarmony交叉编译功能使用帮助文档](https://gitee.com/openharmony/napi_generator/tree/master/src/vscode_plugin/docs/ohCrossCompile.md) + + ![](https://gitee.com/openharmony/napi_generator/raw/master/src/vscode_plugin/images/ohCrossCompile_menu.png) + - **方式2**: 通过在工具栏选择 **[帮助]** -> **[显示所有命令]** 或者 快捷命令 **[ctrl + shift + p]** 在弹出窗口里输入h2dts等命令使用功能 diff --git a/src/vscode_plugin/src/extension.ts b/src/vscode_plugin/src/extension.ts index c48d7f27079d053149ccfbcc1fc6f6a8e517aa19..89d1be3015f20b66941a4ea9a5437578937191ae 100644 --- a/src/vscode_plugin/src/extension.ts +++ b/src/vscode_plugin/src/extension.ts @@ -20,7 +20,7 @@ import * as path from 'path'; import * as ts from 'typescript'; import * as fs from 'fs'; import * as os from 'os'; -import { downloadSdk, extractTarGz, extractZip, crossCompile } from './ohcrosscompile'; +import { downloadSdk , extractTarGz, extractZip, crossCompile, checkNative } from './ohcrosscompile'; import { parseHeaderFile } from './parsec'; import { DtscppRootInfo, GenInfo } from './datatype'; import { parseTsFile } from './parsets'; @@ -46,7 +46,38 @@ const INPUT_INCONSISTENT = vscode.l10n.t('Inconsistent input'); const PARSE_COMPLETE = vscode.l10n.t('Parse complete.'); const GEN_COMPLETE = vscode.l10n.t('Generation complete:'); const OPEN_IN_EXPLORER = vscode.l10n.t('Open in Explorer'); - +const PICK_MAKE = vscode.l10n.t('Use Makefile for compilation.'); +const PICK_CMAKE = vscode.l10n.t('Use CMakeLists.txt for compilation.'); +const TOOL_PICK_PLACEHOLDER = vscode.l10n.t('Please select the way you want to compile: '); +const OH_CROSS_COMPILE_TITLE = vscode.l10n.t('OpenHarmony Cross Compile'); +const COMPILATION_METHOD_LOST = vscode.l10n.t('Unable to comfirm the compilation method, compilation aborted.'); +const ARCH_PICK_64 = vscode.l10n.t('To compile 64-bit third-party library.'); +const ARCH_PICK_32 = vscode.l10n.t('To compile 32-bit third-party library.'); +const ARCH_PICK_PLACEHOLDER = vscode.l10n.t('Please select the target system architecture for compilation: '); +const ARCHITECTURE_LOST = vscode.l10n.t('Unable to comfirm target system architecture, compilation aborted.'); +const LOCAL = vscode.l10n.t('Local'); +const LOCAL_DESCRIPTION = vscode.l10n.t('Please select the \'native\' folder in local OpenHarmony SDK files.'); +const DOWNLOAD = vscode.l10n.t('Download'); +const DOWNLOAD_DESCRIPTION = vscode.l10n.t('Download a specified version of OpenHarmony SDK from internet.'); +const SOURCE_PICK_PLACEHOLDER = vscode.l10n.t('Please select the SDK you want to use: '); +const NATIVE_CHECK_FAILED = vscode.l10n.t('Unable to verify the integrity of the native tools in OpenHarmony SDK, please try again and select a correct path of the \'native\' folder.'); +const FOLDER_LOST = vscode.l10n.t('No folder selected, compilation aborted.'); +const API9_LABEL = vscode.l10n.t('API Version 9'); +const API9_DETAIL = vscode.l10n.t('Please select a folder to install this SDK. It is compatible with OpenHarmony 3.2 Release.'); +const API10_LABEL = vscode.l10n.t('API Version 10'); +const API10_DETAIL = vscode.l10n.t('Please select a folder to install this SDK. It is compatible with OpenHarmony 4.0 Release.'); +const API11_LABEL = vscode.l10n.t('API Version 11'); +const API11_DETAIL = vscode.l10n.t('Please select a folder to install this SDK. It is compatible with OpenHarmony 4.1 Release.'); +const API12_LABEL = vscode.l10n.t('API Version 12'); +const API12_DETAIL = vscode.l10n.t('Please select a folder to install this SDK. It is compatible with OpenHarmony 5.0.0 Release.'); +const VERSION_PICK_PLACEHOLDER = vscode.l10n.t('Please specify the SDK version: '); +const DOWNLOADING_TITLE = vscode.l10n.t('Downloading and installing SDK'); +const DOWNLOADING_START = vscode.l10n.t('Start downloading...'); +const DOWNLOADING_COMPLETE = vscode.l10n.t('Download complete. Extracting .tar.gz files... '); +const SDK_INSTALLED = vscode.l10n.t('SDK installation complete.'); +const SDK_VERSION_LOST = vscode.l10n.t('Unable to specify the version of OpenHarmony SDK, compilation aborted.'); +const SDK_SOURCE_LOST = vscode.l10n.t('Unable to comfirm the source of OpenHarmony SDK, compilation aborted.'); +const CMAKE_MAKE_LOST = vscode.l10n.t('Cannot detect CMakeLists.txt or Makefile!'); // this method is called when your extension is activated // your extension is activated the very first time the command is executed @@ -56,286 +87,342 @@ export function activate(context: vscode.ExtensionContext) { console.log('Congratulations, your extension "helloworld-sample" is now active!'); const ohcrosscompile = vscode.commands.registerCommand('extension.ohcrosscompile', async (uri) => { + let compileTool: string; + let thirdPartyPath: string; + let nativePath: string; + let ohArchitecture = new Array(); const platform = os.platform(); - // vscode.window.showInformationMessage(`Platform: ${platform}`); + - // ѡѡҪĿ¼ - const thirdPartyPick = vscode.window.createQuickPick(); - thirdPartyPick.title = "OpenHarmony cross compile"; - thirdPartyPick.step = 1; - thirdPartyPick.totalSteps = 5; - thirdPartyPick.placeholder = "Please select the directory of the third-party library you want to compile. "; - thirdPartyPick.items = [{ label: "Browse local files" }]; - thirdPartyPick.onDidAccept(async () => { - const thirdPartyUri = await vscode.window.showOpenDialog({ - canSelectMany: false, //ֻѡһļ - canSelectFolders: true, //ѡļ - canSelectFiles: false //ѡļ - }); - if (thirdPartyUri && thirdPartyUri[0]) { //Ƿѡļ - // ȡļ· - let thirdPartyPath = ""; - thirdPartyPath = thirdPartyUri[0].path; - if (platform === "win32") { //WindowsϵͳҲʹбܵ· /D:/Learning/nativeҪȥǰ/ - thirdPartyPath = thirdPartyPath.slice(1); + if (uri && uri.path) { + thirdPartyPath = uri.path; + if (platform === "win32") { + thirdPartyPath = thirdPartyPath.slice(1); + } + const canCmake = fs.existsSync(thirdPartyPath.concat("/CMakeLists.txt")); + const canMake = fs.existsSync(thirdPartyPath.concat("/GNUmakefile")) || fs.existsSync(thirdPartyPath.concat("/Makefile")) || fs.existsSync(thirdPartyPath.concat("/makefile")); + if (canCmake || canMake) { //⵽CMakeLists.txtmakefileԼ + + + // ûвļСװļУ򴴽ԶȡװĿ¼ + const ohCrossCompilePath = thirdPartyPath.concat("/ohCrossCompile"); + if (!fs.existsSync(ohCrossCompilePath)) { + fs.mkdirSync(ohCrossCompilePath); + } + + // ûļĬôļ + const configPath = ohCrossCompilePath.concat("/config.json") + if (!fs.existsSync(configPath)) { + const defaultConfig = { + settings: { + compileTool: "", + nativePath: "", + thirdPartyPath: thirdPartyPath, + // ohArchitecture: ["arm64-v8a", "armeabi-v7a"] + ohArchitecture: [] + }, + actions: [] + }; + fs.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 4), 'utf8'); + } + const configContent = JSON.parse(fs.readFileSync(configPath, 'utf8')); + if (configContent.settings === undefined) { + const defaultConfig = { + settings: { + compileTool: "", + nativePath: "", + thirdPartyPath: thirdPartyPath, + // ohArchitecture: ["arm64-v8a", "armeabi-v7a"] + ohArchitecture: [] + }, + actions: [] + }; + fs.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 4), 'utf8'); + } + + // ȡ뷽ʽmakecmake + if (configContent.settings.compileTool !== undefined && (configContent.settings.compileTool === "make" || configContent.settings.compileTool === "cmake")) { //ļѾ洢뷽ʽ + compileTool = configContent.settings.compileTool; + } else if (canCmake && canMake) { //Զжϳmakecmakeʹãѯû洢 + + const toolPickItems = [ + { + label: "make", + description: PICK_MAKE + }, + { + label: "cmake", + description: PICK_CMAKE + } + ]; + const toolPickOptions = { + canPickMany: false, + ignoreFocusOut: true, + placeHolder: TOOL_PICK_PLACEHOLDER, + title: OH_CROSS_COMPILE_TITLE + }; + const toolPick = await vscode.window.showQuickPick(toolPickItems, toolPickOptions); + + if (toolPick) { + compileTool = toolPick.label; + configContent.settings.compileTool = compileTool; + fs.writeFileSync(configPath, JSON.stringify(configContent, null, 4), 'utf8'); + } else { + vscode.window.showInformationMessage(COMPILATION_METHOD_LOST); + return; + } + } else if (canCmake) { //Զжϳֻʹcmake + compileTool = "cmake"; + configContent.settings.compileTool = "cmake"; + fs.writeFileSync(configPath, JSON.stringify(configContent, null, 4), 'utf8'); + } else { //Զжϳֻʹmake + compileTool = "make"; + configContent.settings.compileTool = "make"; + fs.writeFileSync(configPath, JSON.stringify(configContent, null, 4), 'utf8'); } - console.log(`thirdPartyPath: ${thirdPartyPath}`); - // ѡѡDZ빤makecmake - const toolPick = vscode.window.createQuickPick(); - toolPick.title = "OpenHarmony cross compile"; - toolPick.step = 2; - toolPick.totalSteps = 5; - toolPick.placeholder = "Please select the way you want to compile: "; - toolPick.items = [{ label: "cmake" }, { label: "make" }]; - toolPick.onDidAccept(async () => { - // ȡ빤ѡĽ - const compileTool = toolPick.selectedItems[0].label; - // vscode.window.showInformationMessage("You've selected " + compileTool); - // ѡѡ񽻲Ŀϵͳܹarm64-v8aarmeabi-v7a - const archPick = vscode.window.createQuickPick(); - archPick.title = "OpenHarmony cross compile"; - archPick.step = 3; - archPick.totalSteps = 5; - archPick.placeholder = "Please select the target system architecture for compilation: "; - archPick.items = [ + // ȷҪCPUܹװļ򴴽 + if (configContent.settings.ohArchitecture === undefined || configContent.settings.ohArchitecture.length === 0) { //ļ޷ȷCPUܹѯû + const archPickItems = [ { label: "arm64-v8a", - description: "To compile 64-bit third-party library." + description: ARCH_PICK_64 }, { label: "armeabi-v7a", - description: "To compile 32-bit third-party library." + description: ARCH_PICK_32 } ]; - archPick.onDidAccept(async () => { - // ȡϵͳܹѡĽ - const ohArchitecture = archPick.selectedItems[0].label; - console.log(ohArchitecture); + const archPickOptions = { + canPickMany: true, + ignoreFocusOut: true, + placeHolder: ARCH_PICK_PLACEHOLDER, + title: OH_CROSS_COMPILE_TITLE + }; + const archPick = await vscode.window.showQuickPick(archPickItems, archPickOptions) + if (archPick && Array.isArray(archPick) && archPick.length > 0) { //ûѡϢļ + for (let item of archPick) { + let arch = item.label; + ohArchitecture.push(arch); + if (!fs.existsSync(`${ohCrossCompilePath}/${arch}`)) { + fs.mkdirSync(`${ohCrossCompilePath}/${arch}`); + } + if (!fs.existsSync(`${ohCrossCompilePath}/${arch}/installed`)) { + fs.mkdirSync(`${ohCrossCompilePath}/${arch}/installed`); + } + } + configContent.settings.ohArchitecture = ohArchitecture; + fs.writeFileSync(configPath, JSON.stringify(configContent, null, 4), 'utf8'); + } else { + vscode.window.showInformationMessage(ARCHITECTURE_LOST); + return; + } + } else { + if (configContent.settings.ohArchitecture.includes("arm64-v8a")) { + ohArchitecture.push("arm64-v8a"); + if (!fs.existsSync(`${ohCrossCompilePath}/arm64-v8a`)) { + fs.mkdirSync(`${ohCrossCompilePath}/arm64-v8a`); + } + if (!fs.existsSync(`${ohCrossCompilePath}/arm64-v8a/installed`)) { + fs.mkdirSync(`${ohCrossCompilePath}/arm64-v8a/installed`); + } + } + if (configContent.settings.ohArchitecture.includes("armeabi-v7a")) { + ohArchitecture.push("armeabi-v7a"); + if (!fs.existsSync(`${ohCrossCompilePath}/armeabi-v7a`)) { + fs.mkdirSync(`${ohCrossCompilePath}/armeabi-v7a`); + } + if (!fs.existsSync(`${ohCrossCompilePath}/armeabi-v7a/installed`)) { + fs.mkdirSync(`${ohCrossCompilePath}/armeabi-v7a/installed`); + } + } + } + + + // ȷsdknativeߵ· + if (configContent.settings.nativePath === undefined || configContent.settings.nativePath === "") { //ѯû + + // ȷsdkԴDZػ + const sourcePickItems = [ + { + label: LOCAL, + description: LOCAL_DESCRIPTION + }, + { + label: DOWNLOAD, + description: DOWNLOAD_DESCRIPTION + } + ]; + const sourcePickOptions = { + canPickMany: false, + ignoreFocusOut: true, + placeHolder: SOURCE_PICK_PLACEHOLDER, + title: OH_CROSS_COMPILE_TITLE + } + const sourcePick = await vscode.window.showQuickPick(sourcePickItems, sourcePickOptions); + + if (sourcePick) { + if (sourcePick.label === LOCAL) { //sdkԴΪأѯûnativeڵľ·ǷϷ + const folderUri = await vscode.window.showOpenDialog({ + canSelectMany: false, + canSelectFolders: true, + canSelectFiles: false + }); + if (folderUri && folderUri[0]) { + let folderPath = folderUri[0].path; + if (platform === "win32") { + folderPath = folderPath.slice(1); + } + if (checkNative(platform, folderPath)) { + nativePath = folderPath; + configContent.settings.nativePath = folderPath; + fs.writeFileSync(configPath, JSON.stringify(configContent, null, 4), 'utf8'); - // ѡѡʹñsdkǴָ汾sdk - const sourcePick = vscode.window.createQuickPick(); - sourcePick.title = "OpenHarmony cross compile"; - sourcePick.step = 4; - sourcePick.totalSteps = 5; - sourcePick.placeholder = "Please select the SDK you want to use: "; - sourcePick.items = [ - { - label: "Local", - description: "Select the 'native' folder in local OpenHarmony SDK files." - }, - { - label: "Download", - description: "Download a specified version of OpenHarmony SDK from internet." + // ִб + crossCompile(platform, undefined, configPath, thirdPartyPath, compileTool, ohArchitecture, nativePath, ohCrossCompilePath); + } else { + vscode.window.showInformationMessage(NATIVE_CHECK_FAILED); + return; + } + } else { + vscode.window.showInformationMessage(FOLDER_LOST); + return; } - ]; - sourcePick.onDidAccept(async () => { - // ȡsdkԴѡĽ - const sdkSource = sourcePick.selectedItems[0].label; - console.log(sdkSource); + } else if (sourcePick.label === DOWNLOAD) { //sdkԴΪ磬ѯذ汾·زѹsdk + // ȡذ汾Ӷ + const versionPickItems = [ + { + label: API9_LABEL, + description: "Ohos_sdk_public 3.2.11.9 (API Version 9 Release)", + detail: API9_DETAIL + }, + { + label: API10_LABEL, + description: "Ohos_sdk_public 4.0.10.13 (API Version 10 Release)", + detail: API10_DETAIL + }, + { + label: API11_LABEL, + description: "Ohos_sdk_public 4.1.7.5 (API Version 11 Release)", + detail: API11_DETAIL + }, + { + label: API12_LABEL, + description: "Ohos_sdk_public 5.0.0.71 (API Version 12 Release)", + detail: API12_DETAIL + }, + ]; + const versionPickOptions = { + canPickMany: false, + ignoreFocusOut: true, + placeHolder: VERSION_PICK_PLACEHOLDER, + title: OH_CROSS_COMPILE_TITLE + } + const versionPick = await vscode.window.showQuickPick(versionPickItems, versionPickOptions); + if (versionPick) { + const apiVersion = versionPick.label; + let downloadLink: string; + switch (apiVersion) { + case API9_LABEL: + downloadLink = "https://repo.huaweicloud.com/openharmony/os/3.2-Release/ohos-sdk-windows_linux-public.tar.gz"; + break; + case API10_LABEL: + downloadLink = "https://repo.huaweicloud.com/openharmony/os/4.0-Release/ohos-sdk-windows_linux-public.tar.gz"; + break; + case API11_LABEL: + downloadLink = "https://repo.huaweicloud.com/openharmony/os/4.1-Release/ohos-sdk-windows_linux-public.tar.gz"; + break; + case API12_LABEL: + downloadLink = "https://repo.huaweicloud.com/openharmony/os/5.0.0-Release/ohos-sdk-windows_linux-public.tar.gz"; + break; + } - let nativePath = ""; - if (sdkSource === "Local") { + // ѯ· const folderUri = await vscode.window.showOpenDialog({ - canSelectMany: false, //ֻѡһļ - canSelectFolders: true, //ѡļ - canSelectFiles: false //ѡļ + canSelectMany: false, + canSelectFolders: true, + canSelectFiles: false }); - if (folderUri && folderUri[0]) { //Ƿѡļ - // ȡļ· - let folderPath = ""; - let pathNames: string[]; - folderPath = folderUri[0].path; + if (folderUri && folderUri[0]) { + let folderPath = folderUri[0].path; if (platform === "win32") { folderPath = folderPath.slice(1); } - pathNames = folderPath.split('/'); - // ѡļǷΪnativeļ - if (pathNames[pathNames.length - 1] !== "native") { - vscode.window.showErrorMessage('Can\'t detect the native folder!'); - } else { - nativePath = folderPath; + let filePath = folderPath.concat("/ohos-sdk-windows_linux-public.tar.gz"); + + // زѹsdkеnative + await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: DOWNLOADING_TITLE, + cancellable: false + }, async (progress) => { + progress.report({ increment: 0, message: DOWNLOADING_START }); + await downloadSdk(downloadLink, filePath, progress); + vscode.window.showInformationMessage(vscode.l10n.t('SDK downloaded to: {0}', filePath)); + // vscode.window.showInformationMessage(`SDK downloaded to: ${filePath}`); - // ѡɱļĿ¼ - const generatePick = vscode.window.createQuickPick(); - generatePick.title = "OpenHarmony cross compile"; - generatePick.step = 5; - generatePick.totalSteps = 5; - generatePick.placeholder = "Please select a folder to store the generated compilation configuration files: "; - generatePick.items = [{ label: "Browse local files" }]; - generatePick.onDidAccept(async () => { - const generateUri = await vscode.window.showOpenDialog({ - canSelectMany: false, - canSelectFolders: true, - canSelectFiles: false - }); - if (generateUri && generateUri[0]) { - let generatePath = ""; - generatePath = generateUri[0].path; - if (platform === "win32") { - generatePath = generatePath.slice(1); - } - console.log(`generatePath: ${generatePath}`); + // ѹsdkеnativeƴװnativePath + progress.report({ increment: 10, message: DOWNLOADING_COMPLETE }); + await extractTarGz(filePath, folderPath); + progress.report({ increment: 100, message: SDK_INSTALLED }); - crossCompile(platform, undefined, thirdPartyPath, compileTool, ohArchitecture, nativePath, generatePath); - - } else { - vscode.window.showErrorMessage('You haven\'t selected a folder to store the generated compilation configuration files! '); - } - }); - generatePick.show(); - } - } else { - vscode.window.showErrorMessage('No file selected'); - } - - } else if (sdkSource === "Download") { - // ѡsdkİ汾ȷӦ - const versionPick = vscode.window.createQuickPick(); - versionPick.title = "OpenHarmony cross compile"; - versionPick.placeholder = "Please specify the SDK version: "; - versionPick.items = [ - { - label: "API Version 9", - description: "Ohos_sdk_public 3.2.11.9 (API Version 9 Release)", - detail: "Select a folder to install this SDK. It is compatible with OpenHarmony 3.2 Release." - }, - { - label: "API Version 10", - description: "Ohos_sdk_public 4.0.10.13 (API Version 10 Release)", - detail: "Select a folder to install this SDK. It is compatible with OpenHarmony 4.0 Release." - }, - { - label: "API Version 11", - description: "Ohos_sdk_public 4.1.7.5 (API Version 11 Release)", - detail: "Select a folder to install this SDK. It is compatible with OpenHarmony 4.1 Release." - }, - { - label: "API Version 12", - description: "Ohos_sdk_public 5.0.0.71 (API Version 12 Release)", - detail: "Select a folder to install this SDK. It is compatible with OpenHarmony 5.0.0 Release." - }, - ]; - - versionPick.onDidAccept(async () => { - const apiVersion = versionPick.selectedItems[0].label; - let downloadLink = ""; - switch (apiVersion) { - case "API Version 9": - downloadLink = "https://repo.huaweicloud.com/openharmony/os/3.2-Release/ohos-sdk-windows_linux-public.tar.gz"; - break; - case "API Version 10": - downloadLink = "https://repo.huaweicloud.com/openharmony/os/4.0-Release/ohos-sdk-windows_linux-public.tar.gz"; - break; - case "API Version 11": - downloadLink = "https://repo.huaweicloud.com/openharmony/os/4.1-Release/ohos-sdk-windows_linux-public.tar.gz"; - break; - case "API Version 12": - downloadLink = "https://repo.huaweicloud.com/openharmony/os/5.0.0-Release/ohos-sdk-windows_linux-public.tar.gz"; - break; - } - console.log(downloadLink); - const terminal = vscode.window.createTerminal({name: "OpenHarmony cross compile"}); - - // ѡsdk· - const folderUri = await vscode.window.showOpenDialog({ - canSelectMany: false, - canSelectFolders: true, - canSelectFiles: false - }); - if (folderUri && folderUri[0]) { - // ȡļ·ƴװļ· - let folderPath = ""; - folderPath = folderUri[0].path; + nativePath = folderPath; + if (apiVersion !== API12_LABEL) { //api12汾·ûohos-sdk9-11汾 + nativePath = nativePath.concat("/ohos-sdk"); + } if (platform === "win32") { - folderPath = folderPath.slice(1); + nativePath = nativePath.concat("/windows"); //windowsϵͳµnativePath· + } else { + nativePath = nativePath.concat("/linux"); //linuxϵͳµnativePath· } - const fileName = "ohos-sdk-windows_linux-public.tar.gz"; - let filePath = path.join(folderPath, fileName); - console.log(filePath); - - // زѹsdkеnative - await vscode.window.withProgress({ - location: vscode.ProgressLocation.Notification, - title: "Downloading and installing SDK", - cancellable: false - }, async (progress) => { - // sdk - progress.report({ increment: 0, message: "Start downloading..." }); - - await downloadSdk(downloadLink, filePath, progress); - vscode.window.showInformationMessage(`SDK downloaded to: ${filePath}`); - - // ѹsdkеnativeƴװnativePath - progress.report({ increment: 10, message: "Download complete. Extracting..." }); - await extractTarGz(filePath, folderPath); - nativePath = folderPath; - if (apiVersion !== "API Version 12") { //api12汾·ûohos-sdk9-11汾 - nativePath = path.join(nativePath, "ohos-sdk"); - } - if (platform === "win32") { - nativePath = path.join(nativePath, "windows"); //windowsϵͳµnativePath· - } else { - nativePath = path.join(nativePath, "linux"); //linuxϵͳµnativePath· - } - for (const file of await fs.promises.readdir(nativePath)) { - if (file.startsWith("native")) { - filePath = path.join(nativePath, file); //ȡnativeѹļ· - } + for (const file of await fs.promises.readdir(nativePath)) { + if (file.startsWith("native")) { + filePath = nativePath.concat("/" + file); //ȡnativeѹļ· } - await extractZip(platform, terminal, filePath, nativePath); - nativePath = path.join(nativePath, "native"); - vscode.window.showInformationMessage(`SDK (${apiVersion}) installed to: ${folderPath}`); - progress.report({ increment: 100, message: "SDK installation complete." }) - }); - - // ѡɱļĿ¼ - const generatePick = vscode.window.createQuickPick(); - generatePick.title = "OpenHarmony cross compile"; - generatePick.step = 5; - generatePick.totalSteps = 5; - generatePick.placeholder = "Please select a folder to store the compiled binary files: "; - generatePick.items = [{ label: "Browse local files" }]; - generatePick.onDidAccept(async () => { - const generateUri = await vscode.window.showOpenDialog({ - canSelectMany: false, - canSelectFolders: true, - canSelectFiles: false - }); - if (generateUri && generateUri[0]) { - let generatePath = ""; - generatePath = generateUri[0].path; - if (platform === "win32") { - generatePath = generatePath.slice(1); - } - console.log(`generatePath: ${generatePath}`); + } + console.log(filePath); + const terminal = vscode.window.createTerminal({ name: OH_CROSS_COMPILE_TITLE }); + terminal.show(); + await extractZip(platform, terminal, filePath, nativePath); + nativePath = nativePath.concat("/native"); + configContent.settings.nativePath = nativePath; + fs.writeFileSync(configPath, JSON.stringify(configContent, null, 4), 'utf8'); - terminal.show(); - crossCompile(platform, terminal, thirdPartyPath, compileTool, ohArchitecture, nativePath, generatePath); - } else { - vscode.window.showErrorMessage('You haven\'t selected a folder to store the compiled binary files! '); - } - }); - generatePick.show(); - } else { - vscode.window.showErrorMessage('You haven\'t selected a folder to install SDK! '); - } - }); - versionPick.show(); + // ִб + crossCompile(platform, terminal, configPath, thirdPartyPath, compileTool, ohArchitecture, nativePath, ohCrossCompilePath); + }); + } else { + vscode.window.showInformationMessage(FOLDER_LOST); + return; + } + } else { + vscode.window.showInformationMessage(SDK_VERSION_LOST); + return; } - }); - sourcePick.show(); - }); - archPick.show(); - }); - toolPick.show(); - } else { - vscode.window.showErrorMessage('You haven\'t selected the third-party library folder to compile! '); + } + } else { + vscode.window.showInformationMessage(SDK_SOURCE_LOST); + return; + } + } else { //ļnativePathǿգļлȡ + if (checkNative(platform, configContent.settings.nativePath)) { + nativePath = configContent.settings.nativePath; + // ִб + crossCompile(platform, undefined, configPath, thirdPartyPath, compileTool, ohArchitecture, nativePath, ohCrossCompilePath); + } else { //ļлȡnativePathǷãʾ + configContent.settings.nativePath = ""; + fs.writeFileSync(configPath, JSON.stringify(configContent, null, 4), 'utf8'); + vscode.window.showInformationMessage(NATIVE_CHECK_FAILED); + return; + } + } + } else { //ûѡļвCMakeLists.extMakefile + vscode.window.showErrorMessage(CMAKE_MAKE_LOST); } - }); - thirdPartyPick.show(); + } }); + context.subscriptions.push(ohcrosscompile); // The command has been defined in the package.json file // Now provide the implementation of the command with registerCommand diff --git a/src/vscode_plugin/src/ohcrosscompile.ts b/src/vscode_plugin/src/ohcrosscompile.ts index c8177212e7e86599b4cc67c07a2176c26826f771..e65a065c2f7d144642215c7f76edc1e90b0e64a7 100644 --- a/src/vscode_plugin/src/ohcrosscompile.ts +++ b/src/vscode_plugin/src/ohcrosscompile.ts @@ -12,13 +12,34 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import * as vscode from 'vscode'; import * as fs from 'fs'; import * as https from 'https'; import * as zlib from 'zlib'; import * as tar from 'tar'; -import * as unzipper from 'unzipper'; -import * as path from 'path'; + +const WINDOWS_START = vscode.l10n.t('Starting compilation on Windows.'); +const TERMINAL_TITLE = vscode.l10n.t('OpenHarmony Cross Compile'); +const LINUX_START = vscode.l10n.t('Starting compilation on Linux.'); + +export function checkNative(platform: string, nativePath: string): boolean { + if (platform === "win32") { + const cmakePath = nativePath.concat("/build-tools/cmake/bin/cmake.exe"); + const toolchainPath = nativePath.concat("/build/cmake/ohos.toolchain.cmake"); + const clangPath = nativePath.concat("/llvm/bin/clang.exe"); + const arPath = nativePath.concat("/llvm/bin/llvm-ar.exe"); + const ranlibPath = nativePath.concat("/llvm/bin/llvm-ranlib.exe"); + return fs.existsSync(cmakePath) && fs.existsSync(toolchainPath) && fs.existsSync(clangPath) && fs.existsSync(arPath) && fs.existsSync(ranlibPath); + } else { + const cmakePath = nativePath.concat("/build-tools/cmake/bin/cmake"); + const toolchainPath = nativePath.concat("/build/cmake/ohos.toolchain.cmake"); + const clangPath = nativePath.concat("/llvm/bin/clang"); + const arPath = nativePath.concat("/llvm/bin/llvm-ar"); + const ranlibPath = nativePath.concat("/llvm/bin/llvm-ranlib"); + return fs.existsSync(cmakePath) && fs.existsSync(toolchainPath) && fs.existsSync(clangPath) && fs.existsSync(arPath) && fs.existsSync(ranlibPath); + } +} // 下载url所指示的sdk文件,到destination所指示的文件中 export function downloadSdk(url: string, destination: string, progress: vscode.Progress<{ increment: number, message?: string }>): Promise { @@ -26,7 +47,7 @@ export function downloadSdk(url: string, destination: string, progress: vscode.P const file = fs.createWriteStream(destination); //创建写入文件流 https.get(url, (response) => { if (response.statusCode === 200) { - const totalSize = parseInt(String(response.headers['content-length'])); + const totalSize = parseInt(String(response.headers['content-length'])); //单位Byte console.log(`totalSize: ${totalSize}`); let downloadedSize = 0; response.on('data', (chunk) => { //设置response的data事件,当每接收一个数据块时,计算下载进度并报告 @@ -34,18 +55,24 @@ export function downloadSdk(url: string, destination: string, progress: vscode.P const percentage = (downloadedSize / totalSize) * 100; // increment是一个累加量,应每次累加当前数据块大小占总大小的比例 - progress.report({ increment: ((chunk.length / totalSize) * 100 * 0.8), message: `Downloading SDK ... ${percentage.toFixed(2)}%` }); + // progress.report({ increment: ((chunk.length / totalSize) * 100 * 0.8), message: `Downloading SDK ... ${percentage.toFixed(2)}%` }); + progress.report({ increment: ((chunk.length / totalSize) * 100 * 0.8), message: vscode.l10n.t('Downloading SDK ... {0}%', percentage.toFixed(2)) }); }); - response.pipe(file); - file.on('finish', () => { + response.pipe(file); //根据https请求返回的数据写入文件 + file.on('finish', () => { //当所有数据已被写入时,触发finish事件,关闭文件并用resolve更新Promise状态为完成 file.close(); resolve(); }); } else { - vscode.window.showErrorMessage(`Connection failed! Statuscode: ${response.statusCode}`); - reject(new Error(`Failed to get '${url}' (${response.statusCode})`)); + // vscode.window.showErrorMessage(`Connection failed! Statuscode: ${response.statusCode}`); + // reject(new Error(`Failed to get '${url}' (${response.statusCode})`)); + if (response.statusCode) { + vscode.window.showErrorMessage(vscode.l10n.t('Connection failed! Statuscode: {0}', response.statusCode)); + reject(new Error(vscode.l10n.t('Failed to get \'{0}\' ({1})', url, response.statusCode))); + } + } - }).on('error', (err) => { + }).on('error', (err) => { //若https请求错误,则使用fs提供的unlink方法删除目标路径的文件,在unlink方法的回调函数中,用reject更新Promise状态为出错,并传递错误信息err fs.unlink(destination, () => reject(err)); }); }); @@ -77,155 +104,303 @@ export function extractTarGz(filePath: string, destination: string): Promise { return new Promise((resolve, reject) => { - if (platform === "win32") { //Windows - terminal.sendText(`Expand-Archive -Path \"${filePath}\" -DestinationPath \"${destination}\"`); + if (platform === "win32") { + terminal.sendText(`Expand-Archive -Path \"${filePath}\" -DestinationPath \"${destination}\" -Force`); terminal.processId?.then( () => { resolve(); }, (err) => { - vscode.window.showErrorMessage(`Error extracting file: ${err}`); + // vscode.window.showErrorMessage(`Error extracting file: ${err}`); + vscode.window.showErrorMessage(vscode.l10n.t('Error extracting file: {0}', err)); reject(err); } ); - } else { //Linux + + } else { terminal.sendText(`unzip ${filePath} -d ${destination}`); terminal.processId?.then( () => { resolve(); }, (err) => { - vscode.window.showErrorMessage(`Error extracting file: ${err}`); + vscode.window.showErrorMessage(vscode.l10n.t('Error extracting file: {0}', err)); reject(err); } ); } }); - - } // windows系统下对三方库进行交叉编译 -function crossCompile_win32(terminal: vscode.Terminal | undefined, thirdPartyPath: string, compileTool: string, ohArchitecture: string, nativePath: string, generatePath: string): Promise { +function crossCompile_win32(terminal: vscode.Terminal | undefined, thirdPartyPath: string, configPath: string, compileTool: string, ohArchitecture: string[], nativePath: string, ohCrossCompilePath: string): Promise { return new Promise((resolve, reject) => { - vscode.window.showInformationMessage("Starting compilation on Windows."); + vscode.window.showInformationMessage(WINDOWS_START); if (terminal === undefined) { //若使用本地的sdk,不进行解压操作,则terminal为undefined,在编译前进行创建 terminal = terminal = vscode.window.createTerminal({ - name: "OpenHarmony cross compile", - cwd: thirdPartyPath + name: TERMINAL_TITLE, }); - } else { //若使用下载的sdk,解压完要切换到三方库目录,再进行后续编译操作 + terminal.show(); + } else { //若使用下载的sdk,解压完要切换到三方库目录所在的驱动器盘符,以便进行后续编译操作 const driveLetter = thirdPartyPath.split('/')[0]; //获取三方库目录所在的驱动器盘符,如d: terminal.sendText(`if ($?) {${driveLetter}}`); - terminal.sendText(`if ($?) {cd ${thirdPartyPath}}`); } - if (compileTool === "cmake") { - const command1 = "mkdir ohCrossCompile_build"; - const command2 = "cd ohCrossCompile_build"; - const command3 = `${nativePath}/build-tools/cmake/bin/cmake.exe -G "MinGW Makefiles" -DCMAKE_SH="CMAKE_SH-NOTFOUND" -DCMAKE_TOOLCHAIN_FILE=${nativePath}/build/cmake/ohos.toolchain.cmake -DCMAKE_INSTALL_PREFIX=${generatePath} -DOHOS_ARCH=${ohArchitecture} .. -L`; - console.log(command3); - const command4 = "mingw32-make"; - const command5 = "mingw32-make install"; - terminal.sendText(`if ($?) {${command1}} ; if ($?) {${command2}} ; if ($?) {${command3}} ; if ($?) {${command4}} ; if ($?) {${command5}}`); - terminal.processId.then( - () => { - resolve(); - }, - (err) => { - vscode.window.showErrorMessage(`Error occured while compiling. Error: ${err}`); - reject(err); + const configContent = JSON.parse(fs.readFileSync(configPath, 'utf8')); + + // 若配置文件中actions为空,则根据settings设置actions + if (configContent.actions === undefined || configContent.actions.length === 0) { + let actions = new Array(); + for (let arch of ohArchitecture) { //对每个目标系统架构,先组装出commands为空的action + let action = { + compileTool: compileTool, + ohArchitecture: arch, + nativePath: nativePath, + thirdPartyPath: thirdPartyPath, + installPath: `${ohCrossCompilePath}/${arch}/installed`, + cwd: "", + commands: [] + }; + if (compileTool === "cmake") { + action.cwd = `${ohCrossCompilePath}/${arch}`; + } else { + action.cwd = `${thirdPartyPath}`; } - ); - } else if (compileTool === "make") { - let target: string; - if(ohArchitecture === "arm64-v8a") { //64位系统 - target = "aarch64-linux-ohos"; - } else { //32位系统 - target = "arm-linux-ohos"; + actions.push(action); } + configContent.actions = actions; + } - const command1 = `mingw32-make CC=\"${nativePath}/llvm/bin/clang.exe --target=${target}\" AR=${nativePath}/llvm/bin/llvm-ar.exe RANDLIB=${nativePath}/llvm/bin/llvm-ranlib.exe`; - const command2 = `mingw32-make install PREFIX=${generatePath}`; - // terminal.sendText(`if ($?) {${command1}} ; if ($?) {${command2}}`); - terminal.sendText(`${command1} ; ${command2}`); - terminal.processId.then( - () => { - resolve(); - }, - (err) => { - vscode.window.showErrorMessage(`Error occured while compiling. Error: ${err}`); - reject(err); + // 对配置文件中每个action,若其commands为空,则组装出默认命令 + for (let action of configContent.actions) { + // vscode.window.showInformationMessage(`Compiled files of ${action.ohArchitecture} system will be installed at ${action.installPath}. `); + vscode.window.showInformationMessage(vscode.l10n.t('Compiled files of {0} system will be installed at {1}. ', action.ohArchitecture, action.installPath)); + if (action.commands === undefined || action.commands.length === 0) { + let commands = new Array(); + if (action.compileTool === "cmake") { + commands.push({ + command: `cd ${action.cwd}`, + arguments: [] + }); + commands.push({ + command: `${action.nativePath}/build-tools/cmake/bin/cmake.exe`, + arguments: [ + "-G \"MinGW Makefiles\"", + "-DCMAKE_SH=\"CMAKE_SH-NOTFOUND\"", + `-DCMAKE_TOOLCHAIN_FILE=${action.nativePath}/build/cmake/ohos.toolchain.cmake`, + `-DCMAKE_INSTALL_PREFIX=${action.installPath}`, + `-DOHOS_ARCH=${action.ohArchitecture}`, + "../..", + "-L" + ] + }); + commands.push({ + command: "mingw32-make", + arguments: [] + }); + commands.push({ + command: "mingw32-make install", + arguments: [] + }); + } else if (action.compileTool === "make") { + let target: string; + if (action.ohArchitecture === "arm64-v8a") { + target = "aarch64-linux-ohos"; + } else { + target = "arm-linux-ohos"; + } + commands.push({ + command: `cd ${action.cwd}`, + arguments: [] + }); + if (ohArchitecture.length > 1) { + commands.push({ + command: "mingw32-make clean", + arguments: [] + }); + } + commands.push({ + command: "mingw32-make", + arguments: [ + `CC=\"${action.nativePath}/llvm/bin/clang.exe --target=${target}\"`, + `AR=${action.nativePath}/llvm/bin/llvm-ar.exe`, + `RANDLIB=${action.nativePath}/llvm/bin/llvm-ranlib.exe` + ] + }); + commands.push({ + command: "mingw32-make install", + arguments: [ + `PREFIX=${action.installPath}` + ] + }); } - ); + action.commands = commands; + } } + fs.writeFileSync(configPath, JSON.stringify(configContent, null, 4), 'utf8'); + + // 把所有actions的命令拼接在一起,送入终端执行 + let finalCommand = ""; + for (let action of configContent.actions) { + for (let item of action.commands) { + finalCommand = finalCommand.concat(item.command); + for (let i = 0; i <= item.arguments.length - 1; i++) { + finalCommand = finalCommand.concat(` ${item.arguments[i]}`); + } + finalCommand = finalCommand.concat(" ; "); + } + } + terminal.sendText(finalCommand); + console.log(finalCommand); + terminal.processId.then( + () => { + resolve(); + }, + (err) => { + // vscode.window.showErrorMessage(`Error occured while compiling. Error: ${err}`); + vscode.window.showErrorMessage(vscode.l10n.t('Error occured while compiling. Error: {0}', err)); + reject(err); + } + ); }); } // linux系统下对三方库进行交叉编译 -function crossCompile_linux(terminal: vscode.Terminal | undefined, thirdPartyPath: string, compileTool: string, ohArchitecture: string, nativePath: string, generatePath: string): Promise { +function crossCompile_linux(terminal: vscode.Terminal | undefined, thirdPartyPath: string, configPath: string, compileTool: string, ohArchitecture: string[], nativePath: string, ohCrossCompilePath: string): Promise { return new Promise((resolve, reject) => { - vscode.window.showInformationMessage("Starting compilation on Linux."); - // vscode.window.showInformationMessage("Please enter your password in the newly opened terminal to continue."); + vscode.window.showInformationMessage(LINUX_START); if (terminal === undefined) { //若使用本地的sdk,不进行解压操作,则terminal为undefined,在编译前进行创建 terminal = terminal = vscode.window.createTerminal({ - name: "OpenHarmony cross compile", - cwd: thirdPartyPath + name: TERMINAL_TITLE, + // cwd: thirdPartyPath }); - } else { //若使用下载的sdk,解压完要切换到三方库目录,再进行后续编译操作 - terminal.sendText(`cd ${thirdPartyPath}`); + terminal.show(); + } + const configContent = JSON.parse(fs.readFileSync(configPath, 'utf8')); + + // 若配置文件中actions为空,则根据settings设置actions + if (configContent.actions === undefined || configContent.actions.length === 0) { + let actions = new Array(); + for (let arch of ohArchitecture) { //对每个目标系统架构,先组装出commands为空的action + let action = { + compileTool: compileTool, + ohArchitecture: arch, + nativePath: nativePath, + thirdPartyPath: thirdPartyPath, + installPath: `${ohCrossCompilePath}/${arch}/installed`, + cwd: "", + commands: [] + }; + if (compileTool === "cmake") { + action.cwd = `${ohCrossCompilePath}/${arch}`; + } else { + action.cwd = `${thirdPartyPath}`; + } + actions.push(action); + } + configContent.actions = actions; } - if (compileTool === "cmake") { - const command1 = "mkdir ohCrossCompile_build"; - const command2 = "cd ohCrossCompile_build"; - // const command3 = `sudo ${nativePath}/build-tools/cmake/bin/cmake -DCMAKE_TOOLCHAIN_FILE=/${nativePath}/build/cmake/ohos.toolchain.cmake -DCMAKE_INSTALL_PREFIX=${generatePath} -DOHOS_ARCH=${ohArchitecture} .. -L`; - const command3 = `${nativePath}/build-tools/cmake/bin/cmake -DCMAKE_TOOLCHAIN_FILE=/${nativePath}/build/cmake/ohos.toolchain.cmake -DCMAKE_INSTALL_PREFIX=${generatePath} -DOHOS_ARCH=${ohArchitecture} .. -L`; - // const command4 = "sudo make"; - const command4 = "make"; - const command5 = "make install"; - terminal.sendText(`${command1} && ${command2} && ${command3} && ${command4} && ${command5}`); - terminal.processId?.then( - () => { - resolve(); - }, - (err) => { - vscode.window.showErrorMessage(`Error occured while compiling. Error: ${err}`); - reject(err); + // 对配置文件中每个action,若其commands为空,则组装出默认命令 + for (let action of configContent.actions) { + vscode.window.showInformationMessage(vscode.l10n.t('Compiled files of {0} system will be installed at {1}. ', action.ohArchitecture, action.installPath)); + if (action.commands === undefined || action.commands.length === 0) { + let commands = new Array(); + if (action.compileTool === "cmake") { + commands.push({ + command: `cd ${action.cwd}`, + arguments: [] + }); + commands.push({ + command: `${action.nativePath}/build-tools/cmake/bin/cmake`, + arguments: [ + `-DCMAKE_TOOLCHAIN_FILE=${action.nativePath}/build/cmake/ohos.toolchain.cmake`, + `-DCMAKE_INSTALL_PREFIX=${action.installPath}`, + `-DOHOS_ARCH=${action.ohArchitecture}`, + "../..", + "-L" + ] + }); + commands.push({ + command: "make", + arguments: [] + }); + commands.push({ + command: "make install", + arguments: [] + }); + } else if (action.compileTool === "make") { + let target: string; + if (action.ohArchitecture === "arm64-v8a") { + target = "aarch64-linux-ohos"; + } else { + target = "arm-linux-ohos"; + } + commands.push({ + command: `cd ${action.cwd}`, + arguments: [] + }); + if (ohArchitecture.length > 1) { + commands.push({ + command: "make clean", + arguments: [] + }); + } + commands.push({ + command: "make", + arguments: [ + `CC=\"${action.nativePath}/llvm/bin/clang --target=${target}\"`, + `AR=${action.nativePath}/llvm/bin/llvm-ar`, + `RANDLIB=${action.nativePath}/llvm/bin/llvm-ranlib` + ] + }); + commands.push({ + command: "make install", + arguments: [ + `PREFIX=${action.installPath}` + ] + }); } - ); - } else if (compileTool === "make") { - let target: string; - if(ohArchitecture === "arm64-v8a") { //64位系统 - target = "aarch64-linux-ohos"; - } else { //32位系统 - target = "arm-linux-ohos"; + action.commands = commands; } - const command1 = `sudo make CC=\"${nativePath}/llvm/bin/clang --target=${target}\" AR=${nativePath}/llvm/bin/llvm-ar RANDLIB=${nativePath}/llvm/bin/llvm-ranlib`; - const command2 = `make install PREFIX=${generatePath}`; - // terminal.sendText(`${command1} && ${command2}`); - terminal.sendText(`${command1} ; ${command2}`); - terminal.processId?.then( - () => { - resolve(); - }, - (err) => { - vscode.window.showErrorMessage(`Error occured while compiling. Error: ${err}`); - reject(err); + } + fs.writeFileSync(configPath, JSON.stringify(configContent, null, 4), 'utf8'); + + // 把所有actions的命令拼接在一起,送入终端执行 + let finalCommand = ""; + for (let action of configContent.actions) { + for (let item of action.commands) { + finalCommand = finalCommand.concat(item.command); + for (let i = 0; i <= item.arguments.length - 1; i++) { + finalCommand = finalCommand.concat(` ${item.arguments[i]}`); } - ); + finalCommand = finalCommand.concat(" ; "); + } } + terminal.sendText(finalCommand); + console.log(finalCommand); + terminal.processId.then( + () => { + resolve(); + }, + (err) => { + vscode.window.showErrorMessage(vscode.l10n.t('Error occured while compiling. Error: {0}', err)); + reject(err); + } + ); }); } -export function crossCompile(platform: string, terminal: vscode.Terminal | undefined, thirdPartyPath: string, compileTool: string, ohArchitecture: string, nativePath: string, generatePath: string) { +export function crossCompile(platform: string, terminal: vscode.Terminal | undefined, configPath: string, thirdPartyPath: string, compileTool: string, ohArchitecture: string[], nativePath: string, ohCrossCompilePath: string) { if (platform === "win32") { - crossCompile_win32(terminal, thirdPartyPath, compileTool, ohArchitecture, nativePath, generatePath); + crossCompile_win32(terminal, thirdPartyPath, configPath, compileTool, ohArchitecture, nativePath, ohCrossCompilePath); } else { - crossCompile_linux(terminal, thirdPartyPath, compileTool, ohArchitecture, nativePath, generatePath); + crossCompile_linux(terminal, thirdPartyPath, configPath, compileTool, ohArchitecture, nativePath, ohCrossCompilePath); } } \ No newline at end of file