1/* 2* Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. 3* Licensed under the Apache License, Version 2.0 (the "License"); 4* you may not use this file except in compliance with the License. 5* You may obtain a copy of the License at 6* 7* http://www.apache.org/licenses/LICENSE-2.0 8* 9* Unless required by applicable law or agreed to in writing, software 10* distributed under the License is distributed on an "AS IS" BASIS, 11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12* See the License for the specific language governing permissions and 13* limitations under the License. 14*/ 15const path = require('path'); 16const fs = require('fs'); 17 18class Tool { 19 constructor() { 20 21 } 22 static CURRENT_TOOL_PATH = null;//生成工具或插件所在路径,用于找到res 23 static OHOS_PROJECT_PATH = '/home/xx/ohos'; 24 static OHOS_PORTING_TO = 'third_party/opencv'; 25 static OHOS_PRODUCT_OUTPUT_PATH = 'out/rk3568-khdvk';//输出目录 26 static OHOS_SUBSYSTEM_NAME = 'common'; 27 static OHOS_PART_NAME = 'common'; 28 static globalJsonCfg = null; // cfg.json 配置文件 29 static allowedCxx = null; // cxx编译中允许处理的文件后缀列表 30 static allowedC = null; // c编译中允许处理的文件后缀列表 31 32 33 static getResAbsPath(respath) { 34 return path.join(Tool.CURRENT_TOOL_PATH, respath); 35 } 36 static getCMakeToolchain() { 37 switch (process.platform) { 38 case 'win32': 39 return path.join(Tool.CURRENT_TOOL_PATH, 'res/win/ohos.toolchain.cmake'); 40 case 'linux': 41 return path.join(Tool.CURRENT_TOOL_PATH, 'res/linux/ohos.toolchain.cmake'); 42 case 'darwin': 43 return path.join(Tool.CURRENT_TOOL_PATH, 'res/mac/ohos.toolchain.cmake'); 44 default: 45 Logger.err('不支持 %s 平台'.format(process.platform)); 46 return ''; 47 } 48 } 49 static getMakeRaw() { 50 switch (process.platform) { 51 case 'win32': 52 return path.join(Tool.CURRENT_TOOL_PATH, 'res/win/bin/make_raw.exe'); 53 case 'linux': 54 return path.join(Tool.CURRENT_TOOL_PATH, 'res/linux/bin/make_raw'); 55 case 'darwin': 56 return path.join(Tool.CURRENT_TOOL_PATH, 'res/mac/bin/make_raw'); 57 default: 58 Logger.err('不支持 %s 平台'.format(process.platform)); 59 return ''; 60 } 61 } 62 static getMake() { 63 switch (process.platform) { 64 case 'win32': 65 return path.join(Tool.CURRENT_TOOL_PATH, 'res/win/bin/make.exe'); 66 case 'linux': 67 return path.join(Tool.CURRENT_TOOL_PATH, 'res/linux/bin/make'); 68 case 'darwin': 69 return path.join(Tool.CURRENT_TOOL_PATH, 'res/mac/bin/make'); 70 default: 71 Logger.err('不支持 %s 平台'.format(process.platform)); 72 return ''; 73 } 74 } 75 static getCMake() { 76 switch (process.platform) { 77 case 'win32': 78 return path.join(Tool.OHOS_PROJECT_PATH, 'prebuilts/cmake/windows-x86/bin/cmake.exe'); 79 case 'linux': 80 case 'darwin': 81 return path.join(Tool.OHOS_PROJECT_PATH, 'prebuilts/cmake/linux-x86/bin/cmake'); 82 default: 83 Logger.err('不支持 %s 平台'.format(process.platform)); 84 return ''; 85 } 86 87 } 88 static swapPath(p, swapd) { 89 while (p.indexOf('\\') >= 0) { 90 p = p.replace('\\', '/'); 91 } 92 return p; 93 } 94 95 static DIRECTORY_STACK = []; 96 static CURRENT_DIR = null; 97 static pushd(path) { 98 path = Tool.swapPath(path, false); 99 Tool.DIRECTORY_STACK.push(process.cwd()); 100 process.chdir(path); 101 Tool.CURRENT_DIR = path; 102 } 103 static popd() { 104 let d = Tool.DIRECTORY_STACK.pop(); 105 if (d) { 106 process.chdir(d); 107 Tool.CURRENT_DIR = d; 108 } 109 } 110 static BACKUP_DIRECTORY = []; 111 static backupd(bkp) { 112 Tool.BACKUP_DIRECTORY[bkp] = Tool.DIRECTORY_STACK.concat([process.cwd()]); 113 } 114 static recoverd(bkp) { 115 Tool.DIRECTORY_STACK = [].concat(Tool.BACKUP_DIRECTORY[bkp]); 116 Tool.popd(); 117 } 118 119 static TARGET_TYPE = { 120 NONE: 0, 121 MAKE: 1, 122 GN: 2, 123 CMAKE: 3, 124 SCONS: 4, 125 VS: 5, 126 }; 127 static GENERATE_TARGET_TYPE = Tool.TARGET_TYPE.GN; 128 129 static setTarget(type) {//设置生成目标 130 Tool.GENERATE_TARGET_TYPE = type; 131 } 132 static generateTarget(projectPath, analyzeResult) { 133 switch (Tool.GENERATE_TARGET_TYPE) { 134 case Tool.TARGET_TYPE.NONE: 135 break; 136 case Tool.TARGET_TYPE.GN: 137 const { GenerateGn } = require('./generate_gn'); 138 GenerateGn.generate(projectPath, analyzeResult); 139 break; 140 default: 141 Logger.err('generate target not support'); 142 break; 143 } 144 } 145 146 static MOCK_ENUM = { 147 NO_MOCK: 1, 148 MOCK_RECORD: 2, 149 MOCK_RUN: 3, 150 }; 151 static MOCK_TYPE = Tool.MOCK_ENUM.NO_MOCK; 152 153 /** 154 * 获取Json配置文件内容 155 * @returns 156 */ 157 static getJsonCfg() { 158 if (this.globalJsonCfg === null || this.globalJsonCfg === undefined) { 159 let jsonFilePath = path.join(Tool.CURRENT_TOOL_PATH, 'res/cfg.json'); 160 let jsonFile = fs.readFileSync(jsonFilePath, { encoding: 'utf8' }); 161 this.globalJsonCfg = JSON.parse(jsonFile); 162 this.globalJsonCfg.fileSuffix = this.globalJsonCfg.fileSuffix ? ',' + this.globalJsonCfg.fileSuffix : ''; 163 this.globalJsonCfg.compileflag = this.globalJsonCfg.compileflag ? ',' + this.globalJsonCfg.compileflag : ''; 164 } 165 166 return this.globalJsonCfg; 167 } 168 169 /** 170 * 获取cxx编译中允许处理的文件后缀名列表 171 * @returns cxx编译中允许处理的文件后缀名列表 172 */ 173 static getAllowedCxx() { 174 if (this.allowedCxx === null || this.allowedCxx === undefined) { 175 this.allowedCxx = {}; 176 let jsonCfg = this.getJsonCfg(); 177 let allowedCxxSuffix = '.cpp, .cxx, .cc, .o, .z, .so, .a' + jsonCfg.fileSuffix; 178 this.allowedCxx.fileSuffix = 179 allowedCxxSuffix.split(',').map(item => item.trim()).filter(item => item !== ''); 180 let allowedFlag = '--target=, -march=, -mfloat-abi=, -mfpu=, -fsigned-char, -ffast-math, -rdynamic, ' + 181 '-UNDEBUG, -fno-threadsafe-statics, -fno-common, -fno-strict-aliasing, -fcolor-diagnostics, ' + 182 '-fstrict-aliasing, -fdiagnostics-show-option' + jsonCfg.compileflag; 183 this.allowedCxx.compileflag = allowedFlag.split(',').map(item => item.trim()).filter(item => item !== ''); 184 } 185 return this.allowedCxx; 186 } 187 188 /** 189 * 获取c编译中允许处理的文件后缀名列表 190 * @returns c编译中允许处理的文件后缀名列表 191 */ 192 static getAllowedC() { 193 if (this.allowedC === null || this.allowedC === undefined) { 194 this.allowedC = {}; 195 let jsonCfg = this.getJsonCfg(); 196 let allowedCSuffix = '.c, .o, .o", .a, .S, .so' + jsonCfg.fileSuffix; 197 this.allowedC.fileSuffix = allowedCSuffix.split(',').map(item => item.trim()).filter(item => item !== ''); 198 let allowedFlag = '--target=, -march=, -mfloat-abi=, -mfpu=, -fno-common, -fcolor-diagnostics, -ggdb, ' + 199 '-fno-strict-aliasing, -ldl, -flto, -fno-builtin, -fno-stack-protector, -fvisibility=default, ' + 200 '-fsigned-char, -fstack-protector-strong, -fdiagnostics-show-option' + 201 jsonCfg.compileflag; 202 this.allowedC.compileflag = allowedFlag.split(',').map(item => item.trim()).filter(item => item !== ''); 203 } 204 return this.allowedC; 205 } 206} 207 208String.prototype.format = function (...args) { 209 let result = this; 210 let reg = new RegExp('%[sd]{1}'); 211 for (let i = 0; i < args.length; i++) { 212 let p = result.search(reg); 213 if (p < 0) { 214 break; 215 } 216 result = result.substring(0, p) + args[i] + result.substring(p + 2, result.length); 217 } 218 return result; 219}; 220 221try { 222 Tool.VSCODE_INST = require('vscode'); 223} 224catch (err) { 225 Tool.VSCODE_INST = null; 226} 227 228module.exports = { 229 Tool 230}; 231 232const Logger = require('./logger');