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