最近在学习powershell,随便写了个可以加快编译的脚本
不得不说,powershell算是windows下最好用的脚本工具了
理论上这个脚本也是可以在linux下使用的, powershell安装教程
windows下的脚本要用gbk编码,蛋疼…
linux下加快编译的脚本请移步ERLANG快速编译脚本


脚本基本原理是找出项目中修改时间大于timefile的最后修改时间的文件,然后分段编译
脚本请手动修改编码为gbk,否则报错
下面脚本对应的目录结构如下:

1
2
3
4
5
6
7
8
9
10
proj_root
├─src
├─include
├─ebin
│ └─mmake.beam
├─script
│ ├─ctl.ps1
│ └─funlib.ps1
├─Emakefile
└─timefile

ctl.ps1view raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#encoding:gbk

$cur_dir = Split-Path $MyInvocation.MyCommand.Path
$dir_main = "$cur_dir/../"
$dir_erl = $dir_main
$dir_log = "$dir_erl/logs"
$werl = "werl"
$erl = "erl"
$node_name = "cymmo"
$node_domain = "127.0.0.1"
$cookie = "cy_log"
$erl_port_min = 41001
$erl_port_max = 41100

$param_kernel = "-kernel inet_dist_listen_min $erl_port_min -kernel inet_dist_listen_max $erl_port_max"
$param_other = "+P 204800 -smp enable -server_base $dir_main -setcookie $cookie"
$param_env = "-evn ERL_MAX_PORTS 10240"
$param_pa = "-pa $dir_erl/config -pa $dir_erl/ebin -pa $dir_erl/baseebin"

$param_config_game = "-config $dir_erl/config/run_game"
$game_dump_log_file = "-env ERL_CRASH_DUMP $dir_log/game_crash.dump"

$conf = @{
cur_dir = $cur_dir;
dir_main = $dir_main;
dir_erl = $dir_erl;
dir_log = $dir_log;
werl = $werl;
erl = $erl;
node_name = $node_name;
node_domain = $node_domain;
cookie = $cookie;
erl_port_min = $erl_port_min;
erl_port_max = $erl_port_max;

param_kernel = $param_kernel;
param_other = $param_other;
param_env = $param_env;
param_pa = $param_pa;

param_config_game = $param_config_game;
game_dump_log_file = $game_dump_log_file
}

. (Join-Path $conf["cur_dir"] funlib.ps1)

if ($args.Count -eq 0) {
fun_wait_input $conf
}
else {
fun_run $conf $args[0]
}
funlib.ps1view raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#encoding:gbk

function fun_make($conf){
$src = $conf["dir_main"] + "/src"
$inc = $conf["dir_main"] + "/include"
$timefile = $conf["dir_main"] + "/timefile"
$latestTime = $(Get-Item $timefile).LastWriteTime
$now = $(Get-Date)

function get_hrl_str(){
begin{ $list = @() }
process{ $list += $_.Name }
end{
$str = $list -join "|"
if($str -ne ""){
$str = "($str)"
}
$str
}
}
$chhrl_str = Get-ChildItem $inc -Include *.hrl -Recurse | Where-Object {$_.LastWriteTime -gt $latestTime} | get_hrl_str

## 使用管道获取变化的文件
## 1. 获取所有文件
## 2. 检测变化文件
## 3. 生成文件全名列表
function get_erl_list(){
## 每次编译100个文件,防止文件过多造成字符串过长报错
## https://support.microsoft.com/zh-cn/help/830473/command-prompt-cmd-exe-command-line-string-limitation
begin{
$ii = 0
$list1 = @()
$list = @()
}
process{
$f = $_.FullName -replace "\\", "/"
$f = "`\`"$f`\`""
$list1 += $f
$i++
if ($i % 2 -eq 0){
$list += $list1 -join ","
$i = 0
$list1 = @()
}
}
end{
if($list1){
$list += $list1 -join ","
}
$list
}
}
$erl_list = Get-ChildItem $src -Include *.erl -Exclude .svn,.git -Recurse | Where-Object {
if ( $(Get-Item $_.FullName).LastWriteTime -gt $latestTime ){
return $_
}
if($chhrl_str -eq ""){
return $false
}
if (Select-String -Path $_.FullName -Pattern $chhrl_str -Quiet) {
return $_
}else{
return $false
}
} | get_erl_list

Set-Location $conf["dir_erl"]
## 在windows下
## 直接mmake:files(500, [])无效
## 必须mmake:files(500, [], Opts)
## why?
$cmd_str = '{0} {1} -noshell -eval "{{ok,[{{_, Opts}}|_]}}=file:consult(\"./Emakefile\"),case mmake:files(500,[{2}], Opts) of up_to_date -> init:stop(); _ -> init:stop(1) end"'
$compile_status = $true
if($erl_list.gettype().Name -eq "String"){
$erl_list = @() + $erl_list
}
for ($i = 0; $i -lt $erl_list.Count; $i++) {
$erl_str = $erl_list[$i]
$cmd = $cmd_str -f $conf["erl"], $conf["param_pa"], $erl_str
cmd /C $cmd
if ($?) {
continue
}else{
$compile_status = $false
break
}
}
# $cmd = $cmd_str -f $conf["erl"], $conf["param_pa"], $erl_str
cmd /C $cmd
if ($compile_status) {
Write-Output "=============> 编译成功"
$now.ToString() | Out-File $timefile -Append
(Get-Item $timefile).LastWriteTime = $now
}else{
Write-Error "==============> 编译失败"
}
}

function fun_start_game ($conf) {
$node_name = $conf["node_name"]
$node_domain = $conf["node_domain"]
$param_pa = $conf["param_pa"]
$param_kernel = $conf["param_kernel"]
$param_env = $conf["param_env"]
$game_dump_log_file = $conf["game_dump_log_file"]
$param_other = $conf["param_other"]
$param_config_game = $conf["param_config_game"]
Set-Location $conf["dir_erl"]
$arg_str = "-name ${node_name}_game@$node_domain"
$arg_str += " $param_pa $param_kernel $param_env"
$arg_str += " $game_dump_log_file $param_other $param_config_game"
$arg_str += " -hidden -s main -s reloader"
Start-Process -FilePath $conf["werl"] -ArgumentList $arg_str
}

function fun_run ($conf,$inp) {
switch ($inp) {
"make" {
fun_make $conf
break
}
"start_game" {
fun_start_game $conf
break
}
Default {
Write-Output "错误的命令"
}
}
Set-Location $conf["cur_dir"]
}
function fun_wait_input ($conf) {
$helpText = @"
==============================
make : 编译源码
start_game : 启动游戏服
quit : 结束运行
==============================
"@
Write-Output $helpText
$inp = Read-Host "请选择"
$inp = $inp.Trim().ToLower()
switch ($inp) {
"" {
fun_wait_input $conf
break
}
"quit" {
Set-Location $conf["cur_dir"]
break
}
Default {
fun_run $conf $inp
fun_wait_input $conf
}
}
}