Packages
localize_mf2_treesitter
0.1.0
Elixir bindings to the tree-sitter-mf2 grammar. Incremental, error-recovering CST parser for ICU MessageFormat 2 (MF2) messages suitable for editor tooling and LSP use.
Current section
Files
Jump to
Current section
Files
c_src/Makefile
# Makefile for the Localize.Mf2.TreeSitter NIF.
#
# Three translation units link into one shared library:
#
# * c_src/runtime/src/lib.c — tree-sitter runtime (single-TU amalgamation).
# * c_src/grammar/parser.c — tree-sitter-mf2 generated parser.
# * c_src/ts_nif.c — erl_nif glue code.
#
# The runtime and grammar have different internal layouts, so each
# compilation step has its own -I path. They never share headers at
# compile time and are linked together into priv/localize_mf2_treesitter_nif.so.
ERL ?= erl
BASEDIR = $(CURDIR)
PRIVDIR = ./priv
NIF_DIR = c_src
NIF_ENV = c_src/env.mk
RUNTIME_DIR = $(NIF_DIR)/runtime
GRAMMAR_DIR = $(NIF_DIR)/grammar
RUNTIME_OBJ = $(RUNTIME_DIR)/lib.o
GRAMMAR_OBJ = $(GRAMMAR_DIR)/parser.o
NIF_OBJ = $(NIF_DIR)/ts_nif.o
ALL_OBJS = $(RUNTIME_OBJ) $(GRAMMAR_OBJ) $(NIF_OBJ)
NIF_SO = $(PRIVDIR)/localize_mf2_treesitter_nif.so
UNAME_SYS := $(shell uname -s)
UNAME_ARCH := $(shell uname -m)
CC ?= cc
# Optimisation + ISO C — tree-sitter requires C11.
CFLAGS_BASE = -O3 -std=c11 -Wall -Wextra -fPIC
ifeq ($(UNAME_SYS), Darwin)
LDFLAGS = -arch $(UNAME_ARCH) -flat_namespace -undefined dynamic_lookup -shared
CFLAGS_BASE += -arch $(UNAME_ARCH)
else
LDFLAGS = -shared
endif
# Erlang NIF headers — resolved by the env.mk target below.
ERL_CFLAGS = -I$(ERTS_INCLUDE_DIR) -I$(ERL_INTERFACE_INCLUDE_DIR)
# Include paths, per translation unit.
RUNTIME_CFLAGS = -I$(RUNTIME_DIR)/include -I$(RUNTIME_DIR)/src
# tree-sitter's generated parser.c uses a single START_LEXER() macro
# that declares `int32_t lookahead` and a `next_state:` label. Both
# are by-design generic and some generated code paths legitimately
# don't consume them, so GCC/Clang emit `-Wunused-but-set-variable`
# and `-Wunused-label`. These are inherent to the generator output,
# not a sign of a bug in our build — suppress them for this one TU
# rather than loosening warnings globally.
GRAMMAR_CFLAGS = -I$(GRAMMAR_DIR) -Wno-unused-but-set-variable -Wno-unused-label
NIF_CFLAGS = -I$(RUNTIME_DIR)/include $(ERL_CFLAGS)
all: $(NIF_ENV) $(NIF_SO)
clean:
@rm -f $(ALL_OBJS) $(NIF_SO)
distclean: clean
@rm -f $(NIF_ENV)
$(NIF_SO): $(ALL_OBJS)
@mkdir -p $(PRIVDIR)
$(CC) $(ALL_OBJS) $(LDFLAGS) -o $(NIF_SO)
$(RUNTIME_OBJ): $(RUNTIME_DIR)/src/lib.c
$(CC) -c $(CFLAGS_BASE) $(RUNTIME_CFLAGS) $< -o $@
$(GRAMMAR_OBJ): $(GRAMMAR_DIR)/parser.c
$(CC) -c $(CFLAGS_BASE) $(GRAMMAR_CFLAGS) $< -o $@
$(NIF_OBJ): $(NIF_DIR)/ts_nif.c
$(CC) -c $(CFLAGS_BASE) $(NIF_CFLAGS) $< -o $@
$(NIF_ENV):
@$(ERL) -eval "file:write_file(\"$(NIF_ENV)\", \
io_lib:format( \
\"ERTS_INCLUDE_DIR ?= ~s/erts-~s/include/~n\" \
\"ERL_INTERFACE_INCLUDE_DIR ?= ~s~n\" \
\"ERL_INTERFACE_LIB_DIR ?= ~s~n\", \
[code:root_dir(), erlang:system_info(version), \
code:lib_dir(erl_interface, include), \
code:lib_dir(erl_interface, lib)])), \
halt()."
-include $(NIF_ENV)