Packages
vix
0.39.0
0.40.0
0.39.0
0.38.0
0.37.0
0.36.0
0.35.0
0.34.0
0.33.1
0.33.0
0.32.0
0.31.1
0.31.0
0.30.0
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.0
0.23.1
0.22.0
0.21.0
0.20.0
0.19.0
0.18.0
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.1
0.15.0
0.14.0
0.13.0
0.12.0
0.11.0
0.10.1
0.10.0
0.9.0
0.8.0
0.7.0
0.6.1
0.6.0
0.5.0
0.4.0
0.3.0
0.2.1
0.2.0
retired
0.1.0
NIF based bindings for libvips
Current section
Files
Jump to
Current section
Files
c_src/Makefile
# Force POSIX-compatible shell
SHELL = /bin/sh
# Build configuration
MIX_APP_PATH ?= ..
PROJECT_ROOT := $(abspath $(CURDIR)/..)
PREFIX = $(MIX_APP_PATH)/priv
VIX = $(PREFIX)/vix.so
# Compilation mode configuration
VIX_COMPILATION_MODE ?= PRECOMPILED_NIF_AND_LIBVIPS
VIX_COMPILATION_MODE := $(shell echo "$(VIX_COMPILATION_MODE)" | tr '[:lower:]' '[:upper:]')
VALID_COMPILATION_MODES := PRECOMPILED_NIF_AND_LIBVIPS PRECOMPILED_LIBVIPS PLATFORM_PROVIDED_LIBVIPS
ifeq ($(filter $(VIX_COMPILATION_MODE),$(VALID_COMPILATION_MODES)),)
$(error Invalid VIX_COMPILATION_MODE '$(VIX_COMPILATION_MODE)'. Valid modes: $(VALID_COMPILATION_MODES))
endif
# Build tools
CC ?= gcc
RM ?= rm -f
MKDIR_P ?= mkdir -p
PKG_CONFIG ?= pkg-config
# Optional custom libvips prefix for PLATFORM_PROVIDED_LIBVIPS mode
ifdef VIX_LIBVIPS_PREFIX
ifneq ($(filter /%,$(VIX_LIBVIPS_PREFIX)),)
VIX_LIBVIPS_PREFIX_ABS := $(VIX_LIBVIPS_PREFIX)
else
VIX_LIBVIPS_PREFIX_ABS := $(abspath $(PROJECT_ROOT)/$(VIX_LIBVIPS_PREFIX))
endif
VIPS_PKG_CONFIG_PATH := $(VIX_LIBVIPS_PREFIX_ABS)/lib/pkgconfig$(if $(PKG_CONFIG_PATH),:$(PKG_CONFIG_PATH))
VIPS_PKG_CONFIG := env PKG_CONFIG_PATH="$(VIPS_PKG_CONFIG_PATH)" $(PKG_CONFIG)
else
VIPS_PKG_CONFIG := $(PKG_CONFIG)
endif
# System detection and platform-specific configuration
UNAME_SYS := $(shell uname -s 2>/dev/null || echo Unknown)
UNAME_ARCH := $(shell uname -m 2>/dev/null || echo Unknown)
# Base compiler flags
BASE_CFLAGS = -O2 -Wall -Werror -Wextra -Wno-unused-parameter -Wmissing-prototypes -std=c11
# Platform-specific flags
ifeq ($(UNAME_SYS), Darwin)
CFLAGS += $(BASE_CFLAGS)
LDFLAGS += -flat_namespace -undefined suppress
else ifeq ($(UNAME_SYS), Linux)
CFLAGS += $(BASE_CFLAGS)
endif
# flags that are common to all platform
CFLAGS += -D_POSIX_C_SOURCE=200809L -fPIC
# Erlang/OTP includes and libraries
CFLAGS += -I "$(ERTS_INCLUDE_DIR)" -I "$(ERL_INTERFACE_INCLUDE_DIR)"
LDLIBS += -L "$(ERL_INTERFACE_LIB_DIR)"
LDFLAGS += -shared
ifeq ($(VIX_COMPILATION_MODE), PLATFORM_PROVIDED_LIBVIPS)
VIPS_CFLAGS := $(shell ${VIPS_PKG_CONFIG} --cflags vips 2>/dev/null)
VIPS_LIBS := $(shell ${VIPS_PKG_CONFIG} --libs vips 2>/dev/null)
VIPS_VERSION := $(shell ${VIPS_PKG_CONFIG} --modversion vips 2>/dev/null)
CFLAGS += $(VIPS_CFLAGS)
LDLIBS += $(VIPS_LIBS)
PKG_CONFIG_CHECK = check-pkg-config
ifdef VIX_LIBVIPS_PREFIX
LDFLAGS += -Wl,-rpath,$(VIX_LIBVIPS_PREFIX_ABS)/lib
endif
else
PKG_CONFIG_CHECK =
PRECOMPILED_LIBVIPS_PATH = $(PREFIX)/precompiled_libvips
ifeq ($(VIX_COMPILATION_MODE), PRECOMPILED_LIBVIPS)
# force fetching libvips if previously configured to use PRECOMPILED_NIF_AND_LIBVIPS
# since the precompiled vix does not bundle `include`
PRECOMPILED_LIBVIPS_PREREQUISITE = $(PRECOMPILED_LIBVIPS_PATH)/include
else
PRECOMPILED_LIBVIPS_PREREQUISITE = $(PRECOMPILED_LIBVIPS_PATH)
endif
CFLAGS += -pthread
CFLAGS += -I "$(PRECOMPILED_LIBVIPS_PATH)/include"
CFLAGS += -I "$(PRECOMPILED_LIBVIPS_PATH)/lib/glib-2.0/include"
CFLAGS += -I "$(PRECOMPILED_LIBVIPS_PATH)/include/glib-2.0"
LDLIBS += -L "$(PRECOMPILED_LIBVIPS_PATH)/lib"
ifeq ($(UNAME_SYS), Darwin)
LDFLAGS += -Wl,-rpath,@loader_path/precompiled_libvips/lib
LDLIBS += $(PRECOMPILED_LIBVIPS_PATH)/lib/libvips-cpp.*.dylib
else ifeq ($(UNAME_SYS), Linux)
LDFLAGS += -Wl,-s -Wl,--disable-new-dtags -Wl,-rpath='$$ORIGIN/precompiled_libvips/lib'
LDLIBS += $(PRECOMPILED_LIBVIPS_PATH)/lib/libvips-cpp.so.*
endif
endif
# Verbosity control
V ?= 0
ifeq ($(V),0)
Q = @
SAY = @echo
else
Q =
SAY = @\#
endif
c_verbose_0 = @echo " CC " $(<F);
c_verbose_1 =
c_verbose = $(c_verbose_$(V))
link_verbose_0 = @echo " LD " $(@F);
link_verbose_1 =
link_verbose = $(link_verbose_$(V))
# Source files discovery
SRC := $(wildcard *.c g_object/*.c)
ifeq ($(SRC),)
$(error No C source files found)
endif
# Object files (placed in source directory to avoid env conflicts)
OBJ := $(SRC:.c=.o)
# Dependency files for better incremental builds
DEP := $(SRC:.c=.d)
# Build configuration stamps to force rebuilds when relevant env changes
COMPILE_CONFIG = $(PREFIX)/compile.config
LINK_CONFIG = $(PREFIX)/link.config
$(COMPILE_CONFIG): FORCE | $(PREFIX)
$(Q){ \
printf '%s\n' \
"CC=$(CC)" \
"VIX_COMPILATION_MODE=$(VIX_COMPILATION_MODE)" \
"VIX_LIBVIPS_PREFIX_ABS=$(VIX_LIBVIPS_PREFIX_ABS)" \
"VIPS_VERSION=$(VIPS_VERSION)" \
"CFLAGS=$(CFLAGS)"; \
} > "$@.tmp"
$(Q)if [ ! -f "$@" ] || ! cmp -s "$@.tmp" "$@"; then \
mv "$@.tmp" "$@"; \
else \
$(RM) "$@.tmp"; \
fi
$(LINK_CONFIG): FORCE | $(PREFIX)
$(Q){ \
printf '%s\n' \
"CC=$(CC)" \
"VIX_COMPILATION_MODE=$(VIX_COMPILATION_MODE)" \
"VIX_LIBVIPS_PREFIX_ABS=$(VIX_LIBVIPS_PREFIX_ABS)" \
"VIPS_VERSION=$(VIPS_VERSION)" \
"LDFLAGS=$(LDFLAGS)" \
"LDLIBS=$(LDLIBS)"; \
} > "$@.tmp"
$(Q)if [ ! -f "$@" ] || ! cmp -s "$@.tmp" "$@"; then \
mv "$@.tmp" "$@"; \
else \
$(RM) "$@.tmp"; \
fi
# Main targets
all: check-env $(PKG_CONFIG_CHECK) $(VIX)
$(SAY) "Build complete: $(VIX)"
install: all
calling_from_make:
$(Q)cd .. && mix compile
# Environment validation
check-env:
@if [ -z "$(ERTS_INCLUDE_DIR)" ]; then \
echo "Error: ERTS_INCLUDE_DIR not set"; \
exit 1; \
fi
@if [ -z "$(ERL_INTERFACE_INCLUDE_DIR)" ]; then \
echo "Error: ERL_INTERFACE_INCLUDE_DIR not set"; \
exit 1; \
fi
@if [ -z "$(ERL_INTERFACE_LIB_DIR)" ]; then \
echo "Error: ERL_INTERFACE_LIB_DIR not set"; \
exit 1; \
fi
check-pkg-config:
@if ! command -v ${PKG_CONFIG} >/dev/null 2>&1; then \
echo "Error: ${PKG_CONFIG} (PKG_CONFIG) not found but required for PLATFORM_PROVIDED_LIBVIPS"; \
exit 1; \
fi
@if ! ${VIPS_PKG_CONFIG} --exists vips; then \
echo "Error: vips not found via pkg-config"; \
if [ -n "$(VIX_LIBVIPS_PREFIX_ABS)" ]; then \
echo "Checked custom libvips prefix: $(VIX_LIBVIPS_PREFIX_ABS)"; \
fi; \
echo "Please install libvips development headers"; \
exit 1; \
fi
@if [ -n "$(VIX_LIBVIPS_PREFIX_ABS)" ]; then \
resolved_prefix=$$(${VIPS_PKG_CONFIG} --variable=prefix vips 2>/dev/null || true); \
if [ -z "$$resolved_prefix" ]; then \
echo "Error: failed to resolve the libvips prefix via pkg-config"; \
exit 1; \
fi; \
if [ "$$resolved_prefix" != "$(VIX_LIBVIPS_PREFIX_ABS)" ]; then \
if [ -d "$$resolved_prefix" ] && [ -d "$(VIX_LIBVIPS_PREFIX_ABS)" ] && [ "$$resolved_prefix" -ef "$(VIX_LIBVIPS_PREFIX_ABS)" ]; then \
:; \
else \
echo "Error: libvips resolved to '$$resolved_prefix' instead of '$(VIX_LIBVIPS_PREFIX_ABS)'"; \
echo "VIX_LIBVIPS_PREFIX must point to the libvips installation that should be used"; \
exit 1; \
fi; \
fi; \
fi
# Create output directory
$(PREFIX):
$(Q)$(MKDIR_P) "$@"
$(OBJ): Makefile $(COMPILE_CONFIG) $(PRECOMPILED_LIBVIPS_PREREQUISITE)
# Dependency generation
%.d: %.c
$(Q)$(CC) $(CFLAGS) -MM -MT $(@:.d=.o) $< > $@
# Include dependency files if they exist
-include $(DEP)
# Object file compilation with dependency tracking
%.o: %.c
$(c_verbose)$(CC) -c $(CFLAGS) -MMD -MP -o $@ $<
# Final linking
$(VIX): $(PREFIX) $(LINK_CONFIG) $(OBJ)
$(link_verbose)$(CC) $(OBJ) -o $@ $(LDFLAGS) $(LDLIBS)
# Precompiled libvips setup
$(PRECOMPILED_LIBVIPS_PREREQUISITE):
$(SAY) "Setting up precompiled libvips..."
$(Q) elixir ../build_scripts/precompiler.exs "$(PREFIX)"
# Clean targets
clean:
$(SAY) "Cleaning build artifacts..."
$(Q)$(RM) $(VIX) $(OBJ) $(DEP) $(COMPILE_CONFIG) $(LINK_CONFIG)
clean_precompiled_libvips: clean
$(SAY) "Cleaning precompiled libvips..."
$(Q)$(RM) "$(PREFIX)"/libvips-*.tar.gz
$(Q)$(RM) -r "$(PREFIX)/precompiled_libvips"
# Help target
help:
@echo "Available targets:"
@echo " all - Build the NIF library"
@echo " clean - Clean build artifacts"
@echo " clean_precompiled_libvips - Clean precompiled libvips"
@echo " check-env - Validate build environment"
@echo " help - Show this help"
@echo ""
@echo "Build configuration:"
@echo " VIX_COMPILATION_MODE: $(VIX_COMPILATION_MODE)"
@echo " VIX_LIBVIPS_PREFIX: $(VIX_LIBVIPS_PREFIX_ABS)"
@echo " System: $(UNAME_SYS) $(UNAME_ARCH)"
@echo " CC: $(CC)"
@echo ""
@echo "Set V=1 for verbose output"
# Debug target
debug:
@echo "=== Build Configuration ==="
@echo "VIX_COMPILATION_MODE: $(VIX_COMPILATION_MODE)"
@echo "UNAME_SYS: $(UNAME_SYS)"
@echo "UNAME_ARCH: $(UNAME_ARCH)"
@echo "CC: $(CC)"
@echo "CFLAGS: $(CFLAGS)"
@echo "LDFLAGS: $(LDFLAGS)"
@echo "LDLIBS: $(LDLIBS)"
@echo "PKG_CONFIG: $(PKG_CONFIG)"
@echo "VIPS_PKG_CONFIG: $(VIPS_PKG_CONFIG)"
@echo "VIPS_VERSION: $(VIPS_VERSION)"
@echo "SRC: $(SRC)"
@echo "OBJ: $(OBJ)"
@echo "PREFIX: $(PREFIX)"
@echo "VIX: $(VIX)"
FORCE:
.PHONY: FORCE all clean clean_precompiled_libvips calling_from_make install check-env check-pkg-config help debug