Makefile 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. PYTHON ?= "python3"
  2. export EMACS ?= $(shell command -v emacs 2>/dev/null)
  3. CASK ?= $(shell which cask || echo ${HOME}/.local/bin/cask)
  4. CLANGFORMAT := clang-format
  5. .PHONY: all clean clean_bin clean_cask test_module_assertions test test_ert test_formatting test_valgrind
  6. HARDENING_FLAGS := -fstack-protector -fstack-clash-protection -fcf-protection \
  7. -D_FORTIFY_SOURCE=2 -ftrapv -Wformat=2 -Wjump-misses-init
  8. OPTIMALISATION_FLAGS := -O2
  9. UNAME_S := $(shell uname -s)
  10. ifeq ($(UNAME_S), Darwin) # Clang does not support some gcc options
  11. GCC_NO_WARN=-Wno-unused-command-line-argument
  12. HARDENING_FLAGS=
  13. ifeq (, $(shell which ${CLANGFORMAT}))
  14. CLANGFORMAT := true # darwin form gh CI have no clang-format
  15. endif
  16. endif
  17. ifeq (, $(shell which pkg-config))
  18. $(error "No pkg-config found.")
  19. endif
  20. all: emacspy-module.so
  21. CASK_DIR := $(shell ${CASK} package-directory)
  22. $(CASK_DIR): Cask
  23. ${CASK} install
  24. @touch $(CASK_DIR)
  25. cask: $(CASK_DIR)
  26. IS_PYTHON_OLD := $(shell ${PYTHON} -c 'import platform;from packaging import version as v; \
  27. print("-DPYTHON311OLDER") if (v.parse(platform.python_version()) < v.parse("3.12.0")) else exit(0)')
  28. emacspy.c: emacspy.pyx
  29. cython emacspy.pyx
  30. # https://github.com/grisha/mod_python/issues/81#issuecomment-551655070
  31. emacspy-module.so: BLDLIBRARY=$(shell ${PYTHON} -c \
  32. 'import sysconfig; print(sysconfig.get_config_var("BLDLIBRARY"))')
  33. emacspy-module.so: PKGCONFIG_PATH=$(shell ${PYTHON} -c \
  34. 'import sysconfig; print(sysconfig.get_config_var("LIBPC"))')
  35. emacspy-module.so: LIBPYTHON_NAME=$(shell ${PYTHON} -c \
  36. 'import sysconfig; print(sysconfig.get_config_var("LDLIBRARY"))')
  37. emacspy-module.so: BASE_PREFIX=$(shell ${PYTHON} -c \
  38. 'import sys; print(sys.base_prefix)')
  39. emacspy-module.so: emacspy.c stub.c subinterpreter.c
  40. gcc -fPIC -g -DCYTHON_FAST_THREAD_STATE=0 -DCYTHON_PEP489_MULTI_PHASE_INIT=0 \
  41. ${IS_PYTHON_OLD} -DBASE_PREFIX=L\"${BASE_PREFIX}\" \
  42. -Wall -Wextra -Werror ${OPTIMALISATION_FLAGS} ${HARDENING_FLAGS} ${GCC_NO_WARN} \
  43. emacspy.c stub.c \
  44. ${BLDLIBRARY} -DLIBPYTHON_NAME=\"${LIBPYTHON_NAME}\" \
  45. -shared $(shell pkg-config --cflags --libs $(PKGCONFIG_PATH)"/python3-embed.pc") \
  46. -o emacspy-module.so
  47. clean_bin:
  48. rm -vf emacspy.c emacspy-module.so
  49. clean_cask:
  50. rm -vfr .cask
  51. clean: clean_cask clean_bin
  52. test: test_ert test_formatting
  53. test_ert: cask all
  54. ulimit -c unlimited; ${CASK} emacs -batch -l tests/prepare-tests.el -l ert -l tests/test.el \
  55. -f ert-run-tests-batch-and-exit
  56. # https://stackoverflow.com/questions/20112989/how-to-use-valgrind-with-python
  57. test_valgrind: OPTIMALISATION_FLAGS=
  58. test_valgrind: clean all .valgrind-python.supp
  59. PYTHONMALLOC=malloc valgrind --tool=memcheck --suppressions=.valgrind-python.supp \
  60. --leak-check=full --show-leak-kinds=all \
  61. ${CASK} emacs -batch -l tests/prepare-tests.el -l ert -l tests/test.el \
  62. -f ert-run-tests-batch-and-exit
  63. .valgrind-python.supp:
  64. wget -O .valgrind-python.supp \
  65. "https://raw.githubusercontent.com/python/cpython/main/Misc/valgrind-python.supp"
  66. echo "WARNING: Read instructions from top of .valgrind-python.supp"
  67. false
  68. test_formatting:
  69. ${CLANGFORMAT} --dry-run --Werror stub.c subinterpreter.c
  70. test_module_assertions: emacspy-module.so
  71. ${CASK} emacs --batch --module-assertions --eval \
  72. '(progn (add-to-list '\''load-path ".") (load "emacspy"))'