Commit Graph

83 Commits

Author SHA1 Message Date
Darryl L. Miles 5e8b81cbcc build: remove bundled-readline wiring from the Makefiles (Patch 2)
With the bundled fallback gone (Patch 1) the readline/ special-casing is dead
machinery.  Remove it:

  * Makefile.in: $(submake) drops the `= readline` `-f`/mkdir branch and is now
    plain `$(MAKE) -C <dir> <goal>`; the clean loop drops its matching branch;
    `readline` is removed from BUNDLED_MODULES.
  * scripts/defs.mak.in: remove the `ifeq (@MAKE_READLINE@,1) -I${MAGICSRC}/
    readline` block (system readline headers are on the standard search path) and
    the MAKE_READLINE variable; tidy the srcdir-fallback comment (only the
    top-level Makefile uses it now).
  * scripts/configure.in: drop AC_SUBST(MAKE_READLINE); regenerate configure.

The system readline link flags (rl_libs = -lreadline via READLINE_LIBS) are
unchanged.  readline/ itself is deleted in the next patch.

Verified: no unsubstituted @MAKE_READLINE@; Tcl -j12 builds+installs 375 files
with readline/ not built; --without-tcl --disable-readline -j12 builds (x2).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 14:54:11 -04:00
Darryl L. Miles c05ac60851 build: require system readline (or Tcl); drop the bundled fallback (Patch 1)
configure already preferred the system readline (AC_CHECK_LIB → -lreadline) and
only fell back to the bundled readline/ copy.  Remove that fallback: a non-Tcl
interactive build now requires the *system* GNU readline -- both its header
(AC_CHECK_HEADER readline/readline.h, so configure fails cleanly instead of deep
in compilation) and the library -- and if neither Tcl nor readline is available
configure errors with a clear explanation of the three ways forward (build with
Tcl, install libreadline-dev, or --disable-readline).

Also drop the now-meaningless --enable-readline-bundled, and substitute
MAKE_READLINE=0 unconditionally so the Makefiles' bundled-readline path goes
inert.  readline/ and all Makefiles are left untouched here (cleaned up and
removed in the following patches).

--disable-readline stays as the escape hatch: it just tells configure to ignore
the system readline and build the existing no-line-editing variant.

Verified: Tcl build rc=0 (readline off, 375 files, readline/ not built); non-Tcl
--disable-readline builds (serial); non-Tcl default with no readline dev package
now errors with the guidance message.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 14:54:11 -04:00
Darryl L. Miles 25fa181200 build: detect GNU/BSD date at configure time for SOURCE_DATE_EPOCH
The SOURCE_DATE_EPOCH -> date conversion previously relied on a runtime
`date -u -d @EPOCH 2>/dev/null || date -u -r EPOCH` fallback.  That is
unreliable on macOS/*BSD: BSD `date -d` reads -d as a DST flag and silently
prints the wrong time (exit 0), so the `-r` fallback is never reached.

Decide at configure time instead: prefer coreutils `gdate` (GNU date, e.g.
installed on macOS), else a native `date` that really is GNU (verified by the
epoch-0 output containing 1970), else BSD `date -r`.  configure substitutes the
chosen invocation as @SOURCE_DATE_CMD@ and defs.mak appends the epoch.

Verified on Linux (no gdate -> GNU `date -u -d @`): a fixed SOURCE_DATE_EPOCH
yields a byte-identical buildinfo.o across builds; the no-epoch path still
stamps the current local time.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 14:54:11 -04:00
Darryl L. Miles 1bc8537b5d build: per-file automatic dependencies (.deps), retire the Depend/sed machinery
Replace the monolithic per-directory `Depend` file -- generated by a separate,
serial `make depend` pass (one `gcc -MM` over all sources) and post-processed by
sed -- with automake-style per-file dependency fragments produced as a side
effect of each compile.

rules.mak's %.o rule now adds, when the compiler supports it,
  -MMD -MP -MF .deps/<stem>.d
so every object records the (non-system) headers it used.  Those fragments are
`-include`d best-effort: absent on a first build, present and correct after.
Benefits:
  * self-maintaining -- no explicit depend step; deps refresh on every compile;
  * parallel -- generated during the (already parallel) compile, no barrier;
  * -MMD already drops system headers (what the sed did) and -MP tolerates a
    removed/renamed header, so the sed post-processing is gone;
  * fixes out-of-tree incremental header tracking: with an absolute srcdir the
    old sed stripped the now-absolute *local* header paths too, silently losing
    them; the .d files keep them.

configure probes `-MMD -MP` (AUTODEP_FLAGS; empty and best-effort-skipped if the
compiler cannot).  clean/distclean remove .deps (rm -r); .gitignore replaces the
obsolete */Depend with .deps/.  `make depend` is kept as a no-op for callers that
still invoke it (e.g. the WASM build script).

Verified out-of-tree (--disable-ccache): 324 .d files, 0 Depend files, a header
touch recompiles its dependents, no-op rebuild is idle, clean clears .deps.  (The
top-level depend phase still runs here as a no-op; removed next.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 14:54:11 -04:00
Darryl L. Miles 64614da7a0 build: --enable-ccache-prefix-map for cross-tree ccache sharing
The out-of-tree build puts absolute source-root paths on the command line
(-I${MAGICSRC}, -I${srcdir}, the source file itself), which are part of
ccache's key -- so same-tree rebuilds hit (proven) but different checkouts /
build dirs do not share cache.

New opt-in configure --enable-ccache-prefix-map adds
  -ffile-prefix-map=${MAGICSRC}=.
to CFLAGS (requires ccache; the flag is probed for GCC-8+/clang support and
skipped with a warning otherwise).  This relativizes the source paths embedded
in the compiled output (__FILE__, debug info) so a cached object is valid
regardless of which tree produced it.

Off by default: it makes debug paths relative, so gdb then needs
`set substitute-path . <srcdir>`.  It is only for cross-tree *correctness* and
must be paired with CCACHE_BASEDIR=<build top> in the environment for cross-tree
*hits* (that half normalizes the command-line paths in the hash; this half keeps
the cached output tree-neutral).  Same-tree caching needs neither.

Verified: default/--disable-ccache carry no -ffile-prefix-map;
--enable-ccache-prefix-map (probe "yes") adds it, and with --disable-ccache it
warns and is ignored.  Full build rc=0 (375 files); the installed tclmagic.so
contains zero absolute /work/magic paths.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 14:54:11 -04:00
Darryl L. Miles 5719a536e8 build: autodetect ccache (configure --disable-ccache to opt out)
When ccache is on PATH, prefix CC/CXX with it so every compile goes through
ccache -- no Makefile change, since rules.mak already runs `${CC} ... -c` and
defs.mak substitutes @CC@/@CXX@.  Autodetected on by default; --disable-ccache
opts out.

Placed after the AC_PROG_C* checks so configure's own feature tests use the
plain compiler and only the build picks up the prefix.  Pairs with the
build-info isolation (utils/buildinfo.c): with the volatile MAGIC_BUILDDATE on
only that one unit, a full rebuild hits the cache for every other unit.

Measured (default Tcl build, all objects deleted then rebuilt): 323/324 hits
with the date enabled (only buildinfo.o misses), 324/324 with
--disable-magic-builddate.

Verified: default configure -> CC="ccache gcc", CXX="ccache g++";
--disable-ccache -> CC="gcc".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 14:54:11 -04:00
Darryl L. Miles a9edf1a97d build: add --disable-magic-builddate (reproducible, ccache-stable builds)
New configure option --disable-magic-builddate omits the build date from the
binary.  It is wired via an AC_SUBST'd MAGIC_BUILDDATE_DEFS (not AC_DEFINE), so
it reaches only buildinfo.o rather than @DEFS@ / every command line:

  * enabled (default): buildinfo.o gets -DMAGIC_BUILDDATE="<date>" and defs.mak
    computes the date (SOURCE_DATE_EPOCH-aware);
  * disabled: buildinfo.o gets -DMAGIC_NO_BUILDDATE instead, defs.mak skips the
    date computation entirely (no parse-time `date` spawn), and buildinfo.c
    reports an empty MagicCompileTime.

This gives a fully reproducible build whose one volatile input (the date) is
gone; what remains in buildinfo.o is commit/version/revision, which do not
change second-to-second -- the intended pairing with ccache for day-to-day
development.

Verified both configs: default bakes the date + commit; --disable-magic-builddate
compiles buildinfo.o with -DMAGIC_NO_BUILDDATE (no date), commit still present.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 14:54:11 -04:00
Darryl L. Miles 2b4fcf5968 build: include rules.mak from source, drop the build-top copy
rules.mak has no @...@ substitutions, so there is no reason to copy it into
the build top.  Point all 38 subdir Makefile.in includes at the source copy
directly -- ${MAGICSRC}/rules.mak instead of ${MAGICDIR}/rules.mak -- and
remove AC_CONFIG_FILES([rules.mak:rules.mak]) from configure.  defs.mak (the
one make fragment with substitutions) remains the only generated file in the
build top.  readline/ and the top Makefile never included rules.mak, so they
are unaffected; AC_CONFIG_SRCDIR(rules.mak) (the srcdir sentinel) is kept.

Now editing rules.mak in the source tree takes effect without reconfiguring.

Verified rc=0, 375 files, both in-tree and out-of-tree; out-of-tree build
top has no rules.mak; distclean rc=0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 14:54:11 -04:00
Darryl L. Miles d2650e4833 build: convert nested children + rewire parent recursion to native
Convert the last nested children to Makefile.in and switch their parents
from the -f fallback to native recursion (they now have generated build
Makefiles).  Rename and rewire are one unit: a pure rename would break the
parent's -f path to the (now-.in) child.

Converted (5): scmos/cif_template, doc/man, doc/tutcells, doc/html,
doc/latexfiles.  Pure renames -- still build via the srcdir derivation;
@srcdir@ substitution follows.

Rewired to native `make -C <child>` (config.status now creates the child
build dirs + Makefiles):
* scmos/Makefile.in: cif_template build + clean.
* doc/Makefile.in: install/install-tcl over man/tutcells/html/latexfiles.
* Makefile.in: the docs: target -> `make -k -C doc/latexfiles all`.
The `mkdir -p` and `-f ${MAGICSRC}/.../Makefile` are dropped in each.

* configure.in: AC_CONFIG_FILES for the 5 children; regenerated configure.
* .gitignore: ignore each generated child Makefile, same commit.

Verified out-of-tree: full `make && make install` rc=0, 376 files --
scmos recurses natively into cif_template (8 objs), docs regenerate via
native doc/latexfiles (27/28), man pages install via native doc/man.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 14:54:11 -04:00
Darryl L. Miles 887eca61fe build: generate magic/tcltk/scmos/doc/lisp Makefiles from Makefile.in (rename unit)
Fourth batch of the Makefile.in migration: the top-level complex outliers
  magic tcltk scmos doc lisp
Pure renames -- content unchanged, so each still builds via the defs.mak
srcdir derivation; the @srcdir@ substitution follows.

Their nested children (scmos/cif_template and doc/{man,tutcells,html,
latexfiles}) are intentionally NOT converted here: scmos and doc recurse
into them with `-f ${MAGICSRC}/.../Makefile`, which keeps working only
while those children remain static Makefiles.  They convert in a later
step together with the parent-recursion updates.

* git mv <dir>/Makefile -> <dir>/Makefile.in (5 modules)
* configure.in: AC_CONFIG_FILES for each; regenerated configure.
* .gitignore: ignore each generated <dir>/Makefile, same commit.

Verified out-of-tree: full `make` rc=0 -- tclmagic.so, scmos techs (scmos
recurses into the static cif_template via -f, 8 objs), 27/28 docs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 14:54:11 -04:00
Darryl L. Miles fe70666b0c build: generate near-standard + outlier Makefiles from Makefile.in (rename unit)
Third batch of the Makefile.in migration: near-standard modules
(utils windows commands database) and the program/.so outliers
(lef plot router ext2spice ext2sim extcheck net2ir graphics oa).
Pure renames -- content unchanged, so each still builds via the defs.mak
srcdir derivation; the @srcdir@ substitution follows.

* git mv <dir>/Makefile -> <dir>/Makefile.in (13 modules)
* configure.in: AC_CONFIG_FILES for each; regenerated configure.
* .gitignore: ignore each generated <dir>/Makefile, same commit.

These modules carry sibling-object refs (${MAGICDIR}/<mod>/lib*.o) and
custom rules; those keep working unchanged (${MAGICDIR} = the build top,
$(srcdir) from the derivation).  readline/ remains on the -f path.

Verified out-of-tree: config.status writes 35 module Makefiles (22 + 13);
`make modules libs` builds all 33 module libraries (rc=0).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 14:54:11 -04:00
Darryl L. Miles 02d2147753 build: generate 21 standard-module Makefiles from Makefile.in (rename unit)
Second batch of the Makefile.in migration: the remaining standard modules
  bplane calma cif cmwind dbwind debug drc extflat extract garouter gcr
  grouter irouter mzrouter netmenu plow resis select sim textio wiring
Pure renames -- content unchanged, so each still builds via the defs.mak
srcdir derivation (dual mode); the @srcdir@ substitution follows.

* git mv <dir>/Makefile -> <dir>/Makefile.in (21 modules)
* configure.in: AC_CONFIG_FILES for each; regenerated configure.  Their
  build subdirs + Makefiles are now created by config.status, so
  $(submake) recurses natively (make -C <dir>), no -f.
* .gitignore: ignore each generated <dir>/Makefile, in this same commit.

Verified out-of-tree: config.status writes 22 module Makefiles (these 21 +
tiles); `make modules` builds all 33 module libraries (rc=0).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 14:54:11 -04:00
Darryl L. Miles 214cc43f4a build: generate tiles/Makefile from tiles/Makefile.in (rename unit)
First module of the Makefile.in migration (proof).  Pure rename: the
Makefile content is unchanged, so config.status just copies it and the
module still builds via the defs.mak srcdir *derivation* (dual mode from
phase 1) -- the @srcdir@ substitution is a separate follow-up.

* git mv tiles/Makefile -> tiles/Makefile.in
* configure.in: AC_CONFIG_FILES([tiles/Makefile:tiles/Makefile.in]);
  regenerated configure.  config.status now creates build/tiles/Makefile,
  so $(submake) recurses into tiles natively (make -C tiles), no -f.
* .gitignore: ignore the generated tiles/Makefile (in-tree it lands in the
  source tree) -- added in this same commit so it can never be committed.

Verified out-of-tree: config.status writes build/tiles/Makefile,
make -C tiles module builds libtiles.o (rc=0).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 14:54:11 -04:00
Darryl L. Miles 64d2ad8df7 build: generate <magic/autoconf/config.h> from configure
Emit an autoconf config header carrying every autoconf define -- at least
all the -D options that appear on the compiler command lines, plus
anything else configure knows -- available to the tree as
    #include <magic/autoconf/config.h>

It is built directly from confdefs.h just before AC_OUTPUT (which removes
that file), NOT via AC_CONFIG_HEADERS.  This is deliberate:

  * AC_CONFIG_HEADERS would rewrite @DEFS@ to -DHAVE_CONFIG_H and move the
    defines into the header, changing every compiler command line and
    breaking the build until sources #include it.  Building from confdefs.h
    leaves @DEFS@ (and the whole build) exactly as-is, so the header is a
    pure additional artifact with no consumers yet.
  * confdefs.h already holds every AC_DEFINE, including the many that have
    no autoheader template (CALMA_MODULE, HAVE_READLINE, ...), which
    AC_CONFIG_HEADERS/autoheader would have dropped.

Location mirrors the generated database.h (defs.mak GENINC): magic/autoconf/
config.h at the build top when in-tree (build dir == source dir), else
include/magic/autoconf/config.h so the clean -I include/ rule finds it and
the raw build dir stays off the search path.  The directory is created on
demand and the header is rewritten on every ./configure.  No defs.mak.in
change is needed -- the existing -I${GENINC} already resolves it.

.gitignore: ignore the in-tree magic/autoconf/config.h (out-of-tree it is
under the build dir and already ignored).

Verified: out-of-tree writes include/magic/autoconf/config.h, in-tree
writes magic/autoconf/config.h; both contain the command-line defines
(SIZEOF_VOID_P, CALMA_MODULE, HAVE_*, ...); #include <magic/autoconf/
config.h> resolves via -I${GENINC} from a subdir; @DEFS@ is unchanged
(-DHAVE_CONFIG_H absent) and modules still build.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 14:54:11 -04:00
Darryl L. Miles 3f4a9633d6 build: auto-detect latex/dvips and regenerate docs in default make
When latex and dvips are available, the default no-arg "make" now
regenerates the PostScript documentation from its .tex sources into the
build tree; otherwise the pre-built PostScript shipped in the source tree
is used as-is at install time.  Documentation is always available either
way -- installing latex simply refreshes it from source.

configure (scripts/configure.in, regenerated scripts/configure):
* AC_PATH_PROG for latex + dvips; DOCS_TARGET = "docs" only when both are
  found; AC_SUBST(LATEX/DVIPS/DOCS_TARGET).
* Configuration summary prints "LaTeX docs: yes/no".

scripts/defs.mak.in: export LATEX/DVIPS.

Makefile.in:
* all: ... $(DOCS_TARGET) -- pulls in "docs" only when latex was found.
* docs: best-effort -- `make -k` + a warning on failure so a document
  that will not typeset (or a missing texlive package) never fails the
  build; install falls back to the pre-built PostScript for those.

doc/latexfiles/Makefile:
* use ${LATEX}/${DVIPS} from defs.mak.
* the .tex include figures as ../psfigures/*.ps; point the build-tree
  ../psfigures at ${MAGICSRC}/doc/psfigures (no-op in-tree) so latex and
  dvips find them while outputs stay in the build tree.

CI: main.yml and main-aarch64.yml install
texlive-latex-base/-recommended + texlive-fonts-recommended so the Linux
builds exercise doc regeneration (best-effort, never fatal).

README.Tcl: document latex/dvips as an optional prerequisite for docs.

.gitignore: ignore in-tree doc build artifacts (doc/latexfiles/psfiles/,
*.dvi/*.aux/*.log); the pre-built doc/psfiles/ stays tracked.

Verified out-of-tree with TeX Live 2024: configure reports "LaTeX docs:
yes"; `make` regenerates 27/28 documents into the build tree (maint1.tex
has a genuine LaTeX error and falls back), stays exit 0; `make install`
installs the 27 regenerated PostScript from the build tree and maint1
from the source pre-built copy; the source tree is not modified.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 14:54:11 -04:00
Darryl L. Miles 4e967a4766 build: out-of-tree outlier Makefiles — full make + install
Fix the remaining non-standard Makefiles so a full out-of-tree
`../configure && make && make install` builds and installs a complete
magic TCL tree, sources read from the source tree, all outputs in the
build tree.

Shared linker/preprocessor paths (scripts/configure.in, regenerated
scripts/configure):
* --version-script=${MAGICDIR}/magic/symbol.map -> ${MAGICSRC}/... so
  every shared-library link (tclmagic.so, ...) finds the source map.
* MCPP preproc.py path ${MAGICDIR}/scripts -> ${MAGICSRC}/scripts.

Programs (built via tcllibrary, PROGRAMS = magic tcltk):
* magic/Makefile: proto.magicrc, magicWasm.o and the bitmaps/.initrc/
  magicps.pro install copies use $< / $(srcdir) instead of bare names.
* tcltk/Makefile: magicexec/magicdnull compile $<; the sed'd launcher
  scripts (magic.tcl/.sh, ext2spice.sh, ext2sim.sh) read $<; VERSION dep
  -> ${MAGICSRC}; install-tcl copies each TCL file from the build dir if
  present else $(srcdir) (magic.tcl is generated, the rest are source).

Techs (scmos):
* scmos/Makefile: SC_PP template include -> $(srcdir)/extract_template;
  tech-file inputs (scmos.tech.in, *.tech.in) via $(srcdir)/$< ; recurse
  into cif_template with mkdir + -f ${MAGICSRC}/scmos/cif_template/Makefile;
  install copies from build-or-$(srcdir).
* scmos/cif_template/Makefile: MKDIR -> ${MAGICSRC}/scripts/mkdirs;
  SC_CPP gains -I$(srcdir); cpp reads $(srcdir)/cif{in,out}.c so the .gen
  includes resolve; objs/ generated in the build tree.

Data-file installs (source files copied from $(srcdir)):
* graphics/Makefile: glyphs, outline fonts, and the X11 helper build.
* windows/Makefile: glyphs and vector fonts.
* doc/Makefile: recurse into man/tutcells/html/latexfiles build-aware;
  doc/man, doc/tutcells install with $< ; doc/html tars $(srcdir);
  doc/latexfiles reads pre-built PostScript from ${MAGICSRC}/doc/psfiles.

Verified out-of-tree (mkdir _build; cd _build; ../configure): `make`
returns rc=0 (33 module libs, tclmagic.so, magicexec/magicdnull, scmos
tech files + cif_template objs, proto.magicrc), and
`make install DESTDIR=...` returns rc=0 installing 376 files
(bin/magic, tcl/tclmagic.so, sys/ glyphs+fonts+techs+dstyles), with the
source tree left completely clean.

Not exercised by the default TCL build/install and therefore not
converted here: the standalone .so/program variants of
lef/plot/router/ext2spice/ext2sim (their module libs do build), the
disabled oa module (-I. -> -I$(srcdir) still needed if enabled), the
WASM path, and doc/latexfiles PostScript *regeneration* (which still
writes into the source psfiles dir).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 14:54:11 -04:00
Darryl L. Miles 67df47ffb3 build: top Makefile.in + build-dir orchestration (out-of-tree)
Make a plain `make` in a build directory build every module into the
build tree.  The top Makefile becomes a configure-generated Makefile.in,
and each recursion drives a build subdirectory (created on demand) using
the module Makefile from the source tree.

Makefile -> Makefile.in (config.status generates Makefile in the build
top via AC_CONFIG_FILES([Makefile:Makefile.in])):
* Add MAGICSRC = @abs_top_srcdir@; read VERSION and re-run configure from
  ${MAGICSRC}.
* Every descent `(cd $$dir && ${MAKE} <goal>)` and `${MAKE} -C $(dir $@)
  <goal>` becomes:
      mkdir -p <builddir> && ${MAKE} -C <builddir> \
              -f ${MAGICSRC}/<dir>/Makefile <goal>
  so the build subdir need not pre-exist and the source Makefile is used.
  Applied to modules/libs/depend pattern rules and the
  tcllibrary/mains/techs/install/clean loops.
* database/database.h: generate from ${MAGICSRC}/.../database.h.in into
  the build tree (mkdir -p database), via the generated build-tree
  ${MAGICDIR}/scripts/makedbh.
* install-dirs/install-tcl-dirs use ${SCRIPTS}/mkdirs (now source-tree);
  clean skips absent build subdirs; distclean/dist/tags updated for the
  split source/build layout.

scripts/defs.mak.in:
* SCRIPTS now points at the source tree (${MAGICSRC}/scripts) for the
  static helpers (mkdirs, printmans, ...); the one generated helper,
  makedbh, is referenced directly at ${MAGICDIR}/scripts (build tree).
* Guard VPATH so it is set only inside module subdirectories, never at
  the build top -- a top-level VPATH into the source tree could let a
  stale source database/database.h shadow the build-tree copy.

scripts/configure.in: AC_CONFIG_FILES([Makefile:Makefile.in]); regenerated
scripts/configure.

Verified out-of-tree: `../configure && make modules && make libs` builds
all 33 module libraries (lib*.o and lib*.a) plus the generated
database/database.h into the build tree, with no errors and the source
tree left clean.  A full `make` (link the magic program, build techs)
still needs the later outlier fixes (magic/, scmos/, ...).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 14:54:11 -04:00
Darryl L. Miles b522f31d87 build: VPATH-enable shared make machinery (out-of-tree)
With the autoconf layer relocatable, teach the shared make
files to read sources from the source tree and write objects into the
build tree.  The ~26 "standard" and "near-standard" module Makefiles now
build out-of-tree with no per-module edits.

scripts/defs.mak.in:
* Add MAGICSRC = @abs_top_srcdir@ (absolute source top) and derive each
  module's srcdir/VPATH from CURDIR relative to the build top:
      BUILD_TOP      := $(abspath $(MAGICDIR))
      MODULE_SUBPATH := $(subst $(BUILD_TOP),,$(CURDIR))
      srcdir         := $(MAGICSRC)$(MODULE_SUBPATH)
      VPATH          := $(srcdir)
  (MAGICDIR keeps meaning the *build* top; in-tree the trees coincide.)
* CPPFLAGS: add -I${MAGICSRC} (source top, for "<module>/<hdr>.h") and
  -I${srcdir} (same-dir headers), keeping -I${MAGICDIR} for the generated
  database/database.h in the build top.
* MAGIC_VERSION/REVISION read ${MAGICSRC}/VERSION; MAGIC_COMMIT uses
  `git -C ${MAGICSRC}` so it works from a build dir outside the work-tree.

rules.mak:
* Compile rule: `-c $*.c` -> `-c $< -o $@` so the source is found via
  VPATH in srcdir and the object is written to the build cwd.
* Depend and tags rules: prefix sources with $(srcdir)/ (they are passed
  to the compiler/ctags directly, which do not honor VPATH).

scripts/configure.in: AC_CONFIG_FILES([rules.mak:rules.mak]) copies the
VPATH-aware rules.mak into the build top, so a single ${MAGICDIR}
resolves both `include`s in every subdir Makefile.  Regenerated configure.

Known limitation (v1): the Depend post-processing sed strips
absolute-path headers, so with an absolute srcdir most header deps are
dropped; out-of-tree incremental header-change rebuilds are weaker.
Depend is already "optimistic/optional"; relativizing is a follow-up.

Verified out-of-tree: `tiles` and `drc` (the latter #includes the
generated database/database.h) build to completion; all objects land in
the build tree; the source tree stays clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 14:54:11 -04:00
Darryl L. Miles a4e6289035 build: make configure relocatable (out-of-tree)
Enable `mkdir build; cd build; ../configure` to run entirely in the build
directory, with generated config landing there instead of in the source
tree.  This is the autoconf-layer groundwork for a full VPATH build; the
make layer (defs.mak/rules.mak VPATH support, per-dir orchestration) is
still to come, so an out-of-tree `make` is not yet expected to work.

Changes:

* configure (wrapper): run the generated config.status in the *current*
  directory with --srcdir pointing back at the source tree (instead of
  `cd scripts`), so outputs land in the build dir.  Uses an absolute
  basedir so any build-dir location works, not just a subdir of srcdir.

* scripts/configure.in:
  - AC_CONFIG_AUX_DIR(.) -> AC_CONFIG_AUX_DIR(scripts).  Once srcdir
    resolves to the true top (scripts' parent, where rules.mak lives),
    autoconf searches for install-sh/config.sub/... relative to srcdir;
    "." pointed at the wrong place and out-of-tree configure died with
    "cannot find install-sh".
  - Name the .in templates explicitly
    (defs.mak:scripts/defs.mak.in, scripts/makedbh:scripts/makedbh.in)
    so config.status finds them from a separate build dir.  defs.mak is
    written to the build top; makedbh under build/scripts/ to match
    ${SCRIPTS}/makedbh.
  - Drop the trailing `cp defs.mak ..`; defs.mak is now generated in the
    build top directly, and from a build dir the copy would clobber the
    source tree's defs.mak.

* scripts/configure: regenerated with autoconf 2.69.

Verified: out-of-tree `../configure` completes rc=0, writes defs.mak /
scripts/makedbh / config.status into the build dir, records
srcdir=<source top>, and leaves the source tree's tracked files and
generated defs.mak/makedbh untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 14:54:11 -04:00
Darryl L. Miles dc31c1f6f6 Makefile: LDFLAGS autoconf propagation
Also fixed up CC/CXX/CXXFLAGS in the same way.

Main notable concern the tclmagic.so now has reordered position of
$LDFLAGS (was start AND end of list, now start of list only),
$LDDL_FLAGS would have already provided it start of list, so it
would be duplicated set of options.

@LDDL_FLAGS@ no longer prepend $LDFLAGS which is now explicit in the
Makefile to allow specific target control.

The purpose of all this is the toplevel ./configure now has LDFLAGS
control passed down to linker command lines as configure --help
indicates.
2026-07-23 16:09:35 -04:00
Darryl L. Miles 12c7927e88 Makefile: LD_FIRST_LIBS high-priority lib order conf control point 2026-07-23 16:09:35 -04:00
Enno Schnackenberg e45db485d8 Add TCL-embedded WASM build variant alongside the existing non-TCL build
Bump VERSION to 8.3.645.

magic.wasm can now be built as two variants packaged in the same npm
release: notcl/ (legacy, magic's own parser) and tcl/ (intubun/tcl 9.x
statically linked, commands evaluated by Tcl_EvalEx). The TCL fork is
pinned via npm/tcl.ref and cloned/built by magic itself — the tcl/
checkout is treated as read-only and built out-of-source into
magic/build-tcl-wasm/.

Configure layer:
- New usingTk variable decoupled from usingTcl in scripts/configure.in
  + scripts/configure, so --with-tcl --without-tk is finally a valid
  combination. Native Linux Tcl+Tk builds keep their previous behaviour
  (both flags default to enabled).
- When usingTk is empty, configure passes -DMAGIC_NO_TK so the small
  number of remaining Tk callsites in tcltk/tclmagic.{h,c} compile out,
  and TKCOMMON_SRCS / USE_TK_STUBS are omitted from the link.

WASM build orchestration:
- toolchains/emscripten/build-tcl-wasm.sh builds libtcl9.x.a + libtclstub.a
  + tclConfig.sh out-of-source from a pristine intubun/tcl checkout.
- npm/build.sh grew a --variant=<tcl|notcl|both> flag and writes its
  outputs into npm/tcl/ and npm/notcl/. It also clones intubun/tcl with
  autocrlf=false at the SHA pinned by npm/tcl.ref.
- magic/Makefile (WASM block only): magicWasm.o is now compiled with
  DFLAGS_NOSTUB so Tcl_CreateInterp resolves to libtcl9.x directly
  before tclStubsPtr is set. magic.js link pulls in LIB_SPECS_NOSTUB
  and -ltclstub. After rules.mak include, magic: is a phony alias for
  magic.js so the generic ${MODULE} recipe doesn't fight it.
- toolchains/emscripten/defs.mak: add -sUSE_ZLIB=1 (libtcl9 references
  zlib), replace -sSTACK_SIZE=N with -Wl,-z,stack-size=N (emcc >=5
  rejects the setting form).
- magic/magicWasm.c bootstraps the embedded interp under MAGIC_WRAPPER
  (Tcl_CreateInterp -> Tcl_Init -> Tclmagic_Init) and routes
  run_command through Tcl_EvalEx.
- magic/magicTop.c: gate MagicVersion/Revision/CompileTime on
  !MAGIC_WRAPPER so they don't collide with the copies in
  tcltk/tclmagic.c when both objects land in the same wasm binary.

npm package:
- Subpath exports: ".", "./tcl", "./notcl". Default import keeps the
  pre-existing non-TCL behaviour for backward compatibility.
- examples/smoke-tcl.mjs exercises the TCL variant.

CI:
- main-wasm.yml clones intubun/tcl at the pinned ref, builds both
  variants via npm/build.sh --variant=both, runs the existing notcl
  test suite and the new TCL smoke test, and publishes only on a
  v<x.y.z>... git tag. Tag name (minus the leading v) becomes the
  npm version.
2026-06-09 16:07:53 -04:00
Darryl L. Miles af7b6bf119 graphics: minor change to Makefile and configure
This splits and groups DEPSRCS better so errors are not seen trying to
include files that are not present with no intention to build that
source file.
2025-10-04 20:50:31 -04:00
Darryl L. Miles 8b0616eaf5 readline: add configure --enable-readline-bundled option
Cleanup autoconf handling, should always work as expected.
Use of --enable-readline-bundled when readline is needed will use
copy in subdir.
2025-10-04 20:50:31 -04:00
Darryl L. Miles 730d327702 configure.in: AC_CHECK_HEADERS sys/ioctl_compat.h sgtty.h 2025-07-29 10:50:32 -04:00
Darryl L. Miles a8f5291bd7 defs.mak.in: restore autoconf LIBS functionality
This is a standard autoconf variable, it was probably disabled due to
how the graphics/Makefile works and the more complex detection taking
place there.

Needed to use it to add -lpthread to some platforms (freebsd/openbsd)
to make it build out the box.
2025-07-29 10:50:32 -04:00
Darryl L. Miles f45aeb6cee configure.in: AC_STRUCT_DIRENT_D_TYPE 2025-07-29 10:50:32 -04:00
Darryl L. Miles ec7d0fc79a configure.in: AC_PROG_PERL 2025-07-29 10:50:32 -04:00
Darryl L. Miles e51189911b configure.in: AC_PROG_SED (looking for GNU sed) 2025-07-29 10:50:32 -04:00
Darryl L. Miles 9f1398dfcb utils/magsgtty.h: detect termio/ioctl headers
Linux is not based on BSD and this file appears to exist to manage
historic BSD conventions concerning termios.
2025-07-29 10:50:32 -04:00
Darryl L. Miles b6e70f9632 utils/magic_alloca.h: with autoconf AC_FUNC_ALLOCA
Unclear what the correct Copyright header should be on this one,
given most of the lines in the file are from the autoconf
documentation.
2025-07-29 10:50:32 -04:00
Darryl L. Miles 4d2def46f4 configure.in: whitespace cleanup align --help columns 2025-07-29 10:50:32 -04:00
Darryl L. Miles 49caa3267b configure: --enable-debug make this a user accessible config
This should help with automated CI testing as well, where a suite
can be run and debug enabled and checked, just via a specific
CI setup.
2025-07-29 10:50:32 -04:00
Darryl L. Miles dd49ca21d2 configure: --enable-assertions make this a user accessible config
This should help with automated CI testing as well, where a suite
can be run and assertions enabled and checked, just via a specific
CI setup.
2025-07-29 10:50:32 -04:00
Darryl L. Miles d13fa6872e MAKE_xxxxx: to skip building OBJs part of configure 2025-07-29 10:50:32 -04:00
Darryl L. Miles c695980145 configure.in: Add AC_HEADER_TIME 2025-07-27 12:43:04 -04:00
Darryl L. Miles 52d3feac73 configure.in: AC_C_INLINE AC_C_RESTRICT 2025-07-27 12:42:05 -04:00
Darryl L. Miles bfbdf45b88 C23: use AC_HEADER_STDBOOL #include <stdbool.h> 2025-07-26 17:44:45 -04:00
Darryl L. Miles c676c6b1d3 configure.in: getrlimit setrlimit sys/resource.h 2025-04-09 15:19:25 -04:00
Tim Edwards 1cec414618 Added the contents of the "readline" module back. This is
generally unused, as it is incompatible with the Tcl/Tk build of
magic.  However, I had not intended to remove it, only move the
name from "readline-4.3" to "readline".  But "readline/readline"
was in .gitignore, which caused the contents to be removed from
the repository.  This commit restores those files, and also
prevents the readline directory Makefile from making a symbolic
link called "readline" to itself, which was causing compile-time
issues.  The readline code is only kept for backwards compatibility
with ancient versions of magic not using the Tcl/Tk interpreter.
2025-01-10 09:58:57 -05:00
Darryl L. Miles e54111cf6f configure.in: X11 detection and option order
The -L option needs to be placed before the -l it needs to affect.
This maybe important on MacOSX where a nonstandard/optional package
provides X11 support so the locations are not in system locations.
2024-12-26 12:52:25 -05:00
Darryl L. Miles cd63fa3c14 K&R calma: remove system header time() K&R style prototype
time.h has existed since C89 so is a standard header expected
to always be available.

sys/time.h was an optional header that historically only some
platforms provided.

If there is a conflict on specific platforms it is better to
'#if !defined()' that specific niche platform with the problem
if both headers are included in the same compile unit.  But I
don't think this is a problem in modern times.

So this results in a resolution that removes #ifdef around
time.h and the detection by configure for the availabiltiy
of sys/time.h.

K&R obsolete syntax removal for C23 compatibility series
2024-12-26 12:44:50 -05:00
Donn 86630fcc02 Allow Python 3 to not be in PATH, Fix `clean` re-building dependencies
* Adds Python 3 to macOS requirements
* Gate include of `DEPEND_FILE` in `rules.mak` on whether the target is `clean` or not (the include isn't pre-processed; it will attempt to build everything in the include otherwise)
* Make `makedbh` a configurable file- the shebang now uses the discovered path for Python3
2023-08-29 22:43:11 +03:00
Donn 02e16b8bce Build Updates
This is a series of updates to make building magic far less of a headache:

* Drop `csh`/`tcsh` dependency and detection from `./configure`.
* Rewrite makedbh in Python.
* Rewrite printmans in POSIX sh.
* Stop deleting Depend before every compile (which causes some files to recompile and thus increases recompile times significantly)
* Add Depend to CLEANS in scripts/defs.mak.in
* Turn POSIX suffix rule in magic/rules.mak to a pattern rule with proper prerequisites
2023-08-25 12:24:14 -04:00
Johan Euphrosine e249e7a0e3 configure: cleanup diff 2023-07-12 05:04:18 +09:00
Johan Euphrosine f5793bbefb configure: add asmjs-unknown-emscripten target 2023-07-12 04:44:37 +09:00
Johan Euphrosine 96eb275622 quick and dirty emscripten port 2023-07-12 00:31:37 +09:00
Tim Edwards 5aee1dcb5a Added "-Werror=implicit-function-declaration" to CFLAGS in the
configure script, now that Alessandro De Laurenzis has cleaned
up the code so that it will compile with the setting (now, just
need to do the same thing for "implicit-int"!).
2022-10-29 10:04:18 -04:00
Brad Smith 0bfb7c80d3 Simplify OpenBSD shared lib handling 2022-08-22 12:19:42 -04:00
Tim Edwards c997f4cccf Modified the configure script and Makefiles so that systems that do
not include zlib by default will pick it up from the compile line.
2022-05-28 17:51:20 -04:00