From a6f235be87d56473f892495d9ea313decb4da123 Mon Sep 17 00:00:00 2001 From: SheatNoisette Date: Sat, 29 Oct 2022 18:40:32 +0200 Subject: [PATCH 1/4] feat: Check if a file has been modified in build.vsh --- Makefile | 7 +++++-- build.vsh | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 84798ea9..1859e5fb 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: all prod fmt test testfmt +.PHONY: all prod fmt test testfmt clean all: @v run build.vsh @@ -10,7 +10,10 @@ fmt: v fmt -w . test: - LANG=C v test . + LANG=C v test . testfmt: v fmt -verify . + +clean: + $(RM) -r bin diff --git a/build.vsh b/build.vsh index 0421bdc1..5962f1df 100755 --- a/build.vsh +++ b/build.vsh @@ -25,7 +25,21 @@ for dir in dirs { continue } - // TODO: don't build something if it is already built + // Get all of the of v files in the directory and get unix modifed time + mut modification_time := []i64{} + for src_file in ls(dir)!.filter(it.ends_with('.v')) { + modification_time << os.file_last_mod_unix('$dir/$src_file') + } + + // Check if the binary exists and is newer than the source files + // If it is, skip it + if exists('$curdir/bin/$dir') { + bin_mod_time := os.file_last_mod_unix('$curdir/bin/$dir') + // If the binary is newer than the source files, skip it + if modification_time.filter(it < bin_mod_time).len == modification_time.len { + continue + } + } mut final_args := '-Wimpure-v' for arg in vargs { From ba487827376dc1d6ab54df646cc33e1358c2adae Mon Sep 17 00:00:00 2001 From: SheatNoisette Date: Sun, 21 Dec 2025 09:55:09 +0100 Subject: [PATCH 2/4] Support parallel compiling --- Makefile | 7 ++++-- build.vsh | 69 +++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 59 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index 525e4bf9..0e3e9baf 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,13 @@ .PHONY: all prod fmt test testfmt clean +# Make doesn't have a built-in and reliable way to get the number of jobs... +JOBS ?= 1 + all: - @v run build.vsh + @v run build.vsh --cpus=$(JOBS) prod: - @v run build.vsh -prod + @v run build.vsh -prod --cpus=$(JOBS) fmt: v fmt -w . diff --git a/build.vsh b/build.vsh index 31741942..04f2606d 100755 --- a/build.vsh +++ b/build.vsh @@ -1,6 +1,13 @@ #!/bin/env v import time +import runtime +import flag +import os + +struct Config { + jobs int @[short: 'j'; long: cpus] +} const ignore_dirs = { 'windows': [ @@ -41,12 +48,10 @@ const ignore_dirs = { unbuffer_stdout() -dump(user_os()) -dump(ignore_dirs) - -args := arguments() -vargs := if args.len > 1 { args[1..] } else { [] } -dump(vargs) +config, remaining := flag.to_struct[Config](os.args, skip: 1)! +mut jobs := if config.jobs > 0 { config.jobs } else { runtime.nr_cpus() } +mut vargs := remaining.clone() +println('Using ${jobs} parallel jobs') curdir := getwd() chdir('src')! @@ -60,6 +65,8 @@ if !exists('${curdir}/bin') { sw_total := time.new_stopwatch() mut compiled := 0 mut already_compiled := 0 +mut dirs_to_compile := []string{} + for dir in dirs { if dir in ignore_dirs { continue @@ -85,16 +92,48 @@ for dir in dirs { } } - mut final_args := '-Wimpure-v' - for arg in vargs { - final_args += ' ' + arg + dirs_to_compile << dir +} + +// Now compile in parallel +ch := chan bool{cap: jobs} +results_ch := chan bool{cap: dirs_to_compile.len} +print_ch := chan string{cap: 100} + +// Start printer thread, avoiding garbled text when building +spawn fn [print_ch] () { + for { + msg := <-print_ch or { break } + print(msg) } - print('compiling ${dir:-20s}...') - cmd := @VEXE + ' ${final_args} -o ${curdir}/bin/${dir} ./${dir}' - sw := time.new_stopwatch() - execute_or_panic(cmd) - println(' took ${sw.elapsed().milliseconds()}ms .') - compiled++ +}() + +for dir in dirs_to_compile { + // Acquire the current slot + ch <- true + spawn fn [ch, results_ch, dir, curdir, vargs, print_ch] () { + defer { + results_ch <- true + // Released + _ := <-ch + } + mut final_args := '-Wimpure-v' + for arg in vargs { + final_args += ' ' + arg + } + cmd := @VEXE + ' ${final_args} -o "${curdir}/bin/${dir}" "./${dir}"' + sw := time.new_stopwatch() + execute_or_panic(cmd) + print_ch <- 'compiling ${dir:-20s}... took ${sw.elapsed().milliseconds()}ms .\n' + }() } + +// Wait for all compilations to finish +for _ in 0 .. dirs_to_compile.len { + _ := <-results_ch +} + +print_ch.close() +compiled = dirs_to_compile.len println('> Compiled: ${compiled:3} tools in ${sw_total.elapsed().milliseconds()}ms. Already compiled and skipped: ${already_compiled} . All folders: ${dirs.len} .') chdir(curdir)! From 3e4ec07e4910279ebd621309615acc31a08e81d4 Mon Sep 17 00:00:00 2001 From: SheatNoisette Date: Sun, 21 Dec 2025 10:06:02 +0100 Subject: [PATCH 3/4] Update readme for parallel compilation --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9082f415..00951622 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ the command input/output consistent across the tools. ## Building Running `make` or `v run build.vsh` will build all the programs in `bin/`. +Use `JOBS=N make` or `v run build.vsh --cpus=N` to compile in parallel. Note: support for access to user account info (via utmp) is limited to POSIX-like platforms. And, so, for Windows, utilities requiring utmp support (uptime, users, who, whoami) are currently From 0699e6f720a3ab47ac41044a4a0bb951c5feba8e Mon Sep 17 00:00:00 2001 From: SheatNoisette Date: Sun, 21 Dec 2025 15:20:47 +0100 Subject: [PATCH 4/4] build.vsh: Formatting --- build.vsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.vsh b/build.vsh index 04f2606d..3112ad46 100755 --- a/build.vsh +++ b/build.vsh @@ -6,7 +6,7 @@ import flag import os struct Config { - jobs int @[short: 'j'; long: cpus] + jobs int @[long: cpus; short: 'j'] } const ignore_dirs = {