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 childProcess = require("child_process"); 16const fs = require("fs") 17const path = require("path"); 18const { AnalyzeCommand } = require("./analyze_command"); 19const { Logger } = require("./logger"); 20const { Tool } = require("./tool"); 21 22class AnalyzeMake { 23 constructor() { 24 25 } 26 27 static USE_UDP_COLLECTOR = true; 28 static collectByUdp(makeProjectPath) { 29 const dgram = require("dgram"); 30 let udpServer_ = dgram.createSocket("udp4"); 31 let analyzeResult = []; 32 udpServer_.bind(6000); 33 udpServer_.on('listening', () => { 34 Tool.pushd(makeProjectPath); 35 let ret = childProcess.spawn(Tool.getMake(), ["-C", makeProjectPath, "-n"]); 36 ret.stdout.on('data', (data) => {//要有,不然不进入close 37 }); 38 ret.stderr.on('data', (data) => { 39 Logger.err(data.toString()); 40 }); 41 ret.on('close', (code) => { 42 if (code == 0) { 43 Logger.info("-----------------------------make ok"); 44 udpServer_.close(); 45 udpServer_ = null; 46 47 AnalyzeCommand.storeCommands(); 48 49 Tool.generateTarget(makeProjectPath, analyzeResult);//生成结果目标 50 } 51 else Logger.err("make fail"); 52 }); 53 }); 54 udpServer_.on('error', (e) => { 55 Logger.err("udp error"); 56 }); 57 udpServer_.on('message', (msg, rinfo) => { 58 let acmd = msg.toString(); 59 let ret = AnalyzeCommand.analyze(acmd);//解析命令msg 60 if (ret.length > 0) { 61 analyzeResult.push(...ret); 62 } 63 udpServer_.send("ok", 0, 2, rinfo.port, rinfo.address);//反馈ok给make继续执行 64 }); 65 } 66 static analyzeBreakup() { 67 let acmd = "" 68 for (let l of dlist) { 69 if (l.endsWith("\\")) { // 合并带有换行符的命令 70 acmd += l; 71 } 72 else { 73 acmd += l; 74 if (acmd.length > 0) { 75 cmdlist.push(acmd); 76 let ret = AnalyzeCommand.analyze(acmd); 77 if (ret.length > 0) { 78 analyzeResult.push(...ret); 79 } 80 } 81 acmd = ""; 82 } 83 } 84 } 85 static analyze(makeProjectFile) { 86 let makeProjectPath = path.parse(makeProjectFile); 87 if (!fs.existsSync(makeProjectFile)) { 88 Logger.err("Makefile not exist in " + makeProjectPath.dir); 89 return; 90 } 91 if (AnalyzeMake.USE_UDP_COLLECTOR) { 92 AnalyzeMake.collectByUdp(makeProjectPath.dir); 93 return; 94 } 95 Tool.pushd(makeProjectPath.dir); 96 let ret = childProcess.spawn("make", ["-C", makeProjectPath.dir, "-n"]); 97 let cmdlist = []; 98 let analyzeResult = []; 99 let procData = ""; 100 ret.stdout.on('data', (data) => { 101 procData += data.toString(); 102 let p = procData.lastIndexOf("\n"); 103 if (p < 0) { 104 return; 105 } 106 let dlist = procData.substring(0, p).split("\n"); 107 procData = procData.substring(p + 1); 108 AnalyzeMake.analyzeBreakup(dlist, cmdlist, analyzeResult); 109 }); 110 ret.stderr.on('data', (data) => { 111 Logger.err(data.toString()); 112 }); 113 ret.on('close', (code) => { 114 if (code == 0) { 115 Logger.info("-----------------------------make ok"); 116 Tool.generateTarget(makeProjectPath.dir, analyzeResult);//生成结果目标 117 } 118 else Logger.err("make fail"); 119 }); 120 } 121} 122 123module.exports = { 124 AnalyzeMake 125}