Makefile

You can read a lot about makefiles at the wiki.

You can dynamically create makefiles with autoconf or CMake.

Defining the variables(macros). Note: path should be provided without quotes.

MACRO = definition
MAIN_DIR := training
TRAIN_DIR := $(MAIN_DIR)/train/$(PROJECT_NAME)_$(RUN)

You can overwrite macros providing it’s value to a make call

make MACRO="some_new_value"

ifdef and ifndef

ifdef ENV_VAR
    LOCAL_VAR = $(ENV_VAR)
else
    LOCAL_VAR = $(shell $(SOME_SHELL_COMMAND))
endif

execute shell command

# simple command
RESULT = `some_command`

# complex command
SOME_SHELL_COMMAND = find $(TRAIN_DIR) -name 'model*' | awk -F '.' '{print $$2}' | awk -F '-' '{print $$2}' | sort -g | tail -n 1
LOCAL_VAR = $(shell $(SOME_SHELL_COMMAND))

define and call commands

merged_command: command_1 command_2

command_1:
    rm -rf $(TRAIN_DIR)/*

command_2:
    rm -rf $(EVAL_DIR)/*

set environment variables

CUDA_VISIBLE_DEVICES=$(TRAIN_CUDA) python train.py

update one file after another modification

dependent_file.txt: required.html
    lynx -dump required.html > dependent_file.txt