Skip to content

Commit 7c34eab

Browse files
Parallel building (#187)
* feat: Check if a file has been modified in build.vsh * Support parallel compiling * Update readme for parallel compilation * build.vsh: Formatting
1 parent 8662a35 commit 7c34eab

3 files changed

Lines changed: 60 additions & 17 deletions

File tree

Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
.PHONY: all prod fmt test testfmt clean
22

3+
# Make doesn't have a built-in and reliable way to get the number of jobs...
4+
JOBS ?= 1
5+
36
all:
4-
@v run build.vsh
7+
@v run build.vsh --cpus=$(JOBS)
58

69
prod:
7-
@v run build.vsh -prod
10+
@v run build.vsh -prod --cpus=$(JOBS)
811

912
fmt:
1013
v fmt -w .

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ the command input/output consistent across the tools.
2828
## Building
2929

3030
Running `make` or `v run build.vsh` will build all the programs in `bin/`.
31+
Use `JOBS=N make` or `v run build.vsh --cpus=N` to compile in parallel.
3132

3233
Note: support for access to user account info (via utmp) is limited to POSIX-like platforms.
3334
And, so, for Windows, utilities requiring utmp support (uptime, users, who, whoami) are currently

build.vsh

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
#!/bin/env v
22

33
import time
4+
import runtime
5+
import flag
6+
import os
7+
8+
struct Config {
9+
jobs int @[long: cpus; short: 'j']
10+
}
411

512
const ignore_dirs = {
613
'windows': [
@@ -41,12 +48,10 @@ const ignore_dirs = {
4148

4249
unbuffer_stdout()
4350

44-
dump(user_os())
45-
dump(ignore_dirs)
46-
47-
args := arguments()
48-
vargs := if args.len > 1 { args[1..] } else { [] }
49-
dump(vargs)
51+
config, remaining := flag.to_struct[Config](os.args, skip: 1)!
52+
mut jobs := if config.jobs > 0 { config.jobs } else { runtime.nr_cpus() }
53+
mut vargs := remaining.clone()
54+
println('Using ${jobs} parallel jobs')
5055

5156
curdir := getwd()
5257
chdir('src')!
@@ -60,6 +65,8 @@ if !exists('${curdir}/bin') {
6065
sw_total := time.new_stopwatch()
6166
mut compiled := 0
6267
mut already_compiled := 0
68+
mut dirs_to_compile := []string{}
69+
6370
for dir in dirs {
6471
if dir in ignore_dirs {
6572
continue
@@ -85,16 +92,48 @@ for dir in dirs {
8592
}
8693
}
8794

88-
mut final_args := '-Wimpure-v'
89-
for arg in vargs {
90-
final_args += ' ' + arg
95+
dirs_to_compile << dir
96+
}
97+
98+
// Now compile in parallel
99+
ch := chan bool{cap: jobs}
100+
results_ch := chan bool{cap: dirs_to_compile.len}
101+
print_ch := chan string{cap: 100}
102+
103+
// Start printer thread, avoiding garbled text when building
104+
spawn fn [print_ch] () {
105+
for {
106+
msg := <-print_ch or { break }
107+
print(msg)
91108
}
92-
print('compiling ${dir:-20s}...')
93-
cmd := @VEXE + ' ${final_args} -o ${curdir}/bin/${dir} ./${dir}'
94-
sw := time.new_stopwatch()
95-
execute_or_panic(cmd)
96-
println(' took ${sw.elapsed().milliseconds()}ms .')
97-
compiled++
109+
}()
110+
111+
for dir in dirs_to_compile {
112+
// Acquire the current slot
113+
ch <- true
114+
spawn fn [ch, results_ch, dir, curdir, vargs, print_ch] () {
115+
defer {
116+
results_ch <- true
117+
// Released
118+
_ := <-ch
119+
}
120+
mut final_args := '-Wimpure-v'
121+
for arg in vargs {
122+
final_args += ' ' + arg
123+
}
124+
cmd := @VEXE + ' ${final_args} -o "${curdir}/bin/${dir}" "./${dir}"'
125+
sw := time.new_stopwatch()
126+
execute_or_panic(cmd)
127+
print_ch <- 'compiling ${dir:-20s}... took ${sw.elapsed().milliseconds()}ms .\n'
128+
}()
98129
}
130+
131+
// Wait for all compilations to finish
132+
for _ in 0 .. dirs_to_compile.len {
133+
_ := <-results_ch
134+
}
135+
136+
print_ch.close()
137+
compiled = dirs_to_compile.len
99138
println('> Compiled: ${compiled:3} tools in ${sw_total.elapsed().milliseconds()}ms. Already compiled and skipped: ${already_compiled} . All folders: ${dirs.len} .')
100139
chdir(curdir)!

0 commit comments

Comments
 (0)