# Copyright Cartesi and individual authors (see AUTHORS)
# SPDX-License-Identifier: LGPL-3.0-or-later
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with this program (see COPYING). If not, see <https://www.gnu.org/licenses/>.
#

TARGET_OS?=$(shell uname)
export TARGET_OS

# Install settings
DEB_ARCH?= $(shell dpkg --print-architecture 2>/dev/null || echo amd64)
PREFIX= /usr
MACHINE_EMULATOR_VERSION= $(shell make -sC src version)
MACHINE_EMULATOR_SO_VERSION= $(shell make -sC src so-version)
DEB_FILENAME= machine-emulator_$(DEB_ARCH).deb
BIN_RUNTIME_PATH= $(PREFIX)/bin
LIB_RUNTIME_PATH= $(PREFIX)/lib
DOC_RUNTIME_PATH= $(PREFIX)/doc/cartesi-machine
SHARE_RUNTIME_PATH= $(PREFIX)/share/cartesi-machine
IMAGES_RUNTIME_PATH= $(SHARE_RUNTIME_PATH)/images
LUA_RUNTIME_CPATH= $(PREFIX)/lib/lua/5.4
LUA_RUNTIME_PATH= $(PREFIX)/share/lua/5.4

TESTS_DEB_FILENAME= machine-emulator-tests_$(DEB_ARCH).deb
TESTS_DATA_DEB_FILENAME= machine-emulator-tests-data.deb
TESTS_DATA_RUNTIME_PATH= $(SHARE_RUNTIME_PATH)/tests/data
TESTS_SCRIPTS_RUNTIME_PATH= $(SHARE_RUNTIME_PATH)/tests/scripts
TESTS_LUA_RUNTIME_PATH= $(SHARE_RUNTIME_PATH)/tests/lua
TESTS_DOC_RUNTIME_PATH= $(PREFIX)/doc/cartesi-machine-tests
TESTS_DATA_DOC_RUNTIME_PATH= $(PREFIX)/doc/cartesi-machine-tests-data

ifeq ($(TARGET_OS),Darwin)
LIBCARTESI=libcartesi.dylib
LIBCARTESI_JSONRPC=libcartesi_jsonrpc.dylib
LIBCARTESI_SO=libcartesi-$(MACHINE_EMULATOR_SO_VERSION).dylib
LIBCARTESI_SO_JSONRPC=libcartesi_jsonrpc-$(MACHINE_EMULATOR_SO_VERSION).dylib
else
LIBCARTESI=libcartesi.so
LIBCARTESI_JSONRPC=libcartesi_jsonrpc.so
LIBCARTESI_SO=libcartesi-$(MACHINE_EMULATOR_SO_VERSION).so
LIBCARTESI_SO_JSONRPC=libcartesi_jsonrpc-$(MACHINE_EMULATOR_SO_VERSION).so
endif

BIN_INSTALL_PATH=    $(abspath $(DESTDIR)$(BIN_RUNTIME_PATH))
LIB_INSTALL_PATH=    $(abspath $(DESTDIR)$(LIB_RUNTIME_PATH))
DOC_INSTALL_PATH=    $(abspath $(DESTDIR)$(DOC_RUNTIME_PATH))
SHARE_INSTALL_PATH=  $(abspath $(DESTDIR)$(SHARE_RUNTIME_PATH))
IMAGES_INSTALL_PATH= $(abspath $(DESTDIR)$(IMAGES_RUNTIME_PATH))
UARCH_INSTALL_PATH=  $(abspath $(SHARE_INSTALL_PATH)/uarch)
LUA_INSTALL_CPATH=   $(abspath $(DESTDIR)$(LUA_RUNTIME_CPATH))
LUA_INSTALL_PATH=    $(abspath $(DESTDIR)$(LUA_RUNTIME_PATH))
INC_INSTALL_PATH=    $(abspath $(DESTDIR)$(PREFIX)/include/cartesi-machine)

TESTS_SCRIPTS_INSTALL_PATH= $(abspath $(DESTDIR)$(TESTS_SCRIPTS_RUNTIME_PATH))
TESTS_LUA_INSTALL_PATH= $(abspath $(DESTDIR)$(TESTS_LUA_RUNTIME_PATH))
TESTS_DOC_INSTALL_PATH= $(abspath $(DESTDIR)$(TESTS_DOC_RUNTIME_PATH))
TESTS_DATA_INSTALL_PATH= $(abspath $(DESTDIR)$(TESTS_DATA_RUNTIME_PATH))
TESTS_DATA_DOC_INSTALL_PATH= $(abspath $(DESTDIR)$(TESTS_DATA_DOC_RUNTIME_PATH))

INSTALL_FILE= install -m0644
INSTALL_EXEC= install -m0755
INSTALL_DIR= cp -RP
SYMLINK= ln -sf
CHMOD_EXEC= chmod 0755

EMU_TO_BIN= src/cartesi-jsonrpc-machine src/cartesi-hash-tree-hash
EMU_TO_LIB= src/$(LIBCARTESI_SO) src/$(LIBCARTESI_SO_JSONRPC)
EMU_TO_LIB_A= src/libcartesi.a src/libcartesi_jsonrpc.a src/libluacartesi.a src/libluacartesi_jsonrpc.a
EMU_LUA_TO_BIN= src/cartesi-machine.lua src/cartesi-machine-stored-hash.lua
EMU_TO_LUA_PATH= src/cartesi/util.lua src/cartesi/gdbstub.lua src/cartesi/evmu.lua src/cartesi/bash.lua src/cartesi/hash-tree.lua
EMU_TO_LUA_THIRD_PARTY_PATH= src/cartesi/third-party/bint.lua
EMU_TO_LUA_CPATH= src/cartesi.so
EMU_TO_LUA_CARTESI_CPATH= src/cartesi/jsonrpc.so
EMU_TO_INC= $(addprefix src/,cm-jsonrpc.h cm.h cm-version.h)
UARCH_TO_SHARE= uarch-ram.bin

TESTS_TO_BIN= tests/build/misc/test-machine-c-api
TESTS_LUA_TO_LUA_PATH=tests/lua/cartesi
TESTS_LUA_TO_TEST_LUA_PATH=$(wildcard tests/lua/*.lua)
TESTS_SCRIPTS_TO_TEST_SCRIPTS_PATH=$(wildcard tests/scripts/*.sh)
TESTS_DATA_TO_TESTS_DATA_PATH= tests/build/machine tests/build/uarch tests/build/uarch-riscv-arch-test tests/build/images

# Build settings
DEPDIR = third-party
SRCDIR = $(abspath src)
TESTSDIR = $(abspath tests)
DOWNLOADDIR = $(DEPDIR)/downloads
# risc0 is optional and handled separately to allow clean without risc0 tooling installed
SUBCLEAN = $(addsuffix .clean,$(SRCDIR) uarch tests)

# Pass down received UARCH_DEFS to sub-makefiles
export UARCH_DEFS

# Docker image tag
TAG ?= devel
DEBIAN_IMG ?= cartesi/machine-emulator:$(TAG).deb

# Base images for the emulator Dockerfile. Single source of truth: passed as
# build-args and stamped into the image as a label so downstream images (e.g.
# doc/) can reuse the exact same base without duplicating these values.
BUILD_BASE ?= debian:trixie-20250811
RUNTIME_BASE ?= debian:trixie-20250811-slim

# Docker image platform
BUILD_PLATFORM ?=

ifneq ($(BUILD_PLATFORM),)
DOCKER_PLATFORM=--platform $(BUILD_PLATFORM)
endif

# Code instrumentation
debug?=no
relwithdebinfo?=no
release?=no
sanitize?=no
fuzz?=no
coverage?=no
git_commit?=

# If not build type is chosen, set the default to release with debug information,
# so the emulator is packaged correctly by default.
ifeq (,$(filter yes,$(relwithdebinfo) $(release) $(debug) $(sanitize) $(fuzz)))
relwithdebinfo=yes
endif

export sanitize
export fuzz
export debug
export relwithdebinfo
export release
export coverage
export git_commit

# Mac OS X specific settings
ifeq ($(TARGET_OS),Darwin)
export CC = clang
export CXX = clang++
COVERAGE_TOOLCHAIN?=clang
LIBRARY_PATH = "export DYLD_LIBRARY_PATH="

# Linux specific settings
else ifeq ($(TARGET_OS),Linux)
export CC=gcc
export CXX=g++
COVERAGE_TOOLCHAIN?=gcc
LIBRARY_PATH = "export LD_LIBRARY_PATH=$(SRCDIR)"

# Other system
else
export CC=gcc
export CXX=g++
COVERAGE_TOOLCHAIN?=gcc

endif
export COVERAGE_TOOLCHAIN

GENERATED_FILES= uarch/uarch-pristine-hash.c uarch/uarch-pristine-ram.c src/cm-version.h src/interpret-jump-table.hpp
ADD_GENERATED_FILES_DIFF= add-generated-files.diff
COMPUTATION_HASH_TARGETS= build-computation-hash-corpus build-computation-hash-corpus-with-toolchain \
	create-computation-hash-corpus archive-computation-hash-corpus \
	verify-existing-computation-hash-corpus clean-computation-hash-corpus

all: source-default

help:
	@echo 'Main targets:'
	@echo '* all                                 - Build the src/ code. To build from a clean clone, run: make submodules all'
	@echo '  uarch                               - Build microarchitecture (requires riscv64-cartesi-linux-gnu-* toolchain)'
	@echo '  uarch-with-toolchain                - Build microarchitecture using the toolchain docker image'
	@echo '  risc0                               - Build risc0 (requires cargo'
	@echo '  build-tests-all                     - Build all tests (machine, uarch and misc)'
	@echo '  build-tests-machine                 - Build machine emulator tests (requires rv64gc-lp64d riscv64-cartesi-linux-gnu-* toolchain)'
	@echo '  build-tests-machine-with-toolchain  - Build machine emulator tests using the rv64gc-lp64d toolchain docker image'
	@echo '  build-tests-uarch                   - Build microarchitecture rv64i instruction tests (requires rv64ima-lp64 riscv64-cartesi-linux-gnu-* toolchain)'
	@echo '  build-tests-uarch-with-toolchain    - Build microarchitecture rv64i instruction tests using the rv64ima-lp64 toolchain docker image'
	@echo '  build-tests-misc                    - Build miscellaneous tests'
	@echo '  build-tests-misc-with-builder-image - Build miscellaneous tests using the cartesi/machine-emulator:builder image'
	@echo '  build-tests-fuzz                    - Build fuzz test targets (requires Clang with libFuzzer)'
	@echo '  test-machine                        - Run machine emulator tests'
	@echo '  test-uarch                          - Run uarch tests'
	@echo '  test-risc0                         - Run risc0 tests'
	@echo '  test-misc                           - Run miscellaneous tests'
	@echo '  test-fuzz                           - Run fuzz tests (requires Clang with libFuzzer)'
	@echo '  build-computation-hash-corpus       - Build fixtures and record the computation-hash corpus'
	@echo '  build-computation-hash-corpus-with-toolchain - Build and record the corpus using the toolchain image'
	@echo '  create-computation-hash-corpus      - Record the corpus using existing fixtures'
	@echo '  test-computation-hash               - Verify an existing computation-hash corpus'
	@echo '  archive-computation-hash-corpus     - Archive the recorded computation-hash corpus'
	@echo '  test                                - Run all tests'
	@echo '  coverage-all                        - Run all tests and generate the coverage report (requires coverage=yes builds, see tests/scripts/run-coverage-local.sh)'
	@echo '  doc                                 - Build the doxygen documentation (requires doxygen)'
	@echo 'Docker images targets:'
	@echo '  build-emulator-image                - Build the machine-emulator debian based docker image'
	@echo '  build-debian-package                - Build the machine-emulator.deb package from image'
	@echo '  build-toolchain                     - Build the emulator toolchain docker image'
	@echo '  create-generated-files-patch        - Create patch that adds generated files to source tree'
	@echo 'Cleaning targets:'
	@echo '  clean                               - Clean the src/ artifacts'
	@echo '  clean-coverage                      - Remove collected coverage data'
	@echo '  clean-computation-hash-corpus       - Remove the computation-hash corpus and archive'
	@echo '  depclean                            - Clean + dependencies'
	@echo '  distclean                           - Depclean + profile information and downloads'

$(SUBCLEAN): %.clean:
	@$(MAKE) -C $* clean

clean: $(SUBCLEAN)
	@$(MAKE) -C risc0 clean
	@rm -rf machine-emulator*.deb
	@rm -rf $(ADD_GENERATED_FILES_DIFF)

depclean: clean
	@rm -rf $(DOWNLOADDIR)

distclean: depclean

env:
	@echo $(LIBRARY_PATH)
	@echo "export PATH='$(SRCDIR):$(TESTSDIR)/misc:${PATH}'"
	@echo "export LUA_PATH_5_4='$(SRCDIR)/?.lua;$(TESTSDIR)/lua/?.lua;$${LUA_PATH_5_4:-;}'"
	@echo "export LUA_CPATH_5_4='$(SRCDIR)/?.so;$${LUA_CPATH_5_4:-;}'"

doc:
	cd doc && doxygen Doxyfile

bundle-boost: $(DEPDIR)/downloads/boost
$(DEPDIR)/downloads/boost:
	mkdir -p $(DOWNLOADDIR)
	wget -O $(DEPDIR)/downloads/boost_1_83_0.tar.gz https://archives.boost.io/release/1.83.0/source/boost_1_83_0.tar.gz
	tar -C $(DEPDIR)/downloads -xzf $(DEPDIR)/downloads/boost_1_83_0.tar.gz boost_1_83_0/boost
	mv $(DEPDIR)/downloads/boost_1_83_0/boost $(DEPDIR)/downloads/boost
	rm -rf $(DEPDIR)/downloads/boost_1_83_0.tar.gz $(DEPDIR)/downloads/boost_1_83_0

submodules:
	git submodule update --init --recursive

hash luacartesi:
	@eval $$($(MAKE) -s --no-print-directory env); $(MAKE) -C $(SRCDIR) $@

libcartesi libcartesi_jsonrpc libcartesi.a libcartesi_jsonrpc.a libcartesi.so libcartesi_jsonrpc.so:
	@eval $$($(MAKE) -s --no-print-directory env); $(MAKE) -C $(SRCDIR) $@

version:
	@eval $$($(MAKE) -s --no-print-directory env); $(MAKE) -sC $(SRCDIR) $@

test:
	@eval $$($(MAKE) -s --no-print-directory env); $(MAKE) -C tests $@

test-risc0:
	@eval $$($(MAKE) -s --no-print-directory env); $(MAKE) -C risc0 test

test% coverage% build-tests%:
	@eval $$($(MAKE) -s --no-print-directory env); $(MAKE) -C tests $@

$(COMPUTATION_HASH_TARGETS):
	@eval $$($(MAKE) -s --no-print-directory env); $(MAKE) -C tests $@

clean-coverage:
	@$(MAKE) -C tests $@

build-tests-misc-with-builder-image: build-emulator-builder-image

lint check-format format:
	@$(MAKE) $@-src $@-tests

check-format-lua check-lua format-lua:
	@$(MAKE) $@-src $@-tests $@-doc

lint-% check-format-% format-% check-format-lua-% check-lua-% format-lua-%:
	@eval $$($(MAKE) -s --no-print-directory env); $(MAKE) -C $(if $(findstring -doc,$@),doc,$(if $(findstring -src,$@),src,tests)) $(subst -doc,,$(subst -src,,$(subst -tests,,$@)))

source-default:
	@eval $$($(MAKE) -s --no-print-directory env); $(MAKE) -C $(SRCDIR)

uarch: $(SRCDIR)/cm-version.h $(SRCDIR)/interpret-jump-table.hpp
	@eval $$($(MAKE) -s --no-print-directory env); $(MAKE) -C uarch

risc0: $(SRCDIR)/cm-version.h
	@eval $$($(MAKE) -s --no-print-directory env); $(MAKE) -C risc0

$(SRCDIR)/cm-version.h:
	@eval $$($(MAKE) -s --no-print-directory env); $(MAKE) -C $(SRCDIR) cm-version.h

$(SRCDIR)/interpret-jump-table.hpp:
	@eval $$($(MAKE) -s --no-print-directory env); $(MAKE) -C $(SRCDIR) interpret-jump-table.hpp

build-emulator-builder-image:
	docker build $(DOCKER_PLATFORM) --build-arg DEBUG=$(debug) --build-arg COVERAGE=$(coverage) --build-arg THREADS=$(threads) --build-arg SANITIZE=$(sanitize) --build-arg BUILD_BASE=$(BUILD_BASE) --target builder -t cartesi/machine-emulator:builder -f Dockerfile .

build-emulator-toolchain-image build-toolchain:
	docker build $(DOCKER_PLATFORM) --build-arg BUILD_BASE=$(BUILD_BASE) --target toolchain -t cartesi/machine-emulator:toolchain -f Dockerfile .

build-emulator-image:
	docker build $(DOCKER_PLATFORM) --build-arg DEBUG=$(debug) --build-arg COVERAGE=$(coverage) --build-arg THREADS=$(threads) --build-arg SANITIZE=$(sanitize) --build-arg BUILD_BASE=$(BUILD_BASE) --build-arg RUNTIME_BASE=$(RUNTIME_BASE) -t cartesi/machine-emulator:$(TAG) -f Dockerfile .

build-emulator-tests-image: build-emulator-builder-image build-emulator-image
	docker build $(DOCKER_PLATFORM) --build-arg DEBUG=$(debug) --build-arg COVERAGE=$(coverage) --build-arg THREADS=$(threads) --build-arg SANITIZE=$(sanitize) --build-arg TAG=$(TAG) -t cartesi/machine-emulator:tests -f tests/Dockerfile .

build-emulator-tests-builder-image: build-emulator-builder-image
	docker build $(DOCKER_PLATFORM) --target tests-builder --build-arg DEBUG=$(debug) --build-arg COVERAGE=$(coverage) --build-arg THREADS=$(threads) --build-arg SANITIZE=$(sanitize) --build-arg TAG=$(TAG) -t cartesi/machine-emulator:tests-builder -f tests/Dockerfile .

build-debian-package:
	docker build $(DOCKER_PLATFORM) --target debian-packager --build-arg DEBUG=$(debug) --build-arg COVERAGE=$(coverage) --build-arg THREADS=$(threads) --build-arg SANITIZE=$(sanitize) --build-arg BUILD_BASE=$(BUILD_BASE) -t $(DEBIAN_IMG) -f Dockerfile .

build-tests-debian-packages: build-emulator-builder-image
	docker build $(DOCKER_PLATFORM) --target tests-debian-packager --build-arg TAG=$(TAG) -t cartesi/machine-emulator:tests-debian-packager -f tests/Dockerfile .
	$(MAKE) copy-tests-debian-packages

copy-tests-debian-packages:
	docker create --name tests-debian-packages $(DOCKER_PLATFORM) cartesi/machine-emulator:tests-debian-packager
	docker cp tests-debian-packages:/usr/src/emulator/$(TESTS_DEB_FILENAME) .
	docker cp tests-debian-packages:/usr/src/emulator/$(TESTS_DATA_DEB_FILENAME) .
	docker rm tests-debian-packages

copy:
	docker create --name uarch-ram-bin $(DOCKER_PLATFORM) $(DEBIAN_IMG)
	docker cp uarch-ram-bin:/usr/src/emulator/$(DEB_FILENAME) .
	docker cp uarch-ram-bin:/usr/src/emulator/src/cm-version.h .
	docker cp uarch-ram-bin:/usr/src/emulator/src/interpret-jump-table.hpp .
	docker cp uarch-ram-bin:/usr/src/emulator/uarch/uarch-ram.bin .
	docker cp uarch-ram-bin:/usr/src/emulator/uarch/uarch-pristine-ram.c .
	docker cp uarch-ram-bin:/usr/src/emulator/uarch/uarch-pristine-hash.c .
	docker rm uarch-ram-bin

check-toolchain:
	@if docker images $(DOCKER_PLATFORM) -q cartesi/machine-emulator:toolchain 2>/dev/null | grep -q .; then \
		echo "Docker image cartesi/machine-emulator:toolchain exists"; \
	else \
		echo "Docker image cartesi/machine-emulator:toolchain does not exist. Creating:"; \
		$(MAKE) build-toolchain; \
	fi

toolchain-env: check-toolchain
	@docker run $(DOCKER_PLATFORM) --hostname toolchain -it --rm \
		-e USER=$$(id -u -n) \
		-e GROUP=$$(id -g -n) \
		-e UID=$$(id -u) \
		-e GID=$$(id -g) \
		-v `pwd`:/opt/cartesi/machine-emulator \
		-w /opt/cartesi/machine-emulator \
		cartesi/machine-emulator:toolchain /bin/bash

toolchain-exec: check-toolchain
	docker run --hostname toolchain --rm \
		-e USER=$$(id -u -n) \
		-e GROUP=$$(id -g -n) \
		-e UID=$$(id -u) \
		-e GID=$$(id -g) \
		-e UARCH_DEFS="$(UARCH_DEFS)" \
		-v `pwd`:/opt/cartesi/machine-emulator \
		-w /opt/cartesi/machine-emulator \
		cartesi/machine-emulator:toolchain /bin/bash -c "$(CONTAINER_COMMAND)"

uarch-with-toolchain:
	@$(MAKE) toolchain-exec CONTAINER_COMMAND="make uarch coverage=$(coverage)"

# Create install directories
$(BIN_INSTALL_PATH) $(LIB_INSTALL_PATH) $(LUA_INSTALL_PATH) $(LUA_INSTALL_CPATH) $(LUA_INSTALL_CPATH)/cartesi $(LUA_INSTALL_PATH)/cartesi $(LUA_INSTALL_PATH)/cartesi/third-party $(INC_INSTALL_PATH) $(IMAGES_INSTALL_PATH) $(UARCH_INSTALL_PATH) $(TESTS_DATA_INSTALL_PATH) $(TESTS_SCRIPTS_INSTALL_PATH) $(TESTS_LUA_INSTALL_PATH):
	mkdir -m 0755 -p $@

install-headers: $(INC_INSTALL_PATH)
	$(INSTALL_FILE) $(EMU_TO_INC) $(INC_INSTALL_PATH)

install-static-libs: $(LIB_INSTALL_PATH)
	$(INSTALL_FILE) $(EMU_TO_LIB_A) $(LIB_INSTALL_PATH)

install-shared-libs: $(LIB_INSTALL_PATH)
	$(INSTALL_EXEC) $(EMU_TO_LIB) $(LIB_INSTALL_PATH)
	$(SYMLINK) $(LIBCARTESI_SO) $(LIB_INSTALL_PATH)/$(LIBCARTESI)
	$(SYMLINK) $(LIBCARTESI_SO_JSONRPC) $(LIB_INSTALL_PATH)/$(LIBCARTESI_JSONRPC)

install-lua-libs: $(LUA_INSTALL_PATH)/cartesi $(LUA_INSTALL_CPATH)/cartesi $(LUA_INSTALL_PATH)/cartesi/third-party
	$(INSTALL_FILE) $(EMU_LUA_TO_BIN) $(LUA_INSTALL_PATH)
	$(INSTALL_FILE) $(EMU_TO_LUA_PATH) $(LUA_INSTALL_PATH)/cartesi
	$(INSTALL_FILE) $(EMU_TO_LUA_THIRD_PARTY_PATH) $(LUA_INSTALL_PATH)/cartesi/third-party
	$(INSTALL_EXEC) $(EMU_TO_LUA_CPATH) $(LUA_INSTALL_CPATH)
	$(INSTALL_EXEC) $(EMU_TO_LUA_CARTESI_CPATH) $(LUA_INSTALL_CPATH)/cartesi

install-bins: $(BIN_INSTALL_PATH)
	$(INSTALL_EXEC) $(EMU_TO_BIN) $(BIN_INSTALL_PATH)

install-lua-bins: $(BIN_INSTALL_PATH)
	cat tools/template/cartesi-machine.template | sed 's|ARG_LUA_PATH|$(LUA_RUNTIME_PATH)/?.lua|g;s|ARG_LUA_CPATH|$(LUA_RUNTIME_CPATH)/?.so|g;s|ARG_IMAGES_PATH|$(IMAGES_RUNTIME_PATH)|g;s|ARG_LUA_RUNTIME_PATH|$(LUA_RUNTIME_PATH)|g' > $(BIN_INSTALL_PATH)/cartesi-machine
	cat tools/template/cartesi-machine-stored-hash.template | sed 's|ARG_LUA_PATH|$(LUA_RUNTIME_PATH)/?.lua|g;s|ARG_LUA_CPATH|$(LUA_RUNTIME_CPATH)/?.so|g;s|ARG_LUA_RUNTIME_PATH|$(LUA_RUNTIME_PATH)|g' > $(BIN_INSTALL_PATH)/cartesi-machine-stored-hash
	$(CHMOD_EXEC) $(BIN_INSTALL_PATH)/cartesi-machine $(BIN_INSTALL_PATH)/cartesi-machine-stored-hash

install-shared-files: $(IMAGES_INSTALL_PATH)
	$(INSTALL_DIR) tools/gdb $(SHARE_INSTALL_PATH)/gdb

install: install-headers install-static-libs install-shared-libs install-lua-libs install-bins install-lua-bins install-shared-files

install-uarch: install $(UARCH_INSTALL_PATH)
	$(INSTALL_FILE) uarch/$(UARCH_TO_SHARE) $(UARCH_INSTALL_PATH)

debian-package: install
	mkdir -p $(DESTDIR)/DEBIAN $(DOC_INSTALL_PATH)
	$(INSTALL_FILE) COPYING $(DOC_INSTALL_PATH)/copyright
	sed 's|ARG_VERSION|$(MACHINE_EMULATOR_VERSION)|g;s|ARG_ARCH|$(DEB_ARCH)|g' tools/template/control.template > $(DESTDIR)/DEBIAN/control
	dpkg-deb -Zxz --root-owner-group --build $(DESTDIR) $(DEB_FILENAME)

install-tests-data: | $(TESTS_DATA_INSTALL_PATH)
	$(INSTALL_DIR) $(TESTS_DATA_TO_TESTS_DATA_PATH) $(TESTS_DATA_INSTALL_PATH)

install-tests: | $(LUA_INSTALL_PATH) $(BIN_INSTALL_PATH) $(TESTS_SCRIPTS_INSTALL_PATH) $(TESTS_LUA_INSTALL_PATH)
	$(INSTALL_EXEC) $(TESTS_TO_BIN) $(BIN_INSTALL_PATH)
	$(INSTALL_DIR) $(TESTS_LUA_TO_LUA_PATH) $(LUA_INSTALL_PATH)
	$(INSTALL_DIR) $(TESTS_LUA_TO_TEST_LUA_PATH) $(TESTS_LUA_INSTALL_PATH)
	$(INSTALL_DIR) $(TESTS_SCRIPTS_TO_TEST_SCRIPTS_PATH) $(TESTS_SCRIPTS_INSTALL_PATH)
	sed 's|ARG_LUA_PATH|$(LUA_RUNTIME_PATH)/?.lua|g;s|ARG_LUA_CPATH|$(LUA_RUNTIME_CPATH)/?.so|g;s|ARG_LUA_RUNTIME_PATH|$(TESTS_LUA_RUNTIME_PATH)|g;s|ARG_TESTS_PATH|$(TESTS_DATA_RUNTIME_PATH)/machine|g' tools/template/cartesi-machine-tests.template > $(BIN_INSTALL_PATH)/cartesi-machine-tests
	sed 's|ARG_LUA_PATH|$(LUA_RUNTIME_PATH)/?.lua|g;s|ARG_LUA_CPATH|$(LUA_RUNTIME_CPATH)/?.so|g;s|ARG_LUA_RUNTIME_PATH|$(TESTS_LUA_RUNTIME_PATH)|g;s|ARG_TESTS_UARCH_PATH|$(TESTS_DATA_RUNTIME_PATH)/uarch|g' tools/template/uarch-riscv-tests.template > $(BIN_INSTALL_PATH)/uarch-riscv-tests
	sed 's|ARG_LUA_PATH|$(LUA_RUNTIME_PATH)/?.lua|g;s|ARG_LUA_CPATH|$(LUA_RUNTIME_CPATH)/?.so|g;s|ARG_LUA_RUNTIME_PATH|$(TESTS_LUA_RUNTIME_PATH)|g;s|ARG_CM_CLI|$(LUA_RUNTIME_PATH)/cartesi-machine.lua|g;s|ARG_IMAGES_PATH|$(IMAGES_RUNTIME_PATH)|g' tools/template/test-spec.template > $(BIN_INSTALL_PATH)/test-spec
	$(CHMOD_EXEC) $(BIN_INSTALL_PATH)/cartesi-machine-tests $(BIN_INSTALL_PATH)/uarch-riscv-tests $(BIN_INSTALL_PATH)/test-spec

tests-data-debian-package: install-tests-data
	mkdir -p $(DESTDIR)/DEBIAN $(TESTS_DATA_DOC_INSTALL_PATH)
	$(INSTALL_FILE) tools/template/tests-data-copyright.template $(TESTS_DATA_DOC_INSTALL_PATH)/tests-data-copyright
	sed 's|ARG_VERSION|$(MACHINE_EMULATOR_VERSION)|g;s|ARG_ARCH|$(DEB_ARCH)|g' tools/template/tests-data-control.template > $(DESTDIR)/DEBIAN/control
	dpkg-deb -Zxz --root-owner-group --build $(DESTDIR) $(TESTS_DATA_DEB_FILENAME)

tests-debian-package: install-tests
	mkdir -p $(DESTDIR)/DEBIAN $(TESTS_DOC_INSTALL_PATH)
	$(INSTALL_FILE) tools/template/tests-copyright.template $(TESTS_DOC_INSTALL_PATH)/copyright
	sed 's|ARG_VERSION|$(MACHINE_EMULATOR_VERSION)|g;s|ARG_ARCH|$(DEB_ARCH)|g' tools/template/tests-control.template > $(DESTDIR)/DEBIAN/control
	dpkg-deb -Zxz --root-owner-group --build $(DESTDIR) $(TESTS_DEB_FILENAME)

create-generated-files-patch: $(ADD_GENERATED_FILES_DIFF)

$(ADD_GENERATED_FILES_DIFF): $(GENERATED_FILES)
	git add -f $(GENERATED_FILES)
	git diff --default-prefix --staged --output=$(ADD_GENERATED_FILES_DIFF)
	git reset -- $(GENERATED_FILES)

.PHONY: help all submodules doc clean distclean src luacartesi hash uarch risc0 \
	create-generated-files-patch $(COMPUTATION_HASH_TARGETS) $(SUBDIRS) $(SUBCLEAN)
