Skip to content

Linking

Lee Yunjin edited this page Oct 7, 2026 · 1 revision

Linking

pkg-config (recommended)

make install ships cwist.pc, so one line covers include paths, library paths and every dependency:

cc -std=c17 -o server main.c $(pkg-config --cflags --libs --static cwist)

Use --static: libcwist.a is a static archive, and Libs.private in cwist.pc carries the libraries a static link needs (-lcurl, -lnghttp2, the compression libraries). Point PKG_CONFIG_PATH at $PREFIX/lib/pkgconfig when CWIST is installed outside the default search path. On macOS with Homebrew, keg-only curl also needs $(brew --prefix curl)/lib/pkgconfig on PKG_CONFIG_PATH.

In a Makefile:

CFLAGS += $(shell pkg-config --cflags cwist)
LDLIBS += $(shell pkg-config --libs --static cwist)

What is in the archive

libcwist.a is a thin archive: it contains only CWIST's own objects. The bundled dependencies are installed as separate archives in $PREFIX/lib/cwist and their headers in $PREFIX/include/cwist/vendor. Keeping them separate avoids duplicate symbols from a merged archive and lets you replace a dependency archive on its own.

Linking by hand

Compile against both include directories and link against both library directories, CWIST first:

cc -std=c17 -I/opt/cwist/include -I/opt/cwist/include/cwist/vendor main.c \
   -L/opt/cwist/lib -L/opt/cwist/lib/cwist \
   -lcwist -lusrsctp -lnats_static -lttak -lcjson -luriparser -llsquic -lssl -lcrypto \
   -lz -lzstd -lbrotlienc -lbrotlicommon -lbrotlidec -lcurl -lnghttp2 \
   -ldl -lpthread -lm -lstdc++

Order matters for static linking: -lcwist before the libraries it uses.

Flag Provides
-lcwist the framework
-llsquic -lssl -lcrypto QUIC/HTTP/3 and TLS (the bundled BoringSSL, not the system OpenSSL)
-lttak libttak: allocator, epoch reclamation, lock-free queues
-lcjson -luriparser JSON and URI parsing
-lnats_static the bundled NATS client
-lusrsctp SCTP for WebRTC DataChannels (absent when built with CWIST_WEBRTC=0)
-lz -lzstd -lbrotlienc -lbrotlicommon -lbrotlidec compression backends
-lcurl -lnghttp2 the libcurl-based HTTP client
-ldl -lpthread -lm -lstdc++ system runtime; -lstdc++ because BoringSSL has C++ objects

Package names: Brotli is libbrotli-dev on Debian/Ubuntu and brotli-devel on Fedora/RHEL; zstd is libzstd-dev / libzstd-devel.

Which headers to include

Include <cwist/app.h> for the application API and the canonical module headers under cwist/core/, cwist/net/ and cwist/sys/ for everything else, for example:

#include <cwist/app.h>                       /* cwist_app, routing, listen */
#include <cwist/sys/app/middleware.h>        /* built-in middleware */
#include <cwist/core/utils/json_builder.h>   /* JSON builder */
#include <cwist/net/http/cookie.h>           /* cookies */
#include <cwist/core/db/pool.h>              /* SQLite pool */

The top-level headers cwist/app.h, cwist/graphql.h, cwist/graphql_ws.h, cwist/redis.h and cwist/sse.h are thin wrappers around the canonical headers and are safe to use.

Several other top-level headers (cwist/http.h, cwist/https.h, cwist/sql.h, cwist/websocket.h, cwist/json_builder.h, cwist/middleware.h, cwist/query.h, cwist/sstring.h, cwist/mux.h, cwist/siphash.h, cwist/session_manager.h, cwist/err/cwist_err.h) are older standalone copies. Some declare structs with layouts that no longer match the library (for example cwist_db and cwist_websocket), and cwist/http.h shares its include guard with cwist/net/http/http.h, so whichever is included first wins. Do not use them in new code. The Zig and Rust bindings translate only the canonical headers for the same reason.

Each module page in this wiki names the header it documents.

Language bindings

Rust and Zig link the same installed libcwist through cwist.pc; see Language Bindings.

Clone this wiki locally