CC = cc CXX = c++ CFLAGS = -march=native -O2 -std=c11 -Wall -Wextra CXXFLAGS = -march=native -O2 -O2 -Wall -Wextra INCLUDES = -I. -Ideps/include LLAMA_TAG = b10107 LLAMA_URL = https://github.com/ggml-org/llama.cpp/archive/refs/tags/$(LLAMA_TAG).tar.gz LLAMA_TAR = deps/llama-$(LLAMA_TAG).tar.gz LLAMA_SRC_DIR = deps/llama.cpp-src LLAMA_BUILD = $(LLAMA_SRC_DIR)/build STATIC_LIBS = deps/lib/libllama.a \ deps/lib/libggml.a \ deps/lib/libggml-cpu.a \ # System flags required for static linking llama on OpenBSD SYS_LIBS = -static -pthread -lm -lc++ -lc++abi TARGET = lexd SRC = llm.c main.c OBJS = $(SRC:.c=.o) # Standard tools and target directory BINDIR = /usr/local/bin RCDIR = /etc/rc.d VARDIR = /var/$(TARGET) INSTALL = install INSTALL_PROGRAM = $(INSTALL) -m 755 INSTALL_SCRIPT = $(INSTALL) -m 555 MKDIR_P = mkdir -p # Service user configuration SERVICE_USER = _lexd SERVICE_GROUP = _lexd .PHONY: all clean distclean all: $(TARGET) # Explicit link order: libllama -> libggml-cpu -> libggml -> libggml-base $(TARGET): deps/lib/libllama.a $(OBJS) $(CXX) $(CXXFLAGS) $(OBJS) \ -Wl,--start-group \ deps/lib/libllama.a \ deps/lib/libggml-cpu.a \ deps/lib/libggml.a \ deps/lib/libggml-base.a \ -Wl,--end-group \ $(SYS_LIBS) -o $@ # BSD suffix rule: compiles any .c file into .o .c.o: $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ # Rebuild objects if the shared header changes $(OBJS): llm.h # Download llama source and build statically deps/lib/libllama.a deps/lib/libggml.a deps/lib/libggml-cpu.a: @mkdir -p deps/lib deps/include @echo "===> Downloading llama.cpp $(LLAMA_TAG) source..." ftp -o $(LLAMA_TAR) $(LLAMA_URL) @echo "===> Extracting source archive..." tar -xzf $(LLAMA_TAR) -C deps rm -rf $(LLAMA_SRC_DIR) mv deps/llama.cpp-$(LLAMA_TAG) $(LLAMA_SRC_DIR) rm -f $(LLAMA_TAR) @echo "===> Compiling llama static archives..." cmake -S $(LLAMA_SRC_DIR) -B $(LLAMA_BUILD) \ -DCMAKE_BUILD_TYPE=Release \ -DBUILD_SHARED_LIBS=OFF \ -DGGML_OPENMP=OFF \ -DGGML_VULKAN=OFF \ -DLLAMA_BUILD_APP=OFF \ -DLLAMA_BUILD_COMMON=OFF \ -DLLAMA_BUILD_TESTS=OFF \ -DLLAMA_BUILD_UI=OFF \ -DLLAMA_BUILD_EXAMPLES=OFF \ -DLLAMA_BUILD_SERVER=OFF \ -DLLAMA_BUILD_TOOLS=OFF cmake --build $(LLAMA_BUILD) --config Release -j$$(sysctl -n hw.ncpu) @echo "===> Installing .a files and headers into deps/..." find $(LLAMA_BUILD) -type f -name "*.a" -exec cp {} deps/lib/ \; cp -R $(LLAMA_SRC_DIR)/include/* deps/include/ cp -R $(LLAMA_SRC_DIR)/ggml/include/* deps/include/ @echo "===> Cleaning up build directory..." rm -rf $(LLAMA_SRC_DIR) install-user: @if ! id -u $(SERVICE_USER) >/dev/null 2>&1; then \ echo "===> Creating service user..."; \ groupadd $(SERVICE_GROUP) 2>/dev/null || true; \ useradd -g $(SERVICE_GROUP) -s /sbin/nologin -m -c "lexd daemon user" $(SERVICE_USER); \ fi install: $(TARGET) install-user @$(MKDIR_P) $(BINDIR) @echo "===> Installing executable to $(BINDIR)/$(TARGET)..." @$(INSTALL_PROGRAM) $(TARGET) $(BINDIR)/$(TARGET) @echo "===> Installing RC script to $(DESTDIR)$(RCDIR)/$(TARGET)..." @$(MKDIR_P) $(RCDIR) @$(INSTALL_SCRIPT) $(TARGET).rc $(RCDIR)/$(TARGET) @echo "===> Creating data directory $(VARDIR)..." @$(MKDIR_P) $(VARDIR) @chown $(SERVICE_USER):$(SERVICE_GROUP) $(VARDIR) @chmod 750 $(VARDIR) @echo "===> Installation complete." uninstall: @echo "===> Stopping service..." @-rcctl stop $(TARGET) 2>/dev/null || true @rm -f $(BINDIR)/$(TARGET) @rm -f $(RCDIR)/$(TARGET) @echo "Uninstall complete." @echo "Note: The data directory and service accounts were preserved." @echo "To remove all remaining data, run:" @echo " # rm -rf $(VARDIR)" @echo " # userdel -r $(SERVICE_USER)" @echo " # groupdel $(SERVICE_GROUP)" clean: rm -f $(TARGET) $(OBJS) distclean: clean rm -rf deps