about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2025-05-01 16:08:55 +0200
committerbptato <nincsnevem662@gmail.com>2025-05-01 16:08:55 +0200
commit25cb585ed6ecfc7f4b2a6cdb2e2b52258ddb9144 (patch)
treeabc46cb501962443a5a07d271b918266584a0b9b
parent7da7f8e293b27eda94655574df7d2444f6e5fb3b (diff)
downloadchawan-25cb585ed6ecfc7f4b2a6cdb2e2b52258ddb9144.tar.gz
Improve static builds
Now we generate a single "ssl" binary for CGI scripts that need OpenSSL
to reduce the output size.
-rw-r--r--Makefile54
-rw-r--r--adapter/protocol/gemini.nim5
-rw-r--r--adapter/protocol/http.nim9
-rw-r--r--adapter/protocol/sftp.nim5
-rw-r--r--adapter/protocol/ssl.nim16
5 files changed, 61 insertions, 28 deletions
diff --git a/Makefile b/Makefile
index 3852faf5..12ba019c 100644
--- a/Makefile
+++ b/Makefile
@@ -53,9 +53,15 @@ else ifeq ($(TARGET),release1)
 FLAGS += -d:release --debugger:native
 endif
 
+protocols = file ftp gopher finger man spartan chabookmark \
+	stbi jebp sixel canvas resize nanosvg http gemini sftp
+converters = gopher2html md2html ansi2html gmi2html dirlist2html uri2html img2html
+tools = urlenc nc
+
 ifeq ($(STATIC_LINK),1)
 FLAGS += -d:staticLink=$(STATIC_LINK)
 LDFLAGS += -static
+protocols += ssl
 endif
 
 ifneq ($(CFLAGS),)
@@ -67,20 +73,14 @@ endif
 
 export CC CFLAGS LDFLAGS
 
+binaries = $(OUTDIR_BIN)/cha $(OUTDIR_BIN)/mancha
+binaries += $(foreach bin,$(protocols),$(OUTDIR_CGI_BIN)/$(bin))
+binaries += $(foreach bin,$(converters),$(OUTDIR_LIBEXEC)/$(bin))
+binaries += $(foreach bin,$(tools),$(OUTDIR_LIBEXEC)/$(bin))
+binaries += $(OUTDIR_LIBEXEC)/urldec
+
 .PHONY: all
-all: $(OUTDIR_BIN)/cha $(OUTDIR_BIN)/mancha $(OUTDIR_CGI_BIN)/http \
-	$(OUTDIR_CGI_BIN)/gemini $(OUTDIR_LIBEXEC)/gmi2html \
-	$(OUTDIR_CGI_BIN)/gopher $(OUTDIR_LIBEXEC)/gopher2html \
-	$(OUTDIR_CGI_BIN)/finger \
-	$(OUTDIR_CGI_BIN)/file $(OUTDIR_CGI_BIN)/ftp $(OUTDIR_CGI_BIN)/sftp \
-	$(OUTDIR_LIBEXEC)/dirlist2html $(OUTDIR_LIBEXEC)/uri2html \
-	$(OUTDIR_LIBEXEC)/img2html \
-	$(OUTDIR_CGI_BIN)/man $(OUTDIR_CGI_BIN)/spartan \
-	$(OUTDIR_CGI_BIN)/stbi $(OUTDIR_CGI_BIN)/jebp $(OUTDIR_CGI_BIN)/canvas \
-	$(OUTDIR_CGI_BIN)/nanosvg $(OUTDIR_CGI_BIN)/sixel $(OUTDIR_CGI_BIN)/resize \
-	$(OUTDIR_CGI_BIN)/chabookmark \
-	$(OUTDIR_LIBEXEC)/urldec $(OUTDIR_LIBEXEC)/urlenc $(OUTDIR_LIBEXEC)/nc \
-	$(OUTDIR_LIBEXEC)/md2html $(OUTDIR_LIBEXEC)/ansi2html
+all: $(binaries)
 	ln -sf "$(OUTDIR)/$(TARGET)/bin/cha" cha
 
 ifeq ($(shell uname), Linux)
@@ -126,13 +126,15 @@ dynstream = src/io/dynstream.nim
 lcgi = $(dynstream) $(twtstr) $(sandbox) adapter/protocol/lcgi.nim
 lcgi_ssl = $(lcgi) adapter/protocol/lcgi_ssl.nim
 sandbox = src/utils/sandbox.nim $(chaseccomp)
+tinfl = adapter/protocol/tinfl.h
 
 $(OUTDIR_CGI_BIN)/man: $(twtstr)
-$(OUTDIR_CGI_BIN)/http: $(sandbox) $(lcgi_ssl) adapter/protocol/tinfl.h
+$(OUTDIR_CGI_BIN)/http: $(sandbox) $(lcgi_ssl) $(tinfl)
 $(OUTDIR_CGI_BIN)/file: $(twtstr)
 $(OUTDIR_CGI_BIN)/ftp: $(lcgi)
 $(OUTDIR_CGI_BIN)/sftp: $(lcgi) $(twtstr)
 $(OUTDIR_CGI_BIN)/gemini: $(lcgi_ssl)
+$(OUTDIR_CGI_BIN)/ssl: $(lcgi_ssl) $(sandbox) $(tinfl)
 $(OUTDIR_CGI_BIN)/stbi: adapter/img/stbi.nim adapter/img/stb_image.h \
 	adapter/img/stb_image_write.h $(sandbox) $(dynstream)
 $(OUTDIR_CGI_BIN)/jebp: adapter/img/jebp.h $(sandbox)
@@ -169,6 +171,15 @@ $(OUTDIR_CGI_BIN)/%: adapter/img/%.nim
 	$(NIMC) $(FLAGS) --nimcache:"$(OBJDIR)/$(TARGET)/$(subst $(OUTDIR_CGI_BIN)/,,$@)" \
                 -d:disableSandbox=$(DANGER_DISABLE_SANDBOX) -o:"$@" $<
 
+ifeq ($(STATIC_LINK),1)
+$(OUTDIR_CGI_BIN)/http: $(OUTDIR_CGI_BIN)/ssl
+	(cd "$(OUTDIR_CGI_BIN)" && ln -sf ssl http)
+$(OUTDIR_CGI_BIN)/gemini: $(OUTDIR_CGI_BIN)/ssl
+	(cd "$(OUTDIR_CGI_BIN)" && ln -sf ssl gemini)
+$(OUTDIR_CGI_BIN)/sftp: $(OUTDIR_CGI_BIN)/ssl
+	(cd "$(OUTDIR_CGI_BIN)" && ln -sf ssl sftp)
+endif
+
 $(OUTDIR_LIBEXEC)/%: adapter/format/%.nim
 	@mkdir -p "$(OUTDIR_LIBEXEC)"
 	$(NIMC) $(FLAGS) --nimcache:"$(OBJDIR)/$(TARGET)/$(subst $(OUTDIR_LIBEXEC)/,,$@)" \
@@ -211,11 +222,6 @@ manpages = $(manpages1) $(manpages5) $(manpages7)
 .PHONY: manpage
 manpage: $(manpages:%=doc/%)
 
-protocols = http file ftp sftp gopher gemini finger man spartan stbi \
-	jebp sixel canvas resize chabookmark nanosvg
-converters = gopher2html md2html ansi2html gmi2html dirlist2html uri2html img2html
-tools = urlenc nc
-
 .PHONY: install
 install:
 	mkdir -p "$(DESTDIR)$(PREFIX)/bin"
@@ -244,16 +250,24 @@ uninstall:
 	rm -f "$(DESTDIR)$(PREFIX)/bin/mancha"
 # intentionally not quoted
 	for f in $(protocols); do rm -f $(LIBEXECDIR_CHAWAN)/cgi-bin/$$f; done
-# notes:
+# We only want to uninstall binaries that the main distribution
+# includes or has ever included, but not those that the user might have
+# added.  However, some of these cannot be directly derived from our
+# variables:
 # * png has been removed in favor of stbi
 # * data, about have been moved back into the main binary
 # * gmifetch has been replaced by gemini
 # * cha-finger has been renamed to finger
+# * ssl is an alias for http, gemini, sftp in static builds
 	rm -f $(LIBEXECDIR_CHAWAN)/cgi-bin/about
 	rm -f $(LIBEXECDIR_CHAWAN)/cgi-bin/cha-finger
 	rm -f $(LIBEXECDIR_CHAWAN)/cgi-bin/data
 	rm -f $(LIBEXECDIR_CHAWAN)/cgi-bin/gmifetch
 	rm -f $(LIBEXECDIR_CHAWAN)/cgi-bin/png
+	rm -f $(LIBEXECDIR_CHAWAN)/cgi-bin/http
+	rm -f $(LIBEXECDIR_CHAWAN)/cgi-bin/gemini
+	rm -f $(LIBEXECDIR_CHAWAN)/cgi-bin/sftp
+	rm -f $(LIBEXECDIR_CHAWAN)/cgi-bin/ssl
 	rmdir $(LIBEXECDIR_CHAWAN)/cgi-bin || true
 	for f in $(converters) $(tools); do rm -f $(LIBEXECDIR_CHAWAN)/$$f; done
 # urldec is just a symlink to urlenc
diff --git a/adapter/protocol/gemini.nim b/adapter/protocol/gemini.nim
index 2d2d57d8..77364b6f 100644
--- a/adapter/protocol/gemini.nim
+++ b/adapter/protocol/gemini.nim
@@ -257,7 +257,7 @@ proc readResponse(os: PosixStream; ssl: ptr SSL; reqBuf: string) =
   else:
     os.die("InvalidResponse", "Wrong status code")
 
-proc main() =
+proc main*() =
   let os = newPosixStream(STDOUT_FILENO)
   let host = getEnv("MAPPED_URI_HOST")
   var (knownHosts, knownHostsPath) = os.openKnownHosts()
@@ -344,4 +344,5 @@ Update it?
 """)
   closeSSLSocket(ssl)
 
-main()
+when not defined(staticLink):
+  main()
diff --git a/adapter/protocol/http.nim b/adapter/protocol/http.nim
index 655af7a5..3646017e 100644
--- a/adapter/protocol/http.nim
+++ b/adapter/protocol/http.nim
@@ -67,8 +67,8 @@ proc tinfl_decompress(r: var tinfl_decompressor; pIn_buf_next: ptr uint8;
 const InputBufferSize = 16384
 
 # libbrotli bindings
-const libbrotlidec = staticExec("pkg-config --libs libbrotlidec")
-const libbrotlidecCflags = staticExec("pkg-config --cflags libbrotlidec")
+const libbrotlidec = staticExec("pkg-config --libs libbrotlidec libbrotlicommon")
+const libbrotlidecCflags = staticExec("pkg-config --cflags libbrotlidec libbrotlicommon")
 
 {.passl: libbrotlidec.}
 {.passc: libbrotlidecCflags.}
@@ -419,7 +419,7 @@ proc checkCert(os: PosixStream; ssl: ptr SSL) =
     let s = X509_verify_cert_error_string(res)
     os.die("InvalidResponse", $s)
 
-proc main() =
+proc main*() =
   let secure = getEnv("MAPPED_URI_SCHEME") == "https"
   let username = getEnv("MAPPED_URI_USERNAME")
   let password = getEnv("MAPPED_URI_PASSWORD")
@@ -473,4 +473,5 @@ proc main() =
         m += k
   op.ps.sclose()
 
-main()
+when not defined(staticLink):
+  main()
diff --git a/adapter/protocol/sftp.nim b/adapter/protocol/sftp.nim
index e5dc7897..ae0f6216 100644
--- a/adapter/protocol/sftp.nim
+++ b/adapter/protocol/sftp.nim
@@ -385,7 +385,7 @@ please remove this host from """ & hostsPath & ".")
     quit(1)
   hosts.libssh2_knownhost_free()
 
-proc main() =
+proc main*() =
   let os = newPosixStream(STDOUT_FILENO)
   if getEnv("REQUEST_METHOD") != "GET":
     os.die("InvalidMethod")
@@ -418,4 +418,5 @@ proc main() =
   discard session.libssh2_session_free()
   libssh2_exit()
 
-main()
+when not defined(staticLink):
+  main()
diff --git a/adapter/protocol/ssl.nim b/adapter/protocol/ssl.nim
new file mode 100644
index 00000000..253c2cdf
--- /dev/null
+++ b/adapter/protocol/ssl.nim
@@ -0,0 +1,16 @@
+import std/envvars
+
+import gemini
+import http
+import sftp
+
+proc main() =
+  let scheme = getEnv("MAPPED_URI_SCHEME")
+  if scheme == "gemini":
+    gemini.main()
+  elif scheme == "sftp":
+    sftp.main()
+  else:
+    http.main()
+
+main()