Unverified Commit 31bd76ef authored by Richard Berger's avatar Richard Berger
Browse files

Merge remote-tracking branch 'origin/master' into zstd_support

parents 40ea0323 24f58076
Loading
Loading
Loading
Loading
+54 −36
Original line number Diff line number Diff line
@@ -15,75 +15,93 @@ if(BUILD_DOC)
    endif()
    set(VIRTUALENV ${Python3_EXECUTABLE} -m virtualenv -p ${Python3_EXECUTABLE})
  endif()
  find_package(Doxygen 1.8.10 REQUIRED)

  file(GLOB DOC_SOURCES ${LAMMPS_DOC_DIR}/src/[^.]*.rst)


  add_custom_command(
    OUTPUT docenv
    COMMAND ${VIRTUALENV} docenv
  )

  set(DOCENV_BINARY_DIR ${CMAKE_BINARY_DIR}/docenv/bin)
  set(DOCENV_REQUIREMENTS_FILE ${LAMMPS_DOC_DIR}/utils/requirements.txt)

  set(SPHINX_CONFIG_DIR ${LAMMPS_DOC_DIR}/utils/sphinx-config)
  set(SPHINX_CONFIG_FILE_TEMPLATE ${SPHINX_CONFIG_DIR}/conf.py.in)
  set(SPHINX_STATIC_DIR  ${SPHINX_CONFIG_DIR}/_static)

  # configuration and static files are copied to binary dir to avoid collisions with parallel builds
  set(DOC_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/doc)
  set(DOC_BUILD_CONFIG_FILE ${DOC_BUILD_DIR}/conf.py)
  set(DOC_BUILD_STATIC_DIR ${DOC_BUILD_DIR}/_static)
  set(DOXYGEN_BUILD_DIR ${DOC_BUILD_DIR}/doxygen)
  set(DOXYGEN_XML_DIR ${DOXYGEN_BUILD_DIR}/xml)

  # copy entire configuration folder to doc build directory
  # files in _static are automatically copied during sphinx-build, so no need to copy them individually
  file(COPY ${SPHINX_CONFIG_DIR}/ DESTINATION ${DOC_BUILD_DIR})

  # configure paths in conf.py, since relative paths change when file is copied
  configure_file(${SPHINX_CONFIG_FILE_TEMPLATE} ${DOC_BUILD_CONFIG_FILE})

  add_custom_command(
    OUTPUT requirements.txt
    DEPENDS docenv
    COMMAND ${CMAKE_COMMAND} -E copy ${LAMMPS_DOC_DIR}/utils/requirements.txt requirements.txt
    OUTPUT ${DOC_BUILD_DIR}/requirements.txt
    DEPENDS docenv ${DOCENV_REQUIREMENTS_FILE}
    COMMAND ${CMAKE_COMMAND} -E copy ${DOCENV_REQUIREMENTS_FILE} ${DOC_BUILD_DIR}/requirements.txt
    COMMAND ${DOCENV_BINARY_DIR}/pip install --upgrade pip
    COMMAND ${DOCENV_BINARY_DIR}/pip install --upgrade ${LAMMPS_DOC_DIR}/utils/converters
    COMMAND ${DOCENV_BINARY_DIR}/pip install --use-feature=2020-resolver -r requirements.txt --upgrade
    COMMAND ${DOCENV_BINARY_DIR}/pip install --use-feature=2020-resolver -r ${DOC_BUILD_DIR}/requirements.txt --upgrade
  )

  # download mathjax distribution and unpack to folder "mathjax"
  if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/mathjax/es5)
  if(NOT EXISTS ${DOC_BUILD_STATIC_DIR}/mathjax/es5)
    file(DOWNLOAD "https://github.com/mathjax/MathJax/archive/3.0.5.tar.gz"
      "${CMAKE_CURRENT_BINARY_DIR}/mathjax.tar.gz"
      EXPECTED_MD5 5d9d3799cce77a1a95eee6be04eb68e7)
    execute_process(COMMAND ${CMAKE_COMMAND} -E tar xzf mathjax.tar.gz WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
    file(GLOB MATHJAX_VERSION_DIR ${CMAKE_CURRENT_BINARY_DIR}/MathJax-*)
    execute_process(COMMAND ${CMAKE_COMMAND} -E rename ${MATHJAX_VERSION_DIR} ${CMAKE_CURRENT_BINARY_DIR}/mathjax)
    execute_process(COMMAND ${CMAKE_COMMAND} -E rename ${MATHJAX_VERSION_DIR} ${DOC_BUILD_STATIC_DIR}/mathjax)
  endif()
  file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/_static/mathjax)
  file(COPY ${CMAKE_CURRENT_BINARY_DIR}/mathjax/es5 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/html/_static/mathjax/)

  # for increased browser compatibility
  if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/html/_static/polyfill.js)
  if(NOT EXISTS ${DOC_BUILD_STATIC_DIR}/polyfill.js)
    file(DOWNLOAD "https://polyfill.io/v3/polyfill.min.js?features=es6"
      "${CMAKE_CURRENT_BINARY_DIR}/html/_static/polyfill.js")
      "${DOC_BUILD_STATIC_DIR}/polyfill.js")
  endif()

  # note, this may run in parallel with other tasks, so we must not use multiple processes here
  # set up doxygen and add targets to run it
  file(MAKE_DIRECTORY ${DOXYGEN_BUILD_DIR})
  file(COPY ${LAMMPS_DOC_DIR}/doxygen/lammps-logo.png DESTINATION ${DOXYGEN_BUILD_DIR}/lammps-logo.png)
  configure_file(${LAMMPS_DOC_DIR}/doxygen/Doxyfile.in ${DOXYGEN_BUILD_DIR}/Doxyfile)
  get_target_property(LAMMPS_SOURCES lammps SOURCES)
  add_custom_command(
    OUTPUT html
    DEPENDS ${DOC_SOURCES} docenv requirements.txt
    COMMAND ${DOCENV_BINARY_DIR}/sphinx-build -b html -c ${LAMMPS_DOC_DIR}/utils/sphinx-config -d ${CMAKE_BINARY_DIR}/doctrees ${LAMMPS_DOC_DIR}/src html
    COMMAND ${CMAKE_COMMAND} -E create_symlink Manual.html ${CMAKE_CURRENT_BINARY_DIR}/html/index.html
    OUTPUT ${DOXYGEN_XML_DIR}/index.xml
    DEPENDS ${DOC_SOURCES} ${LAMMPS_SOURCES}
    COMMAND Doxygen::doxygen ${DOXYGEN_BUILD_DIR}/Doxyfile WORKING_DIRECTORY ${DOXYGEN_BUILD_DIR}
    COMMAND ${CMAKE_COMMAND} -E touch ${DOXYGEN_XML_DIR}/run.stamp
  )

  # copy selected image files to html output tree
  file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/html/JPG)
  set(HTML_EXTRA_IMAGES balance_nonuniform.jpg balance_rcb.jpg
    balance_uniform.jpg bow_tutorial_01.png bow_tutorial_02.png
    bow_tutorial_03.png bow_tutorial_04.png bow_tutorial_05.png
    dump1.jpg dump2.jpg examples_mdpd.gif gran_funnel.png gran_mixer.png
    hop1.jpg hop2.jpg saed_ewald_intersect.jpg saed_mesh.jpg
    screenshot_atomeye.jpg screenshot_gl.jpg screenshot_pymol.jpg
    screenshot_vmd.jpg sinusoid.jpg xrd_mesh.jpg)
  set(HTML_IMAGE_TARGETS "")
  foreach(_IMG ${HTML_EXTRA_IMAGES})
    string(PREPEND _IMG JPG/)
    list(APPEND HTML_IMAGE_TARGETS "${CMAKE_CURRENT_BINARY_DIR}/html/${_IMG}")
  if(EXISTS ${DOXYGEN_XML_DIR}/run.stamp)
    set(SPHINX_EXTRA_OPTS "-E")
  else()
    set(SPHINX_EXTRA_OPTS "")
  endif()
  add_custom_command(
      OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/html/${_IMG}
      DEPENDS ${LAMMPS_DOC_DIR}/src/${_IMG} ${CMAKE_CURRENT_BINARY_DIR}/html/JPG
      COMMAND ${CMAKE_COMMAND} -E copy ${LAMMPS_DOC_DIR}/src/${_IMG} ${CMAKE_BINARY_DIR}/html/${_IMG}
    OUTPUT html
    DEPENDS ${DOC_SOURCES} docenv ${DOC_BUILD_DIR}/requirements.txt ${DOXYGEN_XML_DIR}/index.xml ${BUILD_DOC_CONFIG_FILE}
    COMMAND ${DOCENV_BINARY_DIR}/sphinx-build ${SPHINX_EXTRA_OPTS} -b html -c ${DOC_BUILD_DIR} -d ${DOC_BUILD_DIR}/doctrees ${LAMMPS_DOC_DIR}/src ${DOC_BUILD_DIR}/html
    COMMAND ${CMAKE_COMMAND} -E create_symlink Manual.html ${DOC_BUILD_DIR}/html/index.html
    COMMAND ${CMAKE_COMMAND} -E copy_directory ${LAMMPS_DOC_DIR}/src/PDF ${DOC_BUILD_DIR}/html/PDF
    COMMAND ${CMAKE_COMMAND} -E remove -f ${DOXYGEN_XML_DIR}/run.stamp
  )
  endforeach()

  add_custom_target(
    doc ALL
    DEPENDS html ${CMAKE_CURRENT_BINARY_DIR}/html/_static/mathjax/es5 ${HTML_IMAGE_TARGETS}
    DEPENDS html ${DOC_BUILD_STATIC_DIR}/mathjax/es5
    SOURCES ${LAMMPS_DOC_DIR}/utils/requirements.txt ${DOC_SOURCES}
  )

  install(DIRECTORY ${CMAKE_BINARY_DIR}/html DESTINATION ${CMAKE_INSTALL_DOCDIR})
  install(DIRECTORY ${DOC_BUILD_DIR}/html DESTINATION ${CMAKE_INSTALL_DOCDIR})
endif()
+1 −1
Original line number Diff line number Diff line
@@ -75,7 +75,7 @@ if(GPU_API STREQUAL "CUDA")
  endif()
  # Kepler (GPU Arch 3.5) is supported by CUDA 5 to CUDA 11
  if((CUDA_VERSION VERSION_GREATER_EQUAL "5.0") AND (CUDA_VERSION VERSION_LESS "12.0"))
    string(APPEND GPU_CUDA_GENCODE " -gencode arch=compute_30,code=[sm_30,compute_30] -gencode arch=compute_35,code=[sm_35,compute_35]")
    string(APPEND GPU_CUDA_GENCODE " -gencode arch=compute_35,code=[sm_35,compute_35]")
  endif()
  # Maxwell (GPU Arch 5.x) is supported by CUDA 6 and later
  if(CUDA_VERSION VERSION_GREATER_EQUAL "6.0")
+3 −3
Original line number Diff line number Diff line
@@ -35,8 +35,8 @@ if(DOWNLOAD_KOKKOS)
  list(APPEND KOKKOS_LIB_BUILD_ARGS "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}")
  include(ExternalProject)
  ExternalProject_Add(kokkos_build
    URL https://github.com/kokkos/kokkos/archive/3.1.01.tar.gz
    URL_MD5 3ccb2100f7fc316891e7dad3bc33fa37
    URL https://github.com/kokkos/kokkos/archive/3.2.00.tar.gz
    URL_MD5 81569170fe232e5e64ab074f7cca5e50
    CMAKE_ARGS ${KOKKOS_LIB_BUILD_ARGS}
    BUILD_BYPRODUCTS <INSTALL_DIR>/lib/libkokkoscore.a
  )
@@ -50,7 +50,7 @@ if(DOWNLOAD_KOKKOS)
  target_link_libraries(lammps PRIVATE LAMMPS::KOKKOS)
  add_dependencies(LAMMPS::KOKKOS kokkos_build)
elseif(EXTERNAL_KOKKOS)
  find_package(Kokkos 3.1.01 REQUIRED CONFIG)
  find_package(Kokkos 3.2.00 REQUIRED CONFIG)
  target_link_libraries(lammps PRIVATE Kokkos::kokkos)
else()
  set(LAMMPS_LIB_KOKKOS_SRC_DIR ${LAMMPS_LIB_SOURCE_DIR}/kokkos)
+7 −0
Original line number Diff line number Diff line
/old
/html
/html-offline
/epub
/latex
/mathjax
/spelling
@@ -10,3 +11,9 @@
/Developer.pdf
/doctrees
/docenv
/doxygen-warn.log
/utils/sphinx-config/conf.py
/doxygen/Doxyfile
*.el
/utils/sphinx-config/_static/mathjax
/utils/sphinx-config/_static/polyfill.js
+73 −49
Original line number Diff line number Diff line
@@ -4,20 +4,28 @@ SHELL = /bin/bash
BUILDDIR       = ${CURDIR}
RSTDIR         = $(BUILDDIR)/src
VENV           = $(BUILDDIR)/docenv
MATHJAX       = $(BUILDDIR)/mathjax
TXT2RST        = $(VENV)/bin/txt2rst
ANCHORCHECK    = $(VENV)/bin/rst_anchor_check
SPHINXCONFIG   = $(BUILDDIR)/utils/sphinx-config
MATHJAX        = $(SPHINXCONFIG)/_static/mathjax
POLYFILL       = $(SPHINXCONFIG)/_static/polyfill.js

PYTHON         = $(shell which python3)
DOXYGEN        = $(shell which doxygen)
VIRTUALENV     = virtualenv
HAS_PYTHON3    = NO
HAS_VIRTUALENV = NO
HAS_DOXYGEN    = NO
HAS_PDFLATEX   = NO

ifeq ($(shell which python3 >/dev/null 2>&1; echo $$?), 0)
HAS_PYTHON3    = YES
endif

ifeq ($(shell which doxygen >/dev/null 2>&1; echo $$?), 0)
HAS_DOXYGEN    = YES
endif

ifeq ($(shell which virtualenv-3 >/dev/null 2>&1; echo $$?), 0)
VIRTUALENV     = virtualenv-3
HAS_VIRTUALENV = YES
@@ -33,16 +41,20 @@ HAS_PDFLATEX = YES
endif


SPHINXEXTRA = -j $(shell $(PYTHON) -c 'import multiprocessing;print(multiprocessing.cpu_count())')
SPHINXEXTRA = -j $(shell $(PYTHON) -c 'import multiprocessing;print(multiprocessing.cpu_count())') $(shell test -f $(BUILDDIR)/doxygen/xml/run.stamp && printf -- "-E")

.PHONY: help clean-all clean clean-spelling epub mobi rst html pdf spelling anchor_check style_check
# grab list of sources from doxygen config file.
# we only want to use explicitly listed files.
DOXYFILES      = $(shell sed -n -e 's/\#.*$$//' -e '/^ *INPUT \+=/,/^[A-Z_]\+ \+=/p' doxygen/Doxyfile.in | sed -e 's/@LAMMPS_SOURCE_DIR@/..\/src/g' -e 's/\\//g' -e 's/ \+/ /' -e 's/[A-Z_]\+ \+= *\(YES\|NO\|\)//') 

.PHONY: help clean-all clean clean-spelling epub mobi rst html pdf spelling anchor_check style_check xmlgen

# ------------------------------------------

help:
	@echo "Please use \`make <target>' where <target> is one of"
	@echo "  html          create HTML doc pages in html dir"
	@echo "  pdf           create Developer.pdf and Manual.pdf in this dir"
	@echo "  pdf           create Manual.pdf in this dir"
	@echo "  fetch         fetch HTML and PDF files from LAMMPS web site"
	@echo "  epub          create ePUB format manual for e-book readers"
	@echo "  mobi          convert ePUB to MOBI format manual for e-book readers (e.g. Kindle)"
@@ -57,23 +69,32 @@ help:
# ------------------------------------------

clean-all: clean
	rm -rf $(BUILDDIR)/docenv $(BUILDDIR)/doctrees $(BUILDDIR)/mathjax Manual.pdf Developer.pdf
	rm -rf $(BUILDDIR)/docenv $(MATHJAX) $(BUILDDIR)/LAMMPS.mobi $(BUILDDIR)/LAMMPS.epub $(BUILDDIR)/Manual.pdf

clean: clean-spelling
	rm -rf html epub latex
	rm -rf $(BUILDDIR)/html $(BUILDDIR)/epub $(BUILDDIR)/latex $(BUILDDIR)/doctrees $(BUILDDIR)/doxygen/xml $(BUILDDIR)/doxygen-warn.log $(BUILDDIR)/doxygen/Doxyfile $(SPHINXCONFIG)/conf.py

clean-spelling:
	rm -rf spelling
	rm -rf $(BUILDDIR)/spelling

$(SPHINXCONFIG)/conf.py: $(SPHINXCONFIG)/conf.py.in
	sed -e 's,@DOXYGEN_XML_DIR@,$(BUILDDIR)/doxygen/xml,g'   \
	    -e 's,@LAMMPS_SOURCE_DIR@,$(BUILDDIR)/../src,g'    \
	    -e 's,@LAMMPS_PYTHON_DIR@,$(BUILDDIR)/../python,g' \
	    -e 's,@LAMMPS_DOC_DIR@,$(BUILDDIR),g' $< > $@

html: $(ANCHORCHECK) $(MATHJAX)
html: xmlgen $(SPHINXCONFIG)/conf.py $(ANCHORCHECK) $(MATHJAX) $(POLYFILL)
	@$(MAKE) $(MFLAGS) -C graphviz all
	@(\
		. $(VENV)/bin/activate ;\
		sphinx-build $(SPHINXEXTRA) -b html -c utils/sphinx-config -d $(BUILDDIR)/doctrees $(RSTDIR) html ;\
		. $(VENV)/bin/activate ; env PYTHONWARNINGS= \
		sphinx-build $(SPHINXEXTRA) -b html -c $(SPHINXCONFIG) -d $(BUILDDIR)/doctrees $(RSTDIR) html ;\
		ln -sf Manual.html html/index.html;\
		rm -f $(BUILDDIR)/doxygen/xml/run.stamp;\
		echo "############################################" ;\
		rst_anchor_check src/*.rst ;\
		python utils/check-packages.py -s ../src -d src ;\
		python $(BUILDDIR)/utils/check-packages.py -s ../src -d src ;\
		env LC_ALL=C grep -n '[^ -~]' $(RSTDIR)/*.rst ;\
		python utils/check-styles.py -s ../src -d src ;\
		python $(BUILDDIR)/utils/check-styles.py -s ../src -d src ;\
		echo "############################################" ;\
		deactivate ;\
	)
@@ -82,30 +103,28 @@ html: $(ANCHORCHECK) $(MATHJAX)
	@rm -rf html/USER
	@rm -rf html/JPG
	@cp -r src/PDF html/PDF
	@mkdir -p html/JPG
	@cp `grep -A2 '\.\. .*\(image\|figure\)::' src/*.rst | grep ':target: JPG' | sed -e 's,.*:target: JPG/,src/JPG/,' | sort | uniq` html/JPG/
	@rm -rf html/PDF/.[sg]*
	@mkdir -p html/_static/mathjax
	@cp -r $(MATHJAX)/es5 html/_static/mathjax/
	@echo "Build finished. The HTML pages are in doc/html."

spelling: $(VENV) utils/sphinx-config/false_positives.txt
spelling: xmlgen $(VENV) $(SPHINXCONFIG)/false_positives.txt
	@(\
		. $(VENV)/bin/activate ;\
		cp utils/sphinx-config/false_positives.txt $(RSTDIR)/ ; env PYTHONWARNINGS= \
		sphinx-build -b spelling -c utils/sphinx-config -d $(BUILDDIR)/doctrees $(RSTDIR) spelling ;\
		. $(VENV)/bin/activate ; env PYTHONWARNINGS= \
		cp $(SPHINXCONFIG)/false_positives.txt $(RSTDIR)/ ; env PYTHONWARNINGS= \
		sphinx-build -b spelling -c $(SPHINXCONFIG) -d $(BUILDDIR)/doctrees $(RSTDIR) spelling ;\
		rm -f $(BUILDDIR)/doxygen/xml/run.stamp;\
		deactivate ;\
	)
	@echo "Spell check finished."

epub: $(VENV)
epub: xmlgen $(VENV) $(SPHINXCONFIG)/conf.py $(ANCHORCHECK)
	@$(MAKE) $(MFLAGS) -C graphviz all
	@mkdir -p epub/JPG
	@rm -f LAMMPS.epub
	@cp src/JPG/lammps-logo.png epub/
	@cp src/JPG/*.* epub/JPG
	@(\
		. $(VENV)/bin/activate ;\
		sphinx-build $(SPHINXEXTRA) -b epub -c utils/sphinx-config -d $(BUILDDIR)/doctrees $(RSTDIR) epub ;\
		sphinx-build $(SPHINXEXTRA) -b epub -c $(SPHINXCONFIG) -d $(BUILDDIR)/doctrees $(RSTDIR) epub ;\
		rm -f $(BUILDDIR)/doxygen/xml/run.stamp;\
		deactivate ;\
	)
	@mv  epub/LAMMPS.epub .
@@ -117,18 +136,13 @@ mobi: epub
	@ebook-convert LAMMPS.epub LAMMPS.mobi
	@echo "Conversion finished. The MOBI manual file is created."

pdf: $(ANCHORCHECK)
pdf: xmlgen $(VENV) $(SPHINXCONFIG)/conf.py $(ANCHORCHECK)
	@$(MAKE) $(MFLAGS) -C graphviz all
	@if [ "$(HAS_PDFLATEX)" == "NO" ] ; then echo "PDFLaTeX was not found! Please check README.md for further instructions" 1>&2; exit 1; fi
	@(\
		cd src/Developer; \
		pdflatex developer; \
		pdflatex developer; \
		mv developer.pdf ../../Developer.pdf; \
		cd ../../; \
	)
	@(\
		. $(VENV)/bin/activate ;\
		sphinx-build $(SPHINXEXTRA) -b latex -c utils/sphinx-config -d $(BUILDDIR)/doctrees $(RSTDIR) latex ;\
		. $(VENV)/bin/activate ; env PYTHONWARNINGS= \
		sphinx-build $(SPHINXEXTRA) -b latex -c $(SPHINXCONFIG) -d $(BUILDDIR)/doctrees $(RSTDIR) latex ;\
		rm -f $(BUILDDIR)/doxygen/xml/run.stamp;\
		echo "############################################" ;\
		rst_anchor_check src/*.rst ;\
		python utils/check-packages.py -s ../src -d src ;\
@@ -154,12 +168,11 @@ pdf: $(ANCHORCHECK)
	@rm -rf latex/USER
	@cp -r src/PDF latex/PDF
	@rm -rf latex/PDF/.[sg]*
	@echo "Build finished. Manual.pdf and Developer.pdf are in this directory."
	@echo "Build finished. Manual.pdf is in this directory."

fetch:
	@rm -rf html_www Manual_www.pdf Developer_www.pdf
	@rm -rf html_www Manual_www.pdf
	@curl -s -o Manual_www.pdf http://lammps.sandia.gov/doc/Manual.pdf
	@curl -s -o Developer_www.pdf http://lammps.sandia.gov/doc/Developer.pdf
	@curl -s -o lammps-doc.tar.gz http://lammps.sandia.gov/tars/lammps-doc.tar.gz
	@tar xzf lammps-doc.tar.gz
	@rm -f lammps-doc.tar.gz
@@ -185,21 +198,32 @@ package_check : $(VENV)
		deactivate ;\
	)

xmlgen : doxygen/xml/index.xml

doxygen/Doxyfile: doxygen/Doxyfile.in
	sed -e 's/@LAMMPS_SOURCE_DIR@/..\/..\/src/g' $< > $@

doxygen/xml/index.xml : $(VENV) doxygen/Doxyfile $(DOXYFILES)
	@(cd doxygen; $(DOXYGEN) Doxyfile && touch xml/run.stamp)
# ------------------------------------------

$(VENV):
	@if [ "$(HAS_PYTHON3)" == "NO" ] ; then echo "Python3 was not found! Please check README.md for further instructions" 1>&2; exit 1; fi
	@if [ "$(HAS_VIRTUALENV)" == "NO" ] ; then echo "virtualenv was not found! Please check README.md for further instructions" 1>&2; exit 1; fi
	@if [ "$(HAS_PYTHON3)" == "NO" ] ; then echo "python3 was not found! Please see README for further instructions" 1>&2; exit 1; fi
	@if [ "$(HAS_DOXYGEN)" == "NO" ] ; then echo "doxygen was not found! Please see README for further instructions" 1>&2; exit 1; fi
	@if [ "$(HAS_VIRTUALENV)" == "NO" ] ; then echo "virtualenv was not found! Please see README for further instructions" 1>&2; exit 1; fi
	@( \
		$(VIRTUALENV) -p $(PYTHON) $(VENV); \
		. $(VENV)/bin/activate; \
		pip install --upgrade pip; \
		pip install --use-feature=2020-resolver -r requirements.txt; \
		pip install --use-feature=2020-resolver -r $(BUILDDIR)/utils/requirements.txt; \
		deactivate;\
	)

$(MATHJAX):
	@git clone --depth 1 https://github.com/mathjax/MathJax.git mathjax
	@git clone --depth 1 https://github.com/mathjax/MathJax.git $@

$(POLYFILL): $(MATHJAX)
	@curl -s -o $@ "https://polyfill.io/v3/polyfill.min.js?features=es6"

$(TXT2RST) $(ANCHORCHECK): $(VENV)
	@( \
Loading