|
| 1 | +# `make help` for documentation. |
| 2 | + |
| 3 | +-include Makefile_params |
| 4 | + |
| 5 | +DEBUG_DEFINE ?= |
| 6 | +DEBUG_FLAGS ?= |
| 7 | +# For -DDEBUG and -DPROFILE, used dedicated DEFINES, as these must be modified |
| 8 | +# separatedly for certain targets. |
| 9 | +DEFINES ?= #-DPOSIX |
| 10 | +# Extension of the input to be compiled. |
| 11 | +IN_EXT ?= .cpp |
| 12 | +# Directory where compilation input files (e.g. `.c` or `.cpp`) are found. |
| 13 | +IN_DIR ?= ./ |
| 14 | +# Fortran compiler. |
| 15 | +FF ?= gfortran |
| 16 | +INCLUDE_DIRS ?= #-L/usr/include/GL |
| 17 | +LIBS ?= #-lglut -lGLU -lGL |
| 18 | +MYCC ?= gcc |
| 19 | +MYCFLAGS ?= -std=c11 -Wall -pedantic-errors -march=native $(CFLAGS_EXTRA) |
| 20 | +MYCXX ?= g++ |
| 21 | +MYCXXFLAGS ?= -std=c++11 -Wall -pedantic-errors -march=native $(CXXFLAGS_EXTRA) |
| 22 | +# Should be turned on for production. |
| 23 | +# For development leave off to compile faster and produce more predictable assembly code. |
| 24 | +OPTIMIZE_FLAGS ?= #-O3 |
| 25 | +# Directory where compiled outputs will be put. |
| 26 | +OUT_DIR ?= ./ |
| 27 | +OUT_BASENAME_NOEXT ?= main |
| 28 | +OUT_EXT ?= |
| 29 | +RUN ?= $(OUT_BASENAME_NOEXT) |
| 30 | +# If this file or directory exists, it will be symlinked into the same directory |
| 31 | +# from which the executable will be run. This way, the executable can suppose this is in the current directory. |
| 32 | +RUN_INPUT ?= input |
| 33 | +PROFILE_DEFINE ?= |
| 34 | +PROFILE_FLAGS ?= |
| 35 | +PREDEF ?= #-DDEBUG -DPROFILE -DWINDOWS |
| 36 | +# Passed as command line args to bin on run. |
| 37 | +RUN_ARGS ?= #0 1 |
| 38 | +TMP_DIR ?= _build/ |
| 39 | +TMP_EXT ?= .o |
| 40 | + |
| 41 | +INS := $(wildcard $(IN_DIR)*$(IN_EXT)) |
| 42 | +INS_NODIR := $(notdir $(INS)) |
| 43 | +TMPS_NODIR := $(INS_NODIR:$(IN_EXT)=$(TMP_EXT)) |
| 44 | +TMPS := $(addprefix $(TMP_DIR),$(TMPS_NODIR)) |
| 45 | +OUT_BASENAME := $(OUT_BASENAME_NOEXT)$(OUT_EXT) |
| 46 | +OUT := $(OUT_DIR)$(OUT_BASENAME) |
| 47 | + |
| 48 | +.PHONY: all all-post assembler clean debug set_debug_flags help mkdir profile set_profile_flags test |
| 49 | + |
| 50 | +all: mkdir $(OUT) |
| 51 | + @#TODO ignore errors if not present |
| 52 | + @if [ -e "$(RUN_INPUT)" ] && [ ! -e "$(OUT_DIR)$(RUN_INPUT)" ]; then ln -s ../$(RUN_INPUT) "$(OUT_DIR)$(RUN_INPUT)"; fi |
| 53 | + @-$(MAKE) all-post |
| 54 | + |
| 55 | +$(OUT): $(TMPS) |
| 56 | + $(MYCXX) $(PROFILE_FLAGS) $^ -o "$@" $(LIBS) |
| 57 | + |
| 58 | +$(TMP_DIR)%$(TMP_EXT): $(IN_DIR)%.c |
| 59 | + $(MYCC) $(DEFINES) $(DEBUG_DEFINE) $(DEBUG_FLAGS) $(PROFILE_DEFINE) $(PROFILE_FLAGS) $(OPTIMIZE_FLAGS) $(PREDEF) $(INCLUDE_DIRS) $(MYCFLAGS) -c "$<" -o "$@" |
| 60 | + |
| 61 | +$(TMP_DIR)%$(TMP_EXT): $(IN_DIR)%.cpp |
| 62 | + $(MYCXX) $(DEFINES) $(DEBUG_DEFINE) $(DEBUG_FLAGS) $(PROFILE_DEFINE) $(PROFILE_FLAGS) $(OPTIMIZE_FLAGS) $(PREDEF) $(INCLUDE_DIRS) $(MYCXXFLAGS) -c "$<" -o "$@" |
| 63 | + |
| 64 | +$(TMP_DIR)%$(TMP_EXT): $(IN_DIR)%.f |
| 65 | + $(FF) $(DEFINES) $(DEBUG_DEFINE) $(DEBUG_FLAGS) $(PROFILE_DEFINE) $(PROFILE_FLAGS) $(OPTIMIZE_FLAGS) $(PREDEF) $(INCLUDE_DIRS) $(CFLAGS) -c "$<" -o "$@" |
| 66 | + |
| 67 | +asm: mkdir |
| 68 | + $(eval OPTIMIZE_FLAGS := -O0) |
| 69 | + $(MYCC) $(PROFILE_DEFINE) $(PROFILE_FLAGS) $(DEBUG_DEFINE) $(DEBUG_FLAGS) $(OPTIMIZE_FLAGS) $(CFLAGS) -fverbose-asm -Wa,-adhln "$(IN_DIR)$(RUN)$(IN_EXT)" $(LIBS) -o $(TMP_DIR)asm$(TMP_EXT) |
| 70 | + |
| 71 | +clean: |
| 72 | + rm -rf "$(TMP_DIR)" "$(OUT)" |
| 73 | + |
| 74 | +debug: clean set_debug_flags all |
| 75 | + gdb $(OUT) |
| 76 | + |
| 77 | +mkdir: |
| 78 | + mkdir -p "$(TMP_DIR)" "$(OUT_DIR)" |
| 79 | + |
| 80 | +profile: clean set_profile_flags all run |
| 81 | + mv -f gmon.out "$(OUT_DIR)" |
| 82 | + gprof -b $(OUT) "$(OUT_DIR)"gmon.out | tee "$(OUT).profile_out" | less |
| 83 | + |
| 84 | +set_debug_flags: |
| 85 | + $(eval DEBUG_FLAGS := -ggdb3) |
| 86 | + $(eval DEBUG_DEFINE := -DDEBUG) |
| 87 | + $(eval OPTIMIZE_FLAGS := -O0) |
| 88 | + |
| 89 | +set_profile_flags: |
| 90 | + $(eval PROFILE_FLAGS := -p -pg) |
| 91 | + $(eval PROFILE_DEFINE := -DPROFILE) |
| 92 | + #$(eval OPTIMIZE_FLAGS := ) |
| 93 | + |
| 94 | +run: all |
| 95 | + @echo |
| 96 | + cd $(OUT_DIR) && ./$(OUT_BASENAME) $(RUN_ARGS) |
| 97 | + |
| 98 | +test: all |
| 99 | + @echo |
| 100 | + if [ -x test ]; then ./test $(OUT_DIR) $(OUT_BASENAME); else $(MAKE) run && echo 'All tests passed.'; fi |
| 101 | + |
| 102 | +-include Makefile_targets |
| 103 | + |
| 104 | +help: |
| 105 | + @echo 'Compile all files with extension IN_EXT in directory IN_DIR into or into a single output file.' |
| 106 | + @echo '' |
| 107 | + @echo 'IN_EXT can be either of: `.cpp`, `.c` or `.f`. The compiler is chosen accordingly.' |
| 108 | + @echo '' |
| 109 | + @echo '# Most useful invocations' |
| 110 | + @echo '' |
| 111 | + @echo 'Build:' |
| 112 | + @echo '' |
| 113 | + @echo ' make' |
| 114 | + @echo '' |
| 115 | + @echo 'Build and run output:' |
| 116 | + @echo '' |
| 117 | + @echo ' make run' |
| 118 | + @echo '' |
| 119 | + @echo '# Targets' |
| 120 | + @echo '' |
| 121 | + @echo 'all ................. Build all.' |
| 122 | + @echo 'asm [RUN=name] ...... BROKEN Print generated assembly code for the file with given basename without extension.' |
| 123 | + @echo 'clean ............... Clean built files.' |
| 124 | + @echo 'debug ............... Run with `gdb`.' |
| 125 | + @echo 'help ................ Print help to stdout.' |
| 126 | + @echo 'profile ............. Run with `gprof`.' |
| 127 | + @echo 'run ................. Run a file with the given basename or the default not given.' |
| 128 | + @echo 'test ................ If `test` exists, run `./test <output-directory> <output-basename>`. Else check exit status == 0.' |
0 commit comments