From 578a5973a91371ba0a5e274f0e336496a1f2cc5d Mon Sep 17 00:00:00 2001 From: Lee Yunjin Date: Thu, 22 Oct 2026 22:59:48 +0900 Subject: [PATCH 1/2] feat(build): CWIST_FAT/CWIST_APP_FAT embedded-friendly fat archive - make CWIST_FAT=1 folds every vendored static archive (BoringSSL, lsquic, libttak, cnats, cJSON, uriparser, usrsctp) into libcwist.a via an ar MRI merge (libtool -static on Darwin), so copying the single archive plus include/cwist onto an embedded target is enough to link a server app; only system libraries stay external. A .build-fat stamp re-archives when the toggle flips, without recompiling objects. - CWIST_APP_FAT=1 implies CWIST_FAT=1 and drops the vendored archives from the example apps' link line (APP_LIBS): the app binary pulls everything from libcwist.a. - New fat.yml workflow builds the fat archive, checks vendored members and key symbols are folded in, links and serves the hello example in a scratch dir with only libcwist.a + headers + app source present, and builds an example with CWIST_APP_FAT=1. --- .github/workflows/fat.yml | 82 ++++++++++++++++++++++++++++++++++ Makefile | 94 ++++++++++++++++++++++++++------------- 2 files changed, 145 insertions(+), 31 deletions(-) create mode 100644 .github/workflows/fat.yml diff --git a/.github/workflows/fat.yml b/.github/workflows/fat.yml new file mode 100644 index 000000000..7bc85bfaf --- /dev/null +++ b/.github/workflows/fat.yml @@ -0,0 +1,82 @@ +name: "Fat archive" + +# CWIST_FAT=1 folds the vendored static archives into libcwist.a so an +# embedded target needs only the archive plus the CWIST headers at link +# time; CWIST_APP_FAT=1 links the example apps against that fat archive +# alone. This job builds the fat archive, proves a server app links and +# serves with nothing but libcwist.a copied next to its source, and builds +# an example with CWIST_APP_FAT=1. + +on: + push: + branches: [main, master, dev] + pull_request: + branches: [main, master, dev] + workflow_dispatch: + +permissions: + contents: read + +jobs: + fat: + name: Fat archive build + embedded-style link smoke + if: github.event_name != 'push' || !contains(github.event.head_commit.message, '[skip ci]') + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install build dependencies + run: | + sudo apt-get update + sudo apt-get install -y cmake libcurl4-openssl-dev libnghttp2-dev libbrotli-dev libzstd-dev + + - name: Build the fat archive + run: make CWIST_FAT=1 libcwist.a -j"$(nproc)" + + - name: Verify vendored archives are folded in + run: | + # Members of every vendored archive must be present, not just the + # CWIST objects: the archive alone has to satisfy an app link. + ar t libcwist.a | grep -q '^cJSON\.o$' + ar t libcwist.a | grep -q '^bio_ssl\.cc\.o$' + ar t libcwist.a | grep -q '^lsqpack\.c\.o$' + ar t libcwist.a | grep -q '^UriCommon\.c\.o$' + nm --defined-only libcwist.a | grep -qw 'T SSL_new' + nm --defined-only libcwist.a | grep -qw 'T lsquic_engine_new' + nm --defined-only libcwist.a | grep -qw 'T natsConnection_Connect' + nm --defined-only libcwist.a | grep -qw 'T sqlite3_open' + + - name: Embedded-style link smoke (archive + headers + app source only) + run: | + # Mirror the embedded workflow: copy just libcwist.a, the headers + # and the app source onto the target, link against system libs only. + work=$(mktemp -d) + cp libcwist.a "$work/" + cp -r include "$work/" + cp example/micro/01-hello/main.c "$work/" + cd "$work" + "${CC:-gcc}" -O2 -std=gnu17 -Iinclude -o hello main.c libcwist.a \ + $(pkg-config --libs libcurl libnghttp2 libbrotlienc libbrotlicommon libbrotlidec libzstd) \ + -pthread -ldl -lm -lstdc++ -lz + ./hello & + pid=$! + sleep 2 + test "$(curl -s -m 3 http://127.0.0.1:8080/)" = "Hello, CWIST!" + kill "$pid" + + - name: CWIST_APP_FAT example build + run: | + # The app link must reference libcwist.a and no vendored archive. + out=$(make CWIST_APP_FAT=1 example/micro/01-hello/hello 2>&1 | tail -1) + echo "$out" + echo "$out" | grep -q 'libcwist\.a' + ! echo "$out" | grep -q 'lib/[a-z0-9_/-]*/[^ ]*\.a' + ./example/micro/01-hello/hello & + pid=$! + sleep 2 + test "$(curl -s -m 3 http://127.0.0.1:8080/)" = "Hello, CWIST!" + kill "$pid" diff --git a/Makefile b/Makefile index 515eaf869..39a131dea 100644 --- a/Makefile +++ b/Makefile @@ -335,6 +335,7 @@ SRCS = src/core/sstring/sstring.c \ EMCC ?= emcc EMAR ?= emar NODE ?= node +RANLIB ?= ranlib WASM_BUILD_DIR = .wasm-build WASM_SRCS = src/core/sstring/sstring.c \ src/core/seq/seq.c \ @@ -701,6 +702,10 @@ LIB_NAME = libcwist.a # flags and every object depends on it, so a changed flag forces a rebuild. .build-flags: FORCE @printf '%s' '$(CFLAGS)' | cmp -s - $@ || printf '%s' '$(CFLAGS)' > $@ +# Records the fat-archive toggle so flipping CWIST_FAT re-archives libcwist.a +# without forcing a recompile of unchanged objects. +.build-fat: FORCE + @printf '%s' 'fat=$(CWIST_FAT)' | cmp -s - $@ || printf '%s' 'fat=$(CWIST_FAT)' > $@ FORCE: .PHONY: FORCE $(OBJS): .build-flags @@ -761,6 +766,19 @@ ifeq ($(CWIST_WEBRTC),1) LIBS += $(USRSCTP_LIB) endif +# --- Fat (embedded-friendly) build options ----------------------------------- +# CWIST_FAT=1 folds every vendored static archive into libcwist.a, so copying +# the single archive plus the CWIST headers onto an embedded target is enough +# to link a server app; only system libraries stay external. +# CWIST_APP_FAT=1 builds the example apps against the fat archive alone (the +# vendored archives drop off their link line); it implies CWIST_FAT=1. +ifeq ($(CWIST_APP_FAT),1) +CWIST_FAT = 1 +APP_LIBS = $(filter-out $(EXTERNAL_LIBS),$(LIBS)) +else +APP_LIBS = $(LIBS) +endif + # --- Build Targets --- all: $(LIBTTAK_LIB) $(CJSON_LIB) $(URIPARSER_LIB) $(SQLITE_DIR)/sqlite3.c $(LSQUIC_LIB) $(LIB_NAME) @@ -812,10 +830,24 @@ lib/lsquic/include/lsquic.h: git submodule update --init --recursive $(LSQUIC_DIR); \ fi -$(LIB_NAME): $(EXTERNAL_LIBS) $(OBJS) - @echo "Creating thin static library..." +$(LIB_NAME): .build-fat $(EXTERNAL_LIBS) $(OBJS) +ifeq ($(CWIST_FAT),1) + @echo "Creating fat static library (CWIST objects + vendored archives)..." @rm -f $@ - ar rcs $@ $(OBJS) + ifeq ($(UNAME_S),Darwin) + libtool -static -o $@ $(OBJS) $(EXTERNAL_LIBS) + else + @{ echo "CREATE $@"; \ + for o in $(sort $(OBJS)); do echo "ADDMOD $$o"; done; \ + for l in $(EXTERNAL_LIBS); do echo "ADDLIB $$l"; done; \ + echo "SAVE"; echo "END"; } | $(AR) -M + $(RANLIB) $@ + endif +else + @echo "Creating static library..." + @rm -f $@ + $(AR) rcs $@ $(OBJS) +endif $(LIBTTAK_LIB): @echo "Building libttak..." @@ -1570,37 +1602,37 @@ EXAMPLE_BINS = example/simple-server/simple-server \ examples: $(EXAMPLE_BINS) example/simple-server/simple-server: $(LIB_NAME) example/simple-server/main.c - $(CC) $(CFLAGS) -o $@ example/simple-server/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/simple-server/main.c $(LIB_NAME) $(APP_LIBS) example/http/step-1-hello-world/hello-world: $(LIB_NAME) example/http/step-1-hello-world/main.c - $(CC) $(CFLAGS) -o $@ example/http/step-1-hello-world/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/http/step-1-hello-world/main.c $(LIB_NAME) $(APP_LIBS) example/http/step-2-mux-router/mux-router: $(LIB_NAME) example/http/step-2-mux-router/main.c - $(CC) $(CFLAGS) -o $@ example/http/step-2-mux-router/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/http/step-2-mux-router/main.c $(LIB_NAME) $(APP_LIBS) example/http/step-3-query-params/query-params: $(LIB_NAME) example/http/step-3-query-params/main.c - $(CC) $(CFLAGS) -o $@ example/http/step-3-query-params/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/http/step-3-query-params/main.c $(LIB_NAME) $(APP_LIBS) example/http/step-4-json-api/json-api: $(LIB_NAME) example/http/step-4-json-api/main.c - $(CC) $(CFLAGS) -o $@ example/http/step-4-json-api/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/http/step-4-json-api/main.c $(LIB_NAME) $(APP_LIBS) example/jwt/step-2-http-auth/jwt-auth: $(LIB_NAME) example/jwt/step-2-http-auth/main.c - $(CC) $(CFLAGS) -o $@ example/jwt/step-2-http-auth/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/jwt/step-2-http-auth/main.c $(LIB_NAME) $(APP_LIBS) example/cde-json-viewer/cde-json-viewer: $(LIB_NAME) example/cde-json-viewer/main.c - $(CC) $(CFLAGS) -o $@ example/cde-json-viewer/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/cde-json-viewer/main.c $(LIB_NAME) $(APP_LIBS) example/db/step-1-open-query/open-query: $(LIB_NAME) example/db/step-1-open-query/main.c - $(CC) $(CFLAGS) -o $@ example/db/step-1-open-query/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/db/step-1-open-query/main.c $(LIB_NAME) $(APP_LIBS) example/db/step-2-migrations/migrations: $(LIB_NAME) example/db/step-2-migrations/main.c - $(CC) $(CFLAGS) -o $@ example/db/step-2-migrations/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/db/step-2-migrations/main.c $(LIB_NAME) $(APP_LIBS) example/db/step-4-json-insert/json-insert: $(LIB_NAME) example/db/step-4-json-insert/main.c - $(CC) $(CFLAGS) -o $@ example/db/step-4-json-insert/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/db/step-4-json-insert/main.c $(LIB_NAME) $(APP_LIBS) example/rps-showcase/rps-showcase: $(LIB_NAME) example/rps-showcase/main.c - $(CC) $(CFLAGS) -o $@ example/rps-showcase/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/rps-showcase/main.c $(LIB_NAME) $(APP_LIBS) # Micro examples MICRO_BINS = example/micro/01-hello/hello \ @@ -1648,55 +1680,55 @@ examples-check: $(LIB_NAME) $(EXAMPLE_BINS) $(MICRO_BINS) done example/micro/01-hello/hello: $(LIB_NAME) example/micro/01-hello/main.c - $(CC) $(CFLAGS) -o $@ example/micro/01-hello/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/micro/01-hello/main.c $(LIB_NAME) $(APP_LIBS) example/micro/02-routes/routes: $(LIB_NAME) example/micro/02-routes/main.c - $(CC) $(CFLAGS) -o $@ example/micro/02-routes/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/micro/02-routes/main.c $(LIB_NAME) $(APP_LIBS) example/micro/03-path-params/path-params: $(LIB_NAME) example/micro/03-path-params/main.c - $(CC) $(CFLAGS) -o $@ example/micro/03-path-params/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/micro/03-path-params/main.c $(LIB_NAME) $(APP_LIBS) example/micro/04-query-params/query-params: $(LIB_NAME) example/micro/04-query-params/main.c - $(CC) $(CFLAGS) -o $@ example/micro/04-query-params/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/micro/04-query-params/main.c $(LIB_NAME) $(APP_LIBS) example/micro/05-json/json: $(LIB_NAME) example/micro/05-json/main.c - $(CC) $(CFLAGS) -o $@ example/micro/05-json/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/micro/05-json/main.c $(LIB_NAME) $(APP_LIBS) example/micro/06-orm-insert/orm-insert: $(LIB_NAME) example/micro/06-orm-insert/main.c - $(CC) $(CFLAGS) -o $@ example/micro/06-orm-insert/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/micro/06-orm-insert/main.c $(LIB_NAME) $(APP_LIBS) example/micro/07-orm-query/orm-query: $(LIB_NAME) example/micro/07-orm-query/main.c - $(CC) $(CFLAGS) -o $@ example/micro/07-orm-query/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/micro/07-orm-query/main.c $(LIB_NAME) $(APP_LIBS) example/micro/08-orm-update-delete/orm-update-delete: $(LIB_NAME) example/micro/08-orm-update-delete/main.c - $(CC) $(CFLAGS) -o $@ example/micro/08-orm-update-delete/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/micro/08-orm-update-delete/main.c $(LIB_NAME) $(APP_LIBS) example/micro/09-html-builder/html-builder: $(LIB_NAME) example/micro/09-html-builder/main.c - $(CC) $(CFLAGS) -o $@ example/micro/09-html-builder/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/micro/09-html-builder/main.c $(LIB_NAME) $(APP_LIBS) example/micro/10-static-files/static-files: $(LIB_NAME) example/micro/10-static-files/main.c - $(CC) $(CFLAGS) -o $@ example/micro/10-static-files/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/micro/10-static-files/main.c $(LIB_NAME) $(APP_LIBS) example/micro/11-jwt-auth/jwt-auth: $(LIB_NAME) example/micro/11-jwt-auth/main.c - $(CC) $(CFLAGS) -o $@ example/micro/11-jwt-auth/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/micro/11-jwt-auth/main.c $(LIB_NAME) $(APP_LIBS) example/micro/12-middleware/middleware: $(LIB_NAME) example/micro/12-middleware/main.c - $(CC) $(CFLAGS) -o $@ example/micro/12-middleware/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/micro/12-middleware/main.c $(LIB_NAME) $(APP_LIBS) example/micro/13-nuke-db/nuke-db: $(LIB_NAME) example/micro/13-nuke-db/main.c - $(CC) $(CFLAGS) -o $@ example/micro/13-nuke-db/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/micro/13-nuke-db/main.c $(LIB_NAME) $(APP_LIBS) example/micro/14-websocket/websocket: $(LIB_NAME) example/micro/14-websocket/main.c - $(CC) $(CFLAGS) -o $@ example/micro/14-websocket/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/micro/14-websocket/main.c $(LIB_NAME) $(APP_LIBS) example/micro/15-pqc-tls/pqc-tls: $(LIB_NAME) example/micro/15-pqc-tls/main.c - $(CC) $(CFLAGS) -o $@ example/micro/15-pqc-tls/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/micro/15-pqc-tls/main.c $(LIB_NAME) $(APP_LIBS) example/micro/16-rdbms-auto/rdbms-auto: $(LIB_NAME) example/micro/16-rdbms-auto/main.c - $(CC) $(CFLAGS) -o $@ example/micro/16-rdbms-auto/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/micro/16-rdbms-auto/main.c $(LIB_NAME) $(APP_LIBS) example/micro/17-blog-crud/blog-crud: $(LIB_NAME) example/micro/17-blog-crud/main.c - $(CC) $(CFLAGS) -o $@ example/micro/17-blog-crud/main.c $(LIB_NAME) $(LIBS) + $(CC) $(CFLAGS) -o $@ example/micro/17-blog-crud/main.c $(LIB_NAME) $(APP_LIBS) clean-examples: rm -f $(EXAMPLE_BINS) $(MICRO_BINS) From a1010db15edfda0ddaf43dc09bb56134cd49a8c3 Mon Sep 17 00:00:00 2001 From: Lee Yunjin Date: Thu, 22 Oct 2026 23:32:06 +0900 Subject: [PATCH 2/2] fix(build): select the fat recipe at recipe time and stage fat-dist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - The ifeq-selected recipe was chosen at parse time, so fat-dist's target-specific CWIST_FAT=1 built a plain archive with a fat stamp; the embedded link then missed BoringSSL (SSL_get_error via the system OpenSSL DSO). Branch on $(CWIST_FAT) inside the recipe instead. - New fat-dist target stages dist/cwist-fat/: the fat archive plus the vendored headers the public API references (cjson, openssl, sqlite3, ttak) — the bundle copied to the embedded board. - fat.yml now builds fat-dist and runs the link smoke from the bundle. --- .github/workflows/fat.yml | 29 ++++++++++++----------- Makefile | 49 +++++++++++++++++++++++++-------------- 2 files changed, 47 insertions(+), 31 deletions(-) diff --git a/.github/workflows/fat.yml b/.github/workflows/fat.yml index 7bc85bfaf..0d5a8b4ad 100644 --- a/.github/workflows/fat.yml +++ b/.github/workflows/fat.yml @@ -1,11 +1,12 @@ name: "Fat archive" -# CWIST_FAT=1 folds the vendored static archives into libcwist.a so an -# embedded target needs only the archive plus the CWIST headers at link -# time; CWIST_APP_FAT=1 links the example apps against that fat archive -# alone. This job builds the fat archive, proves a server app links and -# serves with nothing but libcwist.a copied next to its source, and builds -# an example with CWIST_APP_FAT=1. +# CWIST_FAT=1 folds the vendored static archives into libcwist.a and +# `make fat-dist` stages it with the headers the public API pulls in, so an +# embedded target needs only the bundle plus the app source at link time; +# CWIST_APP_FAT=1 links the example apps against that fat archive alone. +# This job builds the bundle, proves a server app links and serves with +# nothing but the bundle copied next to its source, and builds an example +# with CWIST_APP_FAT=1. on: push: @@ -34,8 +35,8 @@ jobs: sudo apt-get update sudo apt-get install -y cmake libcurl4-openssl-dev libnghttp2-dev libbrotli-dev libzstd-dev - - name: Build the fat archive - run: make CWIST_FAT=1 libcwist.a -j"$(nproc)" + - name: Build the fat archive and embedded bundle + run: make fat-dist -j"$(nproc)" - name: Verify vendored archives are folded in run: | @@ -50,16 +51,16 @@ jobs: nm --defined-only libcwist.a | grep -qw 'T natsConnection_Connect' nm --defined-only libcwist.a | grep -qw 'T sqlite3_open' - - name: Embedded-style link smoke (archive + headers + app source only) + - name: Embedded-style link smoke (bundle + app source only) run: | - # Mirror the embedded workflow: copy just libcwist.a, the headers - # and the app source onto the target, link against system libs only. + # Mirror the embedded workflow: copy just the fat-dist bundle and + # the app source onto the target, link against system libs only. work=$(mktemp -d) - cp libcwist.a "$work/" - cp -r include "$work/" + cp -r dist/cwist-fat "$work/bundle" cp example/micro/01-hello/main.c "$work/" cd "$work" - "${CC:-gcc}" -O2 -std=gnu17 -Iinclude -o hello main.c libcwist.a \ + "${CC:-gcc}" -O2 -std=gnu17 -Ibundle/include -o hello main.c \ + bundle/lib/libcwist.a \ $(pkg-config --libs libcurl libnghttp2 libbrotlienc libbrotlicommon libbrotlidec libzstd) \ -pthread -ldl -lm -lstdc++ -lz ./hello & diff --git a/Makefile b/Makefile index 39a131dea..cc8a245d4 100644 --- a/Makefile +++ b/Makefile @@ -707,7 +707,7 @@ LIB_NAME = libcwist.a .build-fat: FORCE @printf '%s' 'fat=$(CWIST_FAT)' | cmp -s - $@ || printf '%s' 'fat=$(CWIST_FAT)' > $@ FORCE: -.PHONY: FORCE +.PHONY: FORCE fat-dist $(OBJS): .build-flags LIBTTAK_DIR = lib/libttak LIBTTAK_LIB = $(LIBTTAK_DIR)/lib/libttak.a @@ -831,23 +831,38 @@ lib/lsquic/include/lsquic.h: fi $(LIB_NAME): .build-fat $(EXTERNAL_LIBS) $(OBJS) -ifeq ($(CWIST_FAT),1) - @echo "Creating fat static library (CWIST objects + vendored archives)..." @rm -f $@ - ifeq ($(UNAME_S),Darwin) - libtool -static -o $@ $(OBJS) $(EXTERNAL_LIBS) - else - @{ echo "CREATE $@"; \ - for o in $(sort $(OBJS)); do echo "ADDMOD $$o"; done; \ - for l in $(EXTERNAL_LIBS); do echo "ADDLIB $$l"; done; \ - echo "SAVE"; echo "END"; } | $(AR) -M - $(RANLIB) $@ - endif -else - @echo "Creating static library..." - @rm -f $@ - $(AR) rcs $@ $(OBJS) -endif + @if [ "$(CWIST_FAT)" = "1" ]; then \ + echo "Creating fat static library (CWIST objects + vendored archives)..."; \ + if [ "$(UNAME_S)" = "Darwin" ]; then \ + libtool -static -o $@ $(sort $(OBJS)) $(EXTERNAL_LIBS); \ + else \ + { echo "CREATE $@"; \ + for o in $(sort $(OBJS)); do echo "ADDMOD $$o"; done; \ + for l in $(EXTERNAL_LIBS); do echo "ADDLIB $$l"; done; \ + echo "SAVE"; echo "END"; } | $(AR) -M && $(RANLIB) $@; \ + fi; \ + else \ + echo "Creating static library..."; \ + $(AR) rcs $@ $(OBJS); \ + fi + +# The embedded bundle: the fat archive plus every header the public API +# pulls in (the public headers reference cjson, openssl, sqlite3 and ttak), +# laid out as the compiler expects. Copy FAT_DIST_DIR onto the target board +# and build apps with -I/include /lib/libcwist.a; only system +# libraries stay external. +FAT_DIST_DIR ?= dist/cwist-fat +fat-dist: CWIST_FAT = 1 +fat-dist: $(LIB_NAME) + rm -rf $(FAT_DIST_DIR) + mkdir -p $(FAT_DIST_DIR)/lib $(FAT_DIST_DIR)/include/cjson + cp $(LIB_NAME) $(FAT_DIST_DIR)/lib/ + cp -R include/cwist $(FAT_DIST_DIR)/include/ + cp $(CJSON_DIR)/cJSON.h $(FAT_DIST_DIR)/include/cjson/ + cp -R $(LIBTTAK_DIR)/include/ttak $(FAT_DIST_DIR)/include/ + cp -R $(BORINGSSL_DIR)/include/openssl $(FAT_DIST_DIR)/include/ + cp $(SQLITE_DIR)/sqlite3.h $(FAT_DIST_DIR)/include/ $(LIBTTAK_LIB): @echo "Building libttak..."