Build gtkwave's vcd2fst / fst2vcd alone (no GTK, no autotools) and stream VCD into it
If you need FST files on a host with no GTK and no admin rights, you don't need to build all of gtkwave. In gtkwave 3.3.116 (the gtkwave3/ tree of the release tarball), vcd2fst needs only these files: - src/helpers/vcd2fst.c - src/helpers/fst/{fstapi.c,fastlz.c,lz4.c} and their headers - contrib/rtlbrowse/jrb.{c,h} - wave_locale.h (it sits at the top of gtkwave3/, not in src/)
Write a small config.h yourself:
#define HAVE_ALLOCA_H 1
#define HAVE_FSEEKO 1
#define HAVE_GETOPT_H 1
#define HAVE_LIBPTHREAD 1
#define HAVE_REALPATH 1
#define HAVE_INTTYPES_H 1
#define PACKAGE_BUGREPORT "..."
#define PACKAGE_VERSION "3.3.116"
#define VERSION "3.3.116"Then build. Keep the tree layout, because vcd2fst.c includes "fst/fstapi.h" and "../../contrib/rtlbrowse/jrb.h":
CF='-O2 -I. -Isrc/helpers -DHAVE_CONFIG_H -include config.h'
gcc $CF -o vcd2fst src/helpers/vcd2fst.c src/helpers/fst/{fstapi,fastlz,lz4}.c contrib/rtlbrowse/jrb.c -lz -lpthread
gcc $CF -o fst2vcd src/helpers/fst2vcd.c src/helpers/fst/{fstapi,fastlz,lz4}.c -lz -lpthreadJudy is optional (_WAVE_HAVE_JUDY). zlib headers are the only dependency. It built clean with GCC 11 on a RHEL-family host.
Streaming: vcd2fst -v - -f out.fst reads the VCD from stdin, so you can pipe any VCD producer into it (producer -o /dev/stdout | vcd2fst -v - -f out.fst) and never write the VCD to disk.
Measured on one 145 MB source dump: the pipe took 6.7 min wall. vcd2fst used only 0.14 GB RSS and about 130 CPU-s; the VCD producer was the bottleneck. The FST came out at about the same size as the source. Check the result with fst2vcd (look for the $timescale and #time lines).