mirror of
https://github.com/libretro/cpp-cheat.git
synced 2025-02-18 15:17:37 +00:00
182 lines
5.5 KiB
Plaintext
182 lines
5.5 KiB
Plaintext
# `make help` for documentation.
|
|
|
|
-include Makefile_params
|
|
|
|
# C/CPP
|
|
# Don't use the standard names like `CC` and `CXX` to avoid `?=` getting overridden.
|
|
# by the Makefile default values.
|
|
ALL_DEPEND ?=
|
|
MYCC ?= gcc
|
|
MYCXX ?= g++
|
|
G ?= gdb3
|
|
I ?= #-I/usr/include
|
|
O ?= 0
|
|
STD ?= c11
|
|
PEDANTIC ?= -pedantic-errors
|
|
CFLAGS ?= -g$(G) -march=native -O$(O) -pthread -std=$(STD) -Wall -Wextra $(PEDANTIC) $(CFLAGS_EXTRA) #-pg
|
|
MYCXXFLAGS ?= -g$(G) -march=native -O$(O) -pthread -std=c++17 -Wall -Wextra $(PEDANTIC) $(CXXFLAGS_EXTRA) #-pg
|
|
|
|
LIBS ?= -lm -lrt $(LIBS_EXTRA) #-lGL -lGLU -lglut
|
|
|
|
# Fortran
|
|
FF ?= gfortran
|
|
FFLIBS ?= #-l:lapack/liblapack.so
|
|
FFLAGS ?= -O$(O) -std=f2003 -Wextra $(PEDANTIC) $(FFLAGS_EXTRA)
|
|
|
|
# Paths
|
|
IN_DIR ?= ./
|
|
IN_EXTS ?= .c .cpp .f
|
|
# Unlike in Makefile_one, there is no TMP_DIR because there are no .o files generated.
|
|
OUT_DIR ?= ./
|
|
OUT_EXT ?= .out
|
|
OBJECT_EXT ?= .o
|
|
TMP_EXT ?= .tmp
|
|
TMP_PREF ?= tmp.
|
|
|
|
# Basename without extension of file to run on run target.
|
|
RUN ?= main
|
|
# If exists, will be symlinked into the same directory from which the executable will be run.
|
|
# This way, the executable can suppose that this file or directory is in the current directory.
|
|
RUN_INPUT ?= input
|
|
TEST ?= test
|
|
|
|
ASSEMBLER_NOEXT ?= $(IN_DIR)$(RUN)
|
|
|
|
RUN_BNAME := $(RUN)$(OUT_EXT)
|
|
|
|
INS := $(foreach IN_EXT, $(IN_EXTS), $(wildcard $(IN_DIR)*$(IN_EXT)))
|
|
INS_NODIR := $(notdir $(INS))
|
|
OUTS_NODIR_NOEXT := $(basename $(INS_NODIR))
|
|
OUTS_NOEXT := $(addprefix $(OUT_DIR), $(OUTS_NODIR_NOEXT))
|
|
OUTS := $(addsuffix $(OUT_EXT), $(OUTS_NOEXT))
|
|
|
|
.PHONY: all asm clean debug help mkdir objdump set_objdump_flags profile set_profile_flags test $(PHONY)
|
|
|
|
all: mkdir $(OUTS)
|
|
@#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
|
|
ifneq ($(strip $(run)),)
|
|
@echo
|
|
cd $(OUT_DIR) && ./"$(run)"
|
|
endif
|
|
|
|
$(OUT_DIR)%$(OUT_EXT): $(IN_DIR)%.c $(ALL_DEPEND)
|
|
$(MYCC) $(CFLAGS) $(PROFILE_DEFINE) $(PROFILE_FLAGS) $(I) -o "$@" "$<" $(LIBS)
|
|
|
|
$(OUT_DIR)%$(OUT_EXT): $(IN_DIR)%.cpp $(ALL_DEPEND)
|
|
$(MYCXX) $(MYCXXFLAGS) $(PROFILE_DEFINE) $(PROFILE_FLAGS) $(I) -o "$@" "$<" $(LIBS)
|
|
|
|
$(OUT_DIR)%$(OUT_EXT): $(IN_DIR)%.f $(ALL_DEPEND)
|
|
$(FF) $(FFLAGS) $(PROFILE_DEFINE) $(PROFILE_FLAGS) -o "$@" "$<" $(FFLIBS)
|
|
|
|
# Make assembly intermingled with original C code to stdout>
|
|
# TODO0: how not to rewrite the make rules?
|
|
# For bare asm: $(MYCC) $(PROFILE_DEFINE) $(PROFILE_FLAGS) $(CFLAGS) -fverbose-asm -S "$(ASSEMBLER_NOEXT)$$EXT"
|
|
asm: mkdir set_asm_flags
|
|
for EXT in $(IN_EXTS); do \
|
|
if [ -f "$(ASSEMBLER_NOEXT)$$EXT" ]; then \
|
|
case "$$EXT" in \
|
|
.c)\
|
|
$(MYCC) $(PROFILE_DEFINE) $(PROFILE_FLAGS) $(CFLAGS) -c -fverbose-asm -Wa,-adhln "$(ASSEMBLER_NOEXT)$$EXT" $(LIBS) -o $(OUT_DIR)asm.o\
|
|
;;\
|
|
.cpp)\
|
|
$(MYCXX) $(MYCXXFLAGS) $(PROFILE_DEFINE) $(PROFILE_FLAGS) -c -fverbose-asm -Wa,-adhln "$(ASSEMBLER_NOEXT)$$EXT" $(LIBS)\
|
|
;;\
|
|
.f)\
|
|
;;\
|
|
esac;\
|
|
break;\
|
|
fi;\
|
|
done
|
|
|
|
clean:
|
|
if [ ! '$(OUT_DIR)' = './' ]; then \
|
|
rm -rf '$(OUT_DIR)' ;\
|
|
else \
|
|
rm -rf *'$(OBJECT_EXT)' *'$(OUT_EXT)' *'$(TMP_EXT)' '$(TMP_PREF)'* callgrind.out.* ;\
|
|
fi
|
|
if [ -x 'clean' ]; then ./clean; fi
|
|
|
|
debug: clean set_debug_flags all
|
|
cd $(OUT_DIR) && gdb "$(RUN_BNAME)"
|
|
|
|
mkdir:
|
|
@mkdir -p "$(OUT_DIR)"
|
|
|
|
objdump: mkdir set_objdump_flags all
|
|
cd '$(OUT_DIR)' && objdump -CSr '$(RUN_BNAME)'
|
|
|
|
profile: clean set_profile_flags all run
|
|
cd '$(OUT_DIR)' && gprof -b '$(RUN_BNAME)' gmon.out | tee "$(RUN_BNAME).profile_out" | less
|
|
|
|
run: all
|
|
cd $(OUT_DIR) && ./$(RUN_BNAME)
|
|
|
|
time: all
|
|
cd $(OUT_DIR) && time -p ./$(RUN_BNAME)
|
|
|
|
set_profile_flags:
|
|
$(eval PROFILE_FLAGS := -p -pg)
|
|
$(eval PROFILE_DEFINE := -DPROFILE)
|
|
|
|
test: all
|
|
@\
|
|
if [ -x $(TEST) ]; then \
|
|
./$(TEST) '$(OUT_EXT)' ;\
|
|
else\
|
|
fail=false ;\
|
|
for t in *"$(OUT_EXT)"; do\
|
|
if ! ./"$$t"; then \
|
|
fail=true ;\
|
|
break ;\
|
|
fi ;\
|
|
done ;\
|
|
if $$fail; then \
|
|
echo "TEST FAILED: $$t" ;\
|
|
exit 1 ;\
|
|
else \
|
|
echo 'ALL TESTS PASSED' ;\
|
|
exit 0 ;\
|
|
fi ;\
|
|
fi ;\
|
|
|
|
-include Makefile_targets
|
|
|
|
help:
|
|
@echo 'Compiles C files with GCC, and C++ files with g++, Fortran files with gfortran one by one separatelly.'
|
|
@echo ''
|
|
@echo 'Executables have the same name without extension as the file that originated it:'
|
|
@echo ''
|
|
@echo ' c.c -> c'
|
|
@echo ' cpp.c -> cpp'
|
|
@echo ' fortran.f -> fortran'
|
|
@echo ''
|
|
@echo 'Therefore dont use files with the same basename without extension: e.g. `main.c` and `main.cpp`.'
|
|
@echo ''
|
|
@echo '# Most useful invocations'
|
|
@echo ''
|
|
@echo 'Build all:'
|
|
@echo ''
|
|
@echo ' make'
|
|
@echo ''
|
|
@echo 'Build and run output with the default basename:'
|
|
@echo ''
|
|
@echo ' make run'
|
|
@echo ''
|
|
@echo 'Build and run output with given basename:'
|
|
@echo ''
|
|
@echo ' make run=c'
|
|
@echo ''
|
|
@echo 'The `=` sign is *not* optional.'
|
|
@echo ''
|
|
@echo '# Targets'
|
|
@echo ''
|
|
@echo 'all ................. Build all.'
|
|
@echo 'asm [RUN=name] ...... 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[=name] .......... Run a file with the given basename withotu extension or the default not given.'
|
|
@echo 'test ................ Run `./test <output-directory> <output-basename> ...`'
|