CXX ?= g++
DEEPSTREAM_ROOT ?= /opt/nvidia/deepstream/deepstream
BUILD_DIR ?= build
BASE_IMAGE_DIGEST ?= unspecified
DEEPSTREAM_VERSION ?= 9.1
CUDA_ROOT ?= /usr/local/cuda
PREPROCESS_ROOT := $(DEEPSTREAM_ROOT)/sources/gst-plugins/gst-nvdspreprocess
PREPROCESS_TARGET := $(BUILD_DIR)/libcontextra_medium_preprocess.so

LIB_NAME := libcontextra_nvinferserver_rfdetr.so
LIB_TARGET := $(BUILD_DIR)/$(LIB_NAME)
PROCESSOR_OBJECT := $(BUILD_DIR)/processor.o
CONTRACT_TEST := $(BUILD_DIR)/contract_test
DECODE_TEST := $(BUILD_DIR)/decode_test
BUILD_ID_HEADER := $(BUILD_DIR)/build_identity.hpp
SOURCE_SHA256 := $(shell cat processor.cpp tensor_contract.hpp detection_decode.hpp pose_decode.hpp pose_metadata.hpp frame_dimensions.hpp frame_completion.hpp medium_preprocess.cu crowd_contract.hpp crowd_decode.hpp Makefile | sha256sum | cut -d' ' -f1)

CPPFLAGS := \
	-isystem $(DEEPSTREAM_ROOT)/sources/includes \
	-isystem $(DEEPSTREAM_ROOT)/sources/includes/nvdsinferserver \
	-I$(BUILD_DIR) \
	$(shell pkg-config --cflags glib-2.0)
CXXFLAGS := -std=c++17 -O2 -Wall -Wextra -Werror -fPIC -fvisibility=hidden
LDFLAGS := -shared -Wl,--no-undefined -Wl,-z,defs -Wl,-soname,$(LIB_NAME) \
	-Wl,-rpath,$(DEEPSTREAM_ROOT)/lib
LDLIBS := -Wl,--no-as-needed -L$(DEEPSTREAM_ROOT)/lib -lnvds_meta \
	$(shell pkg-config --libs glib-2.0) -Wl,--as-needed

.PHONY: all check clean FORCE

all: $(LIB_TARGET) $(PREPROCESS_TARGET) $(BUILD_DIR)/libcontextra_crowd_preprocess.so

$(BUILD_DIR)/libcontextra_crowd_preprocess.so: medium_preprocess.cu Makefile | $(BUILD_DIR)
	$(CUDA_ROOT)/bin/nvcc -std=c++14 -O2 --fmad=false -shared -Xcompiler -fPIC -DCONTEXTRA_RESOLUTION=512 \
		-I$(PREPROCESS_ROOT)/include -I$(DEEPSTREAM_ROOT)/sources/includes \
		$(shell pkg-config --cflags-only-I gstreamer-1.0) $< \
		-L$(DEEPSTREAM_ROOT)/lib -lnvbufsurftransform -o $@

$(PREPROCESS_TARGET): medium_preprocess.cu Makefile | $(BUILD_DIR)
	$(CUDA_ROOT)/bin/nvcc -std=c++14 -O2 --fmad=false -shared -Xcompiler -fPIC \
		-I$(PREPROCESS_ROOT)/include -I$(DEEPSTREAM_ROOT)/sources/includes \
		$(shell pkg-config --cflags-only-I gstreamer-1.0) $< \
		-L$(DEEPSTREAM_ROOT)/lib -lnvbufsurftransform -o $@

check: $(CONTRACT_TEST) $(DECODE_TEST)
	$(CONTRACT_TEST)
	$(DECODE_TEST)

$(BUILD_DIR):
	mkdir -p $@

$(BUILD_ID_HEADER): FORCE | $(BUILD_DIR)
	printf '%s\n' \
		'#pragma once' \
		'#define CONTEXTRA_ADAPTER_SOURCE_SHA256 "$(SOURCE_SHA256)"' \
		'#define CONTEXTRA_ADAPTER_BASE_DIGEST "$(BASE_IMAGE_DIGEST)"' \
		'#define CONTEXTRA_ADAPTER_DEEPSTREAM_VERSION "$(DEEPSTREAM_VERSION)"' \
		> $@

$(PROCESSOR_OBJECT): processor.cpp tensor_contract.hpp detection_decode.hpp pose_decode.hpp pose_metadata.hpp frame_dimensions.hpp frame_completion.hpp $(BUILD_ID_HEADER) | $(BUILD_DIR)
	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c processor.cpp -o $@

$(LIB_TARGET): $(PROCESSOR_OBJECT) Makefile
	$(CXX) $(LDFLAGS) $(PROCESSOR_OBJECT) $(LDLIBS) -o $@

$(CONTRACT_TEST): contract_test.cpp tensor_contract.hpp Makefile | $(BUILD_DIR)
	$(CXX) -std=c++14 -O2 -Wall -Wextra -Werror contract_test.cpp -o $@

$(DECODE_TEST): decode_test.cpp detection_decode.hpp tensor_contract.hpp Makefile | $(BUILD_DIR)
	$(CXX) -std=c++14 -O2 -Wall -Wextra -Werror decode_test.cpp -o $@

clean:
	rm -rf $(BUILD_DIR)

FORCE:
