# vmkit: example build. # Builds the portable example loader and its companion builder. # # Usage: # make # build both example_loader and example_builder # make run-loader # build + run the example loader # make run-builder # build + run the example builder # make clean # remove built artifacts # # Override CXX or CXXFLAGS as needed: # make CXX=g++ # make CXXFLAGS="-std=c++20 -O3" # Use = (not ?=) so we override Make's built-in default of g++. # Override on the command line: make CXX=g++ CXX = clang++ CXXFLAGS = -std=c++20 -O2 -Wall -Wextra -Wpedantic INCLUDES := -I. # Detect MSYS2 / MinGW / Cygwin shells where MSYS-style /tmp paths leak into # TMP/TEMP and break Microsoft's link.exe. In that case we point both at # LOCALAPPDATA\Temp (resolved by the recipe shell at build time). UNAME_S := $(shell uname -s 2>/dev/null) ifneq (,$(filter MSYS% MINGW% CYGWIN%,$(UNAME_S))) EXE := .exe RM := rm -f TMP_FIX := TMP="$$LOCALAPPDATA\\Temp" TEMP="$$LOCALAPPDATA\\Temp" else ifeq ($(OS),Windows_NT) EXE := .exe RM := rm -f TMP_FIX := else EXE := RM := rm -f TMP_FIX := endif EXAMPLES := example/example_loader$(EXE) example/example_builder$(EXE) .PHONY: all clean run-loader run-builder all: $(EXAMPLES) # The builder reads example/payload.bin (raw shellcode) and emits the # encrypted bytecode + payload header that the loader consumes. If you change # payload.bin, embedded.h regenerates and the loader picks it up automatically. example/embedded.h: example/example_builder$(EXE) example/payload.bin ./$< example/payload.bin > $@ # Loader depends on the generated bytecode header. example/example_loader$(EXE): example/example_loader.cpp vm_loader.hpp example/embedded.h $(TMP_FIX) $(CXX) $(CXXFLAGS) $(INCLUDES) $< -o $@ example/%$(EXE): example/%.cpp vm_loader.hpp $(TMP_FIX) $(CXX) $(CXXFLAGS) $(INCLUDES) $< -o $@ run-loader: example/example_loader$(EXE) ./$< run-builder: example/example_builder$(EXE) ./$< clean: -$(RM) $(EXAMPLES) example/embedded.h