• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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                } else {
51                    Logger.err('make fail');
52                }
53            });
54        });
55        udpServer_.on('error', (e) => {
56            Logger.err('udp error');
57        });
58        udpServer_.on('message', (msg, rinfo) => {
59            let acmd = msg.toString();
60            let ret = AnalyzeCommand.analyze(acmd);//解析命令msg
61            if (ret.length > 0) {
62                analyzeResult.push(...ret);
63            }
64            udpServer_.send('ok', 0, 2, rinfo.port, rinfo.address);//反馈ok给make继续执行
65        });
66    }
67    static analyzeBreakup() {
68        let acmd = '';
69        for (let l of dlist) {
70            if (l.endsWith('\\')) { // 合并带有换行符的命令
71                acmd += l;
72            }
73            else {
74                acmd = getAcmd(acmd, l);
75            }
76        }
77    }
78    static analyze(makeProjectFile) {
79        let makeProjectPath = path.parse(makeProjectFile);
80        if (!fs.existsSync(makeProjectFile)) {
81            Logger.err('Makefile not exist in ' + makeProjectPath.dir);
82            return;
83        }
84        if (AnalyzeMake.USE_UDP_COLLECTOR) {
85            AnalyzeMake.collectByUdp(makeProjectPath.dir);
86            return;
87        }
88        Tool.pushd(makeProjectPath.dir);
89        let ret = childProcess.spawn('make', ['-C', makeProjectPath.dir, '-n']);
90        let cmdlist = [];
91        let analyzeResult = [];
92        let procData = '';
93        ret.stdout.on('data', (data) => {
94            procData += data.toString();
95            let p = procData.lastIndexOf('\n');
96            if (p < 0) {
97                return;
98            }
99            let dlist = procData.substring(0, p).split('\n');
100            procData = procData.substring(p + 1);
101            AnalyzeMake.analyzeBreakup(dlist, cmdlist, analyzeResult);
102        });
103        ret.stderr.on('data', (data) => {
104            Logger.err(data.toString());
105        });
106        ret.on('close', (code) => {
107            if (code === 0) {
108                Logger.info('-----------------------------make ok');
109                Tool.generateTarget(makeProjectPath.dir, analyzeResult);//生成结果目标
110            } else {
111                Logger.err('make fail');
112            }
113        });
114    }
115}
116
117function getAcmd(acmd, l) {
118  acmd += l;
119  if (acmd.length > 0) {
120    cmdlist.push(acmd);
121    let ret = AnalyzeCommand.analyze(acmd);
122    if (ret.length > 0) {
123      analyzeResult.push(...ret);
124    }
125  }
126  acmd = '';
127  return acmd;
128}
129
130module.exports = {
131  AnalyzeMake
132};