python_version=3.8

# $@ is the target list
# $< is the input
# $* is the basename of something

%.so: %.m4
	#
	# Create the pure python file
	m4 --define=purepy=1 < $*.m4 | sed 's/^import \([a-z]*sort\)$$/import \1_py as \1/' > $*_py.py
	# create something without @profile's for pylint
	sed 's/@profile//' < $*_py.py > $*_for_linting.py
	# pylint the file for correctness!
	./this-pylint --which-2 None --ignore-message '.*Too many lines in module' --to-pylint $*_for_linting.py 
	# clean up
	#rm -f $*_for_linting.py
	# Now we start on the fast version - .pyx
	# create the pyx file
	m4 --define=m4pyx=1 < $*.m4 > $*.pyx
	# create the .c file from the .pyx
	/usr/local/cpython-${python_version}/bin/cython $*.pyx
	# clean up
	#rm -f $*.pyx
	# create the .o file from the .c
	gcc -O3 -fPIC -I /usr/local/cpython-$(python_version)/include/python$(python_version)* -c -o $*.o $*.c
	# clean up
	rm -f $*.c
	# create the .so file from the .o
	$(CC) -shared $*.o -o $*.so

go: insertionsort.so binarysort.so funnelsort.so quicksort.so bubblesort.so shellsort.so mergesort.so timsort_reimp.so radixsort.so
	rm -f *.dat
	# this does a line-resolution profiling, if you decorate relevant functions with @profile
	#kernprof.py -l -v ./test-funnelsort
	./this-pylint --which-2 None --to-pylint performance-tests
	/usr/local/cpython-${python_version}/bin/python3 ./performance-tests

go2: test-smallsorts funnelsort_py.py funnelsort.so
	kernprof.py -l -v ./test-smallsorts

go3: timsort_reimp.so
	./test-timsort_reimp

dats=brief_mergesort.dat brief_shellsort.dat brief_bubblesort.dat brief_binarysort.dat brief_insertionsort.dat brief_funnelsort.dat brief_timsort.dat brief_quicksort.dat brief_timsort_cext.dat brief_radixsort.dat brief_cheat_O(n).dat
graph.pdf: graph-pdf.gp $(dats)
	gnuplot graph-pdf.gp

clean:
	rm -f *.dat *.ps *.pdf *.pyx *.c *.so *.o *_for_linting.py *_py.py *.lprof *.pyc
	rm -f *_for_linting.py
	rm -rf __pycache__