Current section

Files

Jump to
erlang_otp_odbc c_src Makefile
Raw

c_src/Makefile

# Makefile for building the odbcserver port program.
# Called from rebar3 hooks.
CURDIR := $(shell pwd)
BASEDIR := $(abspath $(CURDIR)/..)
PRIVDIR := $(BASEDIR)/priv
# Erlang paths
ERL ?= erl
ERTS_INCLUDE_DIR ?= $(shell $(ERL) -noshell -eval "io:format(\"~ts/erts-~ts/include/\", [code:root_dir(), erlang:system_info(version)])." -s init stop)
EI_INCLUDE_DIR ?= $(shell $(ERL) -noshell -eval "io:format(\"~ts\", [code:lib_dir(erl_interface, include)])." -s init stop)
EI_LIB_DIR ?= $(shell $(ERL) -noshell -eval "io:format(\"~ts\", [code:lib_dir(erl_interface, lib)])." -s init stop)
# Platform detection
UNAME_S := $(shell uname -s)
CC ?= cc
CFLAGS ?= -O2 -Wall
LDFLAGS =
# Platform-specific flags
ifeq ($(UNAME_S),Darwin)
TARGET_FLAGS = -DUNIX -DHAVE_STRUCT_SOCKADDR_IN6_SIN6_ADDR
# Try unixODBC first (Homebrew), fall back to iodbc
ODBC_LIB := $(shell pkg-config --libs odbc 2>/dev/null || echo "-lodbc")
ODBC_CFLAGS := $(shell pkg-config --cflags odbc 2>/dev/null)
ifeq ($(ODBC_LIB),-lodbc)
# Check Homebrew paths
HOMEBREW_PREFIX := $(shell brew --prefix 2>/dev/null || echo "/opt/homebrew")
ifneq ($(wildcard $(HOMEBREW_PREFIX)/opt/unixodbc/lib/libodbc.dylib),)
ODBC_LIB = -L$(HOMEBREW_PREFIX)/opt/unixodbc/lib -lodbc
ODBC_CFLAGS = -I$(HOMEBREW_PREFIX)/opt/unixodbc/include
else
ODBC_LIB = -lodbc
endif
endif
else ifeq ($(UNAME_S),Linux)
TARGET_FLAGS = -DUNIX -DHAVE_STRUCT_SOCKADDR_IN6_SIN6_ADDR
ODBC_LIB := $(shell pkg-config --libs odbc 2>/dev/null || echo "-lodbc")
ODBC_CFLAGS := $(shell pkg-config --cflags odbc 2>/dev/null)
else
# Windows / other
TARGET_FLAGS = -DWIN32
ODBC_LIB = -lodbc32
ODBC_CFLAGS =
endif
# Threading
THR_LIBS = -lpthread
THR_DEFS = -D_THREAD_SAFE -D_REENTRANT
INCLUDES = -I. -I$(EI_INCLUDE_DIR) -I$(ERTS_INCLUDE_DIR) $(ODBC_CFLAGS)
ALL_CFLAGS = $(CFLAGS) $(TARGET_FLAGS) $(THR_DEFS) $(INCLUDES)
ALL_LDFLAGS = -L$(EI_LIB_DIR) -lei $(ODBC_LIB) $(THR_LIBS) $(LDFLAGS)
TARGET = $(PRIVDIR)/bin/odbcserver
all: $(TARGET)
$(TARGET): odbcserver.o
@mkdir -p $(PRIVDIR)/bin
$(CC) $< $(ALL_LDFLAGS) -o $@
odbcserver.o: odbcserver.c odbcserver.h
$(CC) $(ALL_CFLAGS) -c -o $@ $<
clean:
rm -f odbcserver.o $(TARGET)
rm -f test_decode_params $(BASEDIR)/test_decode_params
# ---- Test targets ----
TEST_CFLAGS = $(ALL_CFLAGS) -DTEST
TEST_LDFLAGS = -L$(EI_LIB_DIR) -lei $(ODBC_LIB) $(THR_LIBS) $(LDFLAGS)
# Build and run C unit tests (no database needed)
test: test_decode_params
./test_decode_params
test_decode_params: test_decode_params.c odbcserver.c odbcserver.h test_harness.h
$(CC) $(TEST_CFLAGS) -o $@ test_decode_params.c $(TEST_LDFLAGS)
# Build with AddressSanitizer + UndefinedBehaviorSanitizer
sanitize: CFLAGS += -fsanitize=address,undefined -fno-omit-frame-pointer -g
sanitize: LDFLAGS += -fsanitize=address,undefined
sanitize: clean $(TARGET)
# Run C unit tests under ASan/UBSan
test-sanitize: CFLAGS += -fsanitize=address,undefined -fno-omit-frame-pointer -g
test-sanitize: LDFLAGS += -fsanitize=address,undefined
test-sanitize: test
# Run C unit tests under Valgrind (Linux only)
test-valgrind: CFLAGS += -g -O0
test-valgrind: test_decode_params
valgrind --leak-check=full --show-reachable=yes --track-origins=yes \
--error-exitcode=42 --errors-for-leak-kinds=all \
$(if $(wildcard $(BASEDIR)/scripts/valgrind.supp),--suppressions=$(BASEDIR)/scripts/valgrind.supp) \
./test_decode_params
.PHONY: all clean test sanitize test-sanitize test-valgrind