Skip to content

Instantly share code, notes, and snippets.

@bang590
Last active August 6, 2024 14:59
Show Gist options
  • Save bang590/8f3e9704f1c2661836cd to your computer and use it in GitHub Desktop.
Save bang590/8f3e9704f1c2661836cd to your computer and use it in GitHub Desktop.
XCode Linkmap Parser
var readline = require('readline'),
fs = require('fs');
var LinkMap = function(filePath) {
this.files = []
this.filePath = filePath
}
LinkMap.prototype = {
start: function(cb) {
var self = this
var rl = readline.createInterface({
input: fs.createReadStream(self.filePath),
output: process.stdout,
terminal: false
});
var currParser = "";
rl.on('line', function(line) {
if (line[0] == '#') {
if (line.indexOf('Object files') > -1) {
currParser = "_parseFiles";
} else if (line.indexOf('Sections') > -1) {
currParser = "_parseSection";
} else if (line.indexOf('Symbols') > -1) {
currParser = "_parseSymbols";
}
return;
}
if (self[currParser]) {
self[currParser](line)
}
});
rl.on('close', function(line) {
cb(self)
});
},
_parseFiles: function(line) {
var arr =line.split(']')
if (arr.length > 1) {
var idx = Number(arr[0].replace('[',''));
var file = arr[1].split('/').pop().trim()
this.files[idx] = {
name: file,
size: 0
}
}
},
_parseSection: function(line) {
},
_parseSymbols: function(line) {
var arr = line.split('\t')
if (arr.length > 2) {
var size = parseInt(arr[1], 16)
var idx = Number(arr[2].split(']')[0].replace('[', ''))
if (idx && this.files[idx]) {
this.files[idx].size += size;
}
}
},
_formatSize: function(size) {
if (size > 1024 * 1024) return (size/(1024*1024)).toFixed(2) + "MB"
if (size > 1024) return (size/1024).toFixed(2) + "KB"
return size + "B"
},
statLibs: function(h) {
var libs = {}
var files = this.files;
var self = this;
for (var i in files) {
var file = files[i]
var libName
if (file.name.indexOf('.o)') > -1) {
libName = file.name.split('(')[0]
} else {
libName = file.name
}
if (!libs[libName]) {
libs[libName] = 0
}
libs[libName] += file.size
}
var i = 0, sortLibs = []
for (var name in libs) {
sortLibs[i++] = {
name: name,
size: libs[name]
}
}
sortLibs.sort(function(a,b) {
return a.size > b.size ? -1: 1
})
if (h) {
sortLibs.map(function(o) {
o.size = self._formatSize(o.size)
})
}
return sortLibs
},
statFiles: function(h) {
var self = this
self.files.sort(function(a,b) {
return a.size > b.size ? -1: 1
})
if (h) {
self.files.map(function(o) {
o.size = self._formatSize(o.size)
})
}
return this.files
}
}
if (!process.argv[2]) {
console.log('usage: node linkmap.js filepath -hl')
console.log('-h: format size')
console.log('-l: stat libs')
return
}
var isStatLib, isFomatSize
var opts = process.argv[3];
if (opts && opts[0] == '-') {
if (opts.indexOf('h') > -1) isFomatSize = true
if (opts.indexOf('l') > -1) isStatLib = true
}
var linkmap = new LinkMap(process.argv[2])
linkmap.start(function(){
var ret = isStatLib ? linkmap.statLibs(isFomatSize)
: linkmap.statFiles(isFomatSize)
for (var i in ret) {
console.log(ret[i].name + '\t' + ret[i].size)
}
})
@dcty
Copy link

dcty commented Mar 26, 2015

请问一下 filePath 指的是什么?

@grittymindy
Copy link

filePath refers to the path of the link map file.
http://blog.cnbang.net/tech/2296/

@chaserr
Copy link

chaserr commented Jan 28, 2016

怎么去使用它

@Hackice
Copy link

Hackice commented Feb 13, 2016

usage: node linkmap.js filepath -hl
-h: format size
-l: stat libs

@hzm0318hzm
Copy link

如果有armv7和arm64统计的时候是不是就得在统计库大小的时候吧两个的统计都加起来呢,还有那个-l比只加-h大了点,这个是多统计了啥呢

@MoShenGuo
Copy link

image
你好 为什么我运行不起来?

@MoShenGuo
Copy link

你好 大神,这个txt文件除了统计库的大小 还有其他什么别的用处吗? 这个感觉也用处不大

@wangying3426
Copy link

这个好像不能统计 stripped 后的文件大小,有什么办法能统计 stripped 的大小吗?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment