TAGS: MakeFile === QUESTION === Please write a GNU Makefile, which uses the command `cmm print -f db/ -a >out/gpu_plan.md` and `python convert.py out/gpu_plan.md` if source file is changing, to create `out/gpu_plan.html`. ==== ANSWER ==== Here's a GNU Makefile that performs the required operations: ```makefile # Variables to define the source and output directories SRC_DIR = db OUT_DIR = out # List of source files without extension SOURCES = 0014 0022 0013 0001 0016 0017 0018 0023 0019 0002 0025 # Add directory and extension to the source filenames SRC_FILES = $(SOURCES:%=$(SRC_DIR)/%.txt) # Add directory and .md extension to the markdown filenames MD_FILES = $(SOURCES:%=$(OUT_DIR)/%.md) # Add .html extension for the HTML filenames HTML_FILES = $(MD_FILES:.md=.html) # Default target all: Makefile convert.py $(HTML_FILES) $(OUT_DIR)/learning.html Makefile: $(SRC_DIR)/0026.txt cmm print -f $< -S | sed "s/ `printf ' /\t/g'`" >$@ convert.py: $(SRC_DIR)/0003.txt Makefile cmm print -f $< -S >$@ # Rule to create a markdown file from a source file $(OUT_DIR)/%.md: $(SRC_DIR)/%.txt cmm print -f $< -a > $@ # Rule to create an HTML file from a markdown file $(OUT_DIR)/%.html: $(OUT_DIR)/%.md convert.py python convert.py $< $(OUT_DIR)/learning.html: $(SRC_DIR)/0015.txt $(SRC_FILES) Makefile cmm print -f $< -S | \ awk "/LINKS_LINE/ { \ split(\"$(SOURCES)\", sources, \" \"); \ for (i = 1; i <= length(sources); i++) { \ \"awk '/^# /{ sub(/^# /, \\\"\\\"); print \$0; }' db/\" sources[i] \".txt\" | getline NAME; \ print \"
  • \" NAME \"
  • \"; \ } \ } 1" > $@ # Target to clean the output directory clean: rm -f $(OUT_DIR)/* .PHONY: all clean ``` In this `Makefile`: 1. `SOURCES` is a list of all source files (without their file extensions). You can add or remove file names from this list as needed. 2. The `SRC_FILES`, `MD_FILES`, and `HTML_FILES` variables generate the full filenames with directory and extension based on the `SOURCES` list. 3. The `$(OUT_DIR)/%.md: $(SRC_DIR)/%.txt` and `$(OUT_DIR)/%.html: $(OUT_DIR)/%.md` rules use pattern-matching to create the appropriate `.md` or `.html` file for each source file. 4. The `all` target now depends on `$(HTML_FILES)`, which means it will generate an HTML file for each source file listed in `SOURCES`. The `%.txt` and `%.md` are pattern matching rules that match any file with a `.txt` or `.md` extension respectively. `$<` refers to the first prerequisite (i.e., the source file), and `$@` refers to the target of the rule. Generate the `Makefile` with this command: `cmm print -f db/0026.txt -S | sed $'s/ /\t/g' >Makefile` To run this `Makefile`, you can still use `make` command in the terminal, and `make clean` to clean up the output directory.