diff --git a/.github/workflows/main-aarch64.yml b/.github/workflows/main-aarch64.yml index 7100dd25..2eeb84e1 100644 --- a/.github/workflows/main-aarch64.yml +++ b/.github/workflows/main-aarch64.yml @@ -15,7 +15,8 @@ jobs: - name: Get Dependencies run: | sudo apt-get update - sudo apt-get install -y tcl-dev tk-dev libcairo-dev + sudo apt-get install -y tcl-dev tk-dev libcairo-dev \ + texlive-latex-base texlive-latex-recommended texlive-fonts-recommended - name: Build run: | ./configure diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bd8a36cf..2d585eba 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,7 +13,12 @@ jobs: - name: Get Dependencies run: | sudo apt-get update - sudo apt-get install -y tcl-dev tk-dev libcairo-dev + # tcl/tk + cairo for the build; texlive (latex + dvips) so the default + # "make" also regenerates the PostScript documentation. Docs are + # best-effort — a missing texlive package just falls back to the + # pre-built PostScript, it does not fail the build. + sudo apt-get install -y tcl-dev tk-dev libcairo-dev \ + texlive-latex-base texlive-latex-recommended texlive-fonts-recommended - name: Build run: | ./configure diff --git a/.gitignore b/.gitignore index 22b66957..cb8812c6 100644 --- a/.gitignore +++ b/.gitignore @@ -78,3 +78,10 @@ npm/examples/output/ .claudeignore CLAUDE.md CLAUDE.local.md +# LaTeX documentation build artifacts (an in-tree "make" regenerates the +# PostScript here when latex+dvips are installed; out-of-tree these live in the +# build dir instead). The pre-built PostScript under doc/psfiles/ stays tracked. +doc/latexfiles/psfiles/ +doc/latexfiles/*.dvi +doc/latexfiles/*.aux +doc/latexfiles/*.log diff --git a/Makefile.in b/Makefile.in index 353d0df2..ac25a365 100644 --- a/Makefile.in +++ b/Makefile.in @@ -23,7 +23,11 @@ INSTALL_CAD_DIRS = windows doc ${TECHS} -include defs.mak -all: $(ALL_TARGET) techs +# "docs" when configure found latex+dvips (regenerate PostScript from .tex into +# the build tree), empty otherwise (the pre-built PostScript is installed as-is). +DOCS_TARGET = @DOCS_TARGET@ + +all: $(ALL_TARGET) techs $(DOCS_TARGET) standard: mains @@ -103,6 +107,15 @@ techs: depend for dir in ${TECHS}; do \ mkdir -p $$dir && ${MAKE} -C $$dir -f ${MAGICSRC}/$$dir/Makefile all || exit 1; done +# Regenerate the PostScript documentation from its .tex sources (only reached +# from "all" when configure found latex+dvips; see DOCS_TARGET). +.PHONY: docs +docs: + @echo --- making documentation + @mkdir -p doc/latexfiles + @${MAKE} -k -C doc/latexfiles -f ${MAGICSRC}/doc/latexfiles/Makefile all || \ + echo "--- WARNING: some documents did not regenerate; the pre-built PostScript will be used for those at 'make install'" + install: $(INSTALL_TARGET) install-magic: diff --git a/README.Tcl b/README.Tcl index 58f65c79..1375d2da 100644 --- a/README.Tcl +++ b/README.Tcl @@ -27,6 +27,17 @@ read these instructions first. the IRSIM module is not selected at compile-time; in Tcl it is a run-time loadable module. + Optional (documentation): to regenerate the PostScript documentation + from its LaTeX sources you need "latex" and "dvips". On Debian/Ubuntu + these come from the TeX Live packages texlive-latex-base, + texlive-latex-recommended, and texlive-fonts-recommended. When + "configure" finds both tools it prints "LaTeX docs: yes" in its summary + and the default "make" regenerates the docs into the build tree. If the + tools are absent (or a particular document fails to typeset), the + pre-built PostScript shipped in the source tree is installed as-is, so + documentation is always available either way -- installing latex simply + refreshes it from source. + 2) At the top level, do "./configure" and any other options (such as "--prefix=DIR" for non-default installation location). "prefix" determines the value $CAD_ROOT, which is set to ${prefix}/lib, diff --git a/doc/latexfiles/Makefile b/doc/latexfiles/Makefile index 86c70fca..21b664a4 100644 --- a/doc/latexfiles/Makefile +++ b/doc/latexfiles/Makefile @@ -49,19 +49,24 @@ $(DESTDIR)${PS_INSTDIR}/%: $(DESTDIR)${PS_INSTDIR} ${CP} $$f $(DESTDIR)${PS_INSTDIR}/$* # Regenerate a .ps (into the build tree) from its .tex (in the source tree). +# Several .tex include figures as ../psfigures/*.ps (relative to this dir). +# Out-of-tree that would resolve into the empty build tree, so point the +# build-tree ../psfigures at the source copy (a no-op in-tree, where it already +# exists); both latex and dvips then find the figures, outputs stay in-build. ${PS_GENDIR}/%.ps: %.tex @mkdir -p ${PS_GENDIR} + @test -e ../psfigures || ln -s ${MAGICSRC}/doc/psfigures ../psfigures @echo "Converting $*.tex -> $*.dvi" - @TEXINPUTS=$(srcdir): latex $(srcdir)/$*.tex < /dev/null > /dev/null + @TEXINPUTS=$(srcdir): ${LATEX} $(srcdir)/$*.tex < /dev/null > /dev/null @if grep 'LaTeX Warn' $*.log; \ then \ echo "Detected warnings, doing second pass for $*...";\ - TEXINPUTS=$(srcdir): latex $(srcdir)/$*.tex < /dev/null > /dev/null; \ + TEXINPUTS=$(srcdir): ${LATEX} $(srcdir)/$*.tex < /dev/null > /dev/null; \ (grep 'LaTeX Warn' $*.log || (echo > /dev/null)); \ echo; \ fi @echo "Converting $*.dvi -> ${PS_GENDIR}/$*.ps" - @dvips -t letter $*.dvi -o ${PS_GENDIR}/$*.ps > /dev/null + @${DVIPS} -t letter $*.dvi -o ${PS_GENDIR}/$*.ps > /dev/null clean: ${RM} $(GENDVI) $(GEN_GENPS) *.log *.aux diff --git a/scripts/configure b/scripts/configure index 1f9b5368..7dfa7d2a 100755 --- a/scripts/configure +++ b/scripts/configure @@ -682,6 +682,9 @@ X_PRE_LIBS X_CFLAGS XMKMF PYTHON3 +DOCS_TARGET +DVIPS +LATEX GCORE ALLOCA EGREP @@ -6314,6 +6317,97 @@ fi +# Extract the first word of "latex", so it can be a program name with args. +set dummy latex; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_LATEX+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $LATEX in + [\\/]* | ?:[\\/]*) + ac_cv_path_LATEX="$LATEX" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_LATEX="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_LATEX" && ac_cv_path_LATEX="no" + ;; +esac +fi +LATEX=$ac_cv_path_LATEX +if test -n "$LATEX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LATEX" >&5 +$as_echo "$LATEX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +# Extract the first word of "dvips", so it can be a program name with args. +set dummy dvips; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_DVIPS+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $DVIPS in + [\\/]* | ?:[\\/]*) + ac_cv_path_DVIPS="$DVIPS" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_DVIPS="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_DVIPS" && ac_cv_path_DVIPS="no" + ;; +esac +fi +DVIPS=$ac_cv_path_DVIPS +if test -n "$DVIPS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DVIPS" >&5 +$as_echo "$DVIPS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test "x${LATEX}" != "xno" -a "x${DVIPS}" != "xno" ; then + DOCS_TARGET="docs" +else + DOCS_TARGET="" +fi + + + + # Extract the first word of "python3", so it can be a program name with args. set dummy python3; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -10578,6 +10672,13 @@ else fi fi +${ECHO_N} "LaTeX docs: " +if test "x${DOCS_TARGET}" != "x" ; then + echo "yes" +else + echo "no (install 'latex' and 'dvips' to regenerate documentation)" +fi + echo "-----------------------------------------------------------" echo echo "Use 'make' to compile and 'make install' to install." diff --git a/scripts/configure.in b/scripts/configure.in index 8fc89cb5..a703cdc1 100644 --- a/scripts/configure.in +++ b/scripts/configure.in @@ -359,6 +359,21 @@ dnl Check for gcore, used by niceabort.c AC_PATH_PROG(GCORE, gcore, [no]) +dnl LaTeX + dvips are optional. When both are present the default "make" +dnl regenerates the PostScript documentation (doc/latexfiles) from the .tex +dnl sources into the build tree. When either is missing, the pre-built +dnl PostScript shipped in the source tree is installed as-is instead. +AC_PATH_PROG(LATEX, latex, no) +AC_PATH_PROG(DVIPS, dvips, no) +if test "x${LATEX}" != "xno" -a "x${DVIPS}" != "xno" ; then + DOCS_TARGET="docs" +else + DOCS_TARGET="" +fi +AC_SUBST(LATEX) +AC_SUBST(DVIPS) +AC_SUBST(DOCS_TARGET) + dnl Python3 is preferred for running the preprocessor script dnl but CPP can be used instead. AC_PATH_PROG([PYTHON3], [python3], [no]) @@ -2094,6 +2109,13 @@ else fi fi +${ECHO_N} "LaTeX docs: " +if test "x${DOCS_TARGET}" != "x" ; then + echo "yes" +else + echo "no (install 'latex' and 'dvips' to regenerate documentation)" +fi + echo "-----------------------------------------------------------" echo echo "Use 'make' to compile and 'make install' to install." diff --git a/scripts/defs.mak.in b/scripts/defs.mak.in index 2388d12e..d64b1627 100755 --- a/scripts/defs.mak.in +++ b/scripts/defs.mak.in @@ -94,6 +94,8 @@ LD = @LD@ MKDIR = mkdir PERL = @PERL@ SED = @SED@ +LATEX = @LATEX@ +DVIPS = @DVIPS@ MCPP = @MCPP@ MSED = @MSED@ RANLIB = @RANLIB@