How to Use Unrar in a Makefile
Automating the extraction of RAR archives is often necessary when
projects rely on compressed external datasets, third-party libraries, or
legacy dependencies during the build process. This article explains how
to integrate the unrar command-line tool into a GNU
Makefile to automatically extract files during a build, handle
idempotency using sentinel files, and cleanly remove extracted assets
when rebuilding.
Essential
unrar Flags for Automation
Because make is designed for automated, non-interactive
execution, you must run unrar with flags that prevent
interactive prompts from halting the build:
x: Extracts files with their original directory structure intact.-y: Assumes "yes" to all queries, allowing unattended execution.-o+: Automatically overwrites existing files.-inul: (Optional) Suppresses all output except errors to keep build logs clean.
A typical command structure looks like this:
unrar x -y -o+ archive.rar destination/Implementing a Sentinel File Pattern
A common issue when using extraction tools inside Makefiles is
handling dependencies. An archive usually unpacks into multiple files,
which can cause make to run extraction redundantly if
targets are not defined carefully. The recommended approach is using a
hidden "sentinel" (or "stamp") file that indicates the extraction
completed successfully.
Here is a standard Makefile implementation:
# Variables
UNRAR := unrar
ARCHIVE := data/assets.rar
EXTRACT_DIR := build/assets
STAMP_FILE := $(EXTRACT_DIR)/.extracted
.PHONY: all clean
all: $(STAMP_FILE)
@echo "Build complete. Assets are ready."
# Rule to extract the archive
$(STAMP_FILE): $(ARCHIVE)
@mkdir -p $(EXTRACT_DIR)
$(UNRAR) x -y -o+ $(ARCHIVE) $(EXTRACT_DIR)/
@touch $(STAMP_FILE)
# Cleanup rule
clean:
rm -rf $(EXTRACT_DIR)How the Target Works
- Dependency Tracking: The target
$(STAMP_FILE)depends on$(ARCHIVE). Make only executes the extraction step if$(ARCHIVE)is newer than the stamp file or if the stamp file does not exist. - Directory Creation: The rule runs
mkdir -p $(EXTRACT_DIR)to ensure the target output folder exists before running the command. - Touch Command: Once
unrarcompletes,touch $(STAMP_FILE)creates or updates the timestamp of the marker file inside the target directory. - Clean Integration: Adding the output folder to the
cleantarget ensures that runningmake cleancompletely purges extracted artifacts so they can be fresh on the next build.
Extracting Specific Files
If you only need a specific file from an archive rather than the entire contents, define the expected file directly as the target:
EXTRACTED_FILE := build/assets/config.json
$(EXTRACTED_FILE): $(ARCHIVE)
@mkdir -p $(dir $@)
$(UNRAR) x -y -o+ $(ARCHIVE) config.json $(dir $@)In this setup, make checks for config.json
directly, eliminating the need for a separate sentinel file.