.PHONY: all build build-dev build-prod release release-target clean install fmt lint check test ci help upx-binaries install-upx fmt-check
PROJECT_NAME := scaffold-gen
BINARY_NAME := scafgen
CARGO := cargo
TARGET_DIR := target
DIST_DIR := dist
TARGET ?=
UPX_BIN := upx
RUSTFLAGS_RELEASE := -C link-arg=-s
all: build
build: build-dev
build-dev:
@echo "๐จ Building $(PROJECT_NAME) in debug mode..."
$(CARGO) build
@echo "๐ฆ Copying binary to project root..."
@cp $(TARGET_DIR)/debug/$(BINARY_NAME) $(DIST_DIR)/$(BINARY_NAME) 2>/dev/null || \
cp $(TARGET_DIR)/debug/$(PROJECT_NAME) $(DIST_DIR)/$(BINARY_NAME) 2>/dev/null || \
echo "โ ๏ธ Binary not found, check Cargo.toml [[bin]] configuration"
@echo "โ
Debug build complete: $(DIST_DIR)/$(BINARY_NAME)"
build-prod: release
release:
@echo "๐ Building $(PROJECT_NAME) in release mode with optimizations..."
$(CARGO) build --release
@mkdir -p $(DIST_DIR)
@echo "๐ฆ Copying binary to dist directory..."
@cp $(TARGET_DIR)/release/$(BINARY_NAME) $(DIST_DIR)/$(BINARY_NAME) 2>/dev/null || \
cp $(TARGET_DIR)/release/$(PROJECT_NAME) $(DIST_DIR)/$(BINARY_NAME) 2>/dev/null || \
echo "โ ๏ธ Binary not found, check Cargo.toml [[bin]] configuration"
@echo "โ
Release build complete: $(DIST_DIR)/$(BINARY_NAME)"
@ls -lh $(DIST_DIR)/$(BINARY_NAME) 2>/dev/null || true
release-target:
ifndef TARGET
$(error TARGET is not set. Usage: make release-target TARGET=x86_64-unknown-linux-musl)
endif
@echo "๐ Building $(PROJECT_NAME) for target $(TARGET)..."
$(CARGO) build --release --target $(TARGET)
@mkdir -p $(DIST_DIR)
@echo "๐ฆ Copying binary to dist directory..."
@if [ -f "$(TARGET_DIR)/$(TARGET)/release/$(BINARY_NAME)" ]; then \
cp $(TARGET_DIR)/$(TARGET)/release/$(BINARY_NAME) $(DIST_DIR)/$(BINARY_NAME)-$(TARGET); \
elif [ -f "$(TARGET_DIR)/$(TARGET)/release/$(BINARY_NAME).exe" ]; then \
cp $(TARGET_DIR)/$(TARGET)/release/$(BINARY_NAME).exe $(DIST_DIR)/$(BINARY_NAME)-$(TARGET).exe; \
else \
echo "โ ๏ธ Binary not found for target $(TARGET)"; \
exit 1; \
fi
@echo "โ
Release build complete for $(TARGET)"
@ls -lh $(DIST_DIR)/$(BINARY_NAME)-$(TARGET)* 2>/dev/null || true
release-upx: release upx-binaries
@echo "โ
Release build with UPX compression complete"
install-upx:
@echo "๐ Checking for UPX..."
@which $(UPX_BIN) > /dev/null 2>&1 || { \
echo "๐ฆ Installing UPX..."; \
if command -v apt-get > /dev/null 2>&1; then \
sudo apt-get update && sudo apt-get install -y upx-ucl; \
elif command -v brew > /dev/null 2>&1; then \
brew install upx; \
elif command -v pacman > /dev/null 2>&1; then \
sudo pacman -S upx; \
else \
echo "โ Please install UPX manually: https://github.com/upx/upx/releases"; \
exit 1; \
fi; \
}
@echo "โ
UPX is available"
upx-binaries: install-upx
@echo "๐๏ธ Compressing binaries with UPX..."
@if [ -f "$(DIST_DIR)/$(BINARY_NAME)" ]; then \
if $(UPX_BIN) -t "$(DIST_DIR)/$(BINARY_NAME)" >/dev/null 2>&1; then \
echo "โญ๏ธ Skipping $(BINARY_NAME) (already packed by UPX)"; \
else \
echo "๐๏ธ Compressing $(BINARY_NAME)..."; \
$(UPX_BIN) -9 "$(DIST_DIR)/$(BINARY_NAME)" || echo "โ ๏ธ Failed to compress $(BINARY_NAME)"; \
fi; \
ls -lh "$(DIST_DIR)/$(BINARY_NAME)"; \
else \
echo "โ ๏ธ Binary not found: $(DIST_DIR)/$(BINARY_NAME)"; \
fi
install: release
@echo "๐ฆ Installing $(BINARY_NAME) to ~/.cargo/bin..."
$(CARGO) install --path .
@echo "โ
Installation complete"
fmt:
@echo "โจ Formatting code..."
$(CARGO) fmt
fmt-check:
@echo "โจ Checking code formatting..."
$(CARGO) fmt --all -- --check
lint:
@echo "๐ Running linter..."
$(CARGO) clippy --all-targets --all-features -- -D warnings
check:
@echo "โ
Checking code..."
$(CARGO) check
test:
@echo "๐งช Running tests..."
$(CARGO) test
ci: fmt-check lint test
@echo "โ
All CI checks passed!"
clean:
@echo "๐งน Cleaning build artifacts..."
$(CARGO) clean
@rm -rf $(DIST_DIR)
@echo "โ
Clean complete"
size-compare: build-dev
@echo ""
@echo "๐ Binary size comparison:"
@echo "Debug build:"
@ls -lh $(TARGET_DIR)/debug/$(BINARY_NAME) 2>/dev/null || ls -lh $(TARGET_DIR)/debug/$(PROJECT_NAME) 2>/dev/null || echo " Not found"
@echo ""
@if [ -f "$(TARGET_DIR)/release/$(BINARY_NAME)" ] || [ -f "$(TARGET_DIR)/release/$(PROJECT_NAME)" ]; then \
echo "Release build:"; \
ls -lh $(TARGET_DIR)/release/$(BINARY_NAME) 2>/dev/null || ls -lh $(TARGET_DIR)/release/$(PROJECT_NAME) 2>/dev/null; \
fi
help:
@echo "Available targets:"
@echo ""
@echo " Build targets:"
@echo " all - Build in debug mode (default)"
@echo " build - Build in debug mode"
@echo " build-dev - Build in debug mode and copy to project root"
@echo " build-prod - Build in release mode with optimizations"
@echo " release - Build optimized release binary"
@echo " release-upx - Build release and compress with UPX"
@echo ""
@echo " Installation:"
@echo " install - Install binary to ~/.cargo/bin"
@echo " install-upx - Install UPX compression tool"
@echo ""
@echo " Development:"
@echo " fmt - Format code"
@echo " lint - Run linter (clippy)"
@echo " check - Check code without building"
@echo " test - Run tests"
@echo " ci - Run all CI checks"
@echo ""
@echo " Utilities:"
@echo " clean - Clean build artifacts"
@echo " size-compare - Show binary size comparison"
@echo " upx-binaries - Compress binaries with UPX"
@echo " help - Show this help message"
@echo ""
@echo " Cross-compilation:"
@echo " release-target TARGET=<target> - Build for specific target"
@echo " Example: make release-target TARGET=x86_64-unknown-linux-musl"
@echo ""
@echo " Optimization flags used in release build (configured in Cargo.toml):"
@echo " opt-level = 3 - Maximum optimization level"
@echo " lto = \"fat\" - Link-time optimization"
@echo " codegen-units = 1 - Single codegen unit for better optimization"
@echo " strip = true - Strip symbols (like Go's -ldflags=\"-s -w\")"