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
This commit is contained in:
Donn 2023-07-16 19:37:48 +03:00 committed by Tim Edwards
parent cb00ede59d
commit 02e16b8bce
11 changed files with 105 additions and 258 deletions

View File

@ -29,7 +29,7 @@ jobs:
- uses: actions/checkout@v2
- name: Get Dependencies
run: |
sudo apt-get install -y tcl-dev tk-dev libcairo-dev csh
sudo apt-get install -y tcl-dev tk-dev libcairo-dev
- name: Build
run: |
./configure
@ -41,7 +41,6 @@ jobs:
- uses: actions/checkout@v2
- name: Get Dependencies
run: |
sudo apt-get install -y csh
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest

1
.gitignore vendored
View File

@ -32,3 +32,4 @@ magic/tclmagic.dylib
tcltk/magicdnull.dSYM/
tcltk/magicexec.dSYM/
reconfigure.sh
pfx/

View File

@ -3,7 +3,7 @@
Get [Homebrew](https://brew.sh).
```sh
brew install cairo tcl-tk tcsh
brew install cairo tcl-tk
brew install --cask xquartz
./scripts/configure_mac
make database/database.h

View File

@ -59,7 +59,6 @@ libs:
depend: database/database.h
@echo --- making dependencies
${RM} */Depend
for dir in ${MODULES} ${UNUSED_MODULES} ${PROGRAMS}; do \
(cd $$dir && ${MAKE} depend) || exit 1; done

View File

@ -14,13 +14,12 @@ depend: ${DEPEND_FILE}
${DEPEND_FILE}:
${CC} ${CFLAGS} ${CPPFLAGS} ${DFLAGS} ${DEPEND_FLAG} ${DEPSRCS} | \
sed -e "/#/D" -e "/ \//s/ \/.*\.h//" -e "/ \\\/D" \
> ${DEPEND_FILE}
sed -e "/#/D" -e "/ \//s/ \/.*\.h//" -e "/ \\\/D" > ${DEPEND_FILE}
# Original Depend file generating line:
# ${CC} ${CFLAGS} ${CPPFLAGS} ${DFLAGS} ${DEPEND_FLAG} ${SRCS} > ${DEPEND_FILE}
.c.o: ../database/database.h
${OBJS}: %.o: ${SRCS} ../database/database.h
@echo --- compiling ${MODULE}/$*.o
${RM} $*.o
${CC} ${CFLAGS} ${CPPFLAGS} ${DFLAGS} -c $*.c

1
scripts/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
autom4te.cache/

63
scripts/configure vendored
View File

@ -673,7 +673,6 @@ X_PRE_LIBS
X_CFLAGS
XMKMF
PYTHON3
CSH
GCORE
EGREP
GREP
@ -723,7 +722,6 @@ infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
@ -829,7 +827,6 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE}'
@ -1082,15 +1079,6 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
-runstatedir | --runstatedir | --runstatedi | --runstated \
| --runstate | --runstat | --runsta | --runst | --runs \
| --run | --ru | --r)
ac_prev=runstatedir ;;
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
| --run=* | --ru=* | --r=*)
runstatedir=$ac_optarg ;;
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@ -1228,7 +1216,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
libdir localedir mandir runstatedir
libdir localedir mandir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
@ -1381,7 +1369,6 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
@ -5340,53 +5327,6 @@ fi
# Extract the first word of "csh", so it can be a program name with args.
set dummy csh; 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_CSH+:} false; then :
$as_echo_n "(cached) " >&6
else
case $CSH in
[\\/]* | ?:[\\/]*)
ac_cv_path_CSH="$CSH" # 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_CSH="$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_CSH" && ac_cv_path_CSH="no"
;;
esac
fi
CSH=$ac_cv_path_CSH
if test -n "$CSH"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CSH" >&5
$as_echo "$CSH" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test "x${CSH}" = "xno"; then
as_fn_error $? "cannot find /bin/csh---cannot compile!" "$LINENO" 5
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
@ -7794,6 +7734,7 @@ case $target in
;;
*-emscripten*)
$as_echo "#define linux 1" >>confdefs.h
CFLAGS="${CFLAGS} -fPIC -Werror=implicit-function-declaration -Wno-int-conversion -Wno-implicit-int"
;;
*solaris*)

View File

@ -290,16 +290,6 @@ dnl Check for gcore, used by niceabort.c
AC_PATH_PROG(GCORE, gcore, [no])
dnl Check for /bin/csh; warn if not available. We should do something
dnl here to get makedbh to run under other common conditions, such as
dnl csh not being in /bin, or only tcsh being available.
AC_PATH_PROG(CSH, csh, [no])
if test "x${CSH}" = "xno"; then
AC_MSG_ERROR([cannot find /bin/csh---cannot compile!])
fi
dnl Python3 is preferred for running the preprocessor script
dnl but CPP can be used instead.
AC_PATH_PROG([PYTHON3], [python3], [no])

View File

@ -105,4 +105,4 @@ OA_LIBS = @OA_LIBS@
DEPSRCS = ${SRCS}
OBJS = ${SRCS:.c=.o} ${CXXSRCS:.cpp=.o}
LIB_OBJS = ${LIB_SRCS:.c=.o}
CLEANS = ${OBJS} ${LIB_OBJS} lib${MODULE}.a lib${MODULE}.o ${MODULE}
CLEANS = Depend ${OBJS} ${LIB_OBJS} lib${MODULE}.a lib${MODULE}.o ${MODULE}

View File

@ -1,189 +1,107 @@
#!/bin/csh -f
#
#!/usr/bin/env python3
# makes the "database.h" (1st argument, $1) file from "database.h.in"
# (2nd argument, $2), setting various mask operation definitions
# according to the number of words implied by the value of TT_MAXTYPES
import re
import sys
# The following mess grabs the value of TT_MAXTYPES from database.h.in
#
set maxtypes=`sed -n -e '/^#define[[:space:]]*TT_MAXTYPES/s/#define[[:space:]]*TT_MAXTYPES[[:space:]]*//p' < $1 | sed -e 's/\/\*[[:print:]]*\*\/[[:space:]]*//g' `
#
# Alternative method works with outdated versions of sed/ed.
#
if ($maxtypes == "") then
set maxtypes=`sed -n -e '/^#define[ ]*TT_MAXTYPES/s/#define[ ]*TT_MAXTYPES[ ]*//p' < $1 | sed -e 's/\/\*.*\*\/[ ]*//g' `
endif
#
# If we can't generate database.h correctly, nothing is going to compile.
#
if ($maxtypes == "") then
echo "Bad sed script in scripts/makedbh: Cannot generate database/database.h!"
exit
endif
database_h_in = open(sys.argv[1], encoding="utf8").read()
maxtypes_rx = re.compile(r"#define\s+TT_MAXTYPES\s+(\d+)")
match = maxtypes_rx.findall(database_h_in)
if len(match) == 0:
print(
f"Bad regular expression in {sys.argv[0]}: Cannot generate database/database.h!",
file=sys.stderr,
)
exit(-1)
maxtypes = int(match[0])
# Find derived values from bits per word
# Note that bits-per-word should be determined from the compiler, but
# 32 bits per word has always been hardwired into magic.
#
set bpw = 32
bpw = 32
maskwords = (maxtypes + bpw - 1) // bpw
# @ wordmask=$bpw - 1
# set wordshift=`echo "c=l($bpw); d=l(2); scale=0; c/d" | bc -l`
# @ maskwords=$maxtypes + $bpw - 1
# @ maskwords/=$bpw
@ maskwords=$maxtypes + $bpw - 1
@ maskwords/=$bpw
# Prepare Output String
out_string = database_h_in
# Generate the main part of the database.h file from database.h.in
cat $1 > $2
def p(string):
global out_string
out_string += f"{string}"
# Generate a list of integers from 0 to the value of "maskwords" - 1
set count=""
@ maskwords--
while (${maskwords} >= 0)
set count=`echo ${count} ${maskwords}`
@ maskwords--
end
# NOTE: echo -n is not POSIX, not portable to newer Bourne-shells, so use printf
# NOTE: Some OSes are known to buffer printf and echo independently, so do not
# intermix "echo" and "printf" or output may have lines out of order.
# Generated macros
def add_generated_mask_macro(name, expression, *, connector=","):
global maskwords
printf "#define TTMaskZero(m) ( \\\n" >> $2
foreach i (${count})
printf " (m)->tt_words[$i] = 0" >> $2
if ($i == 0) then
printf ")\n" >> $2
printf "\n" >> $2
else
printf ", \\\n" >> $2
endif
end
p(f"#define {name} ( \\\n")
for i in reversed(range(maskwords)):
p(f"\t{expression.format(i=i)}")
if i == 0:
p(")\n\n")
else:
p(f"{connector} \\\n")
printf "#define TTMaskIsZero(m) ( \\\n" >> $2
foreach i (${count})
printf " (m)->tt_words[$i] == 0" >> $2
if ($i == 0) then
printf ")\n" >> $2
printf "\n" >> $2
else
printf " && \\\n" >> $2
endif
end
printf "#define TTMaskEqual(m, n) ( \\\n" >> $2
foreach i (${count})
printf " (m)->tt_words[$i] == (n)->tt_words[$i]" >> $2
if ($i == 0) then
printf ")\n" >> $2
printf "\n" >> $2
else
printf " && \\\n" >> $2
endif
end
add_generated_mask_macro(
"TTMaskZero(m)",
"(m)->tt_words[{i}] = 0",
)
add_generated_mask_macro(
"TTMaskIsZero(m)",
"(m)->tt_words[{i}] == 0",
connector=" &&",
)
add_generated_mask_macro(
"TTMaskEqual(m, n)",
"(m)->tt_words[{i}] == (n)->tt_words[{i}]",
connector=" &&",
)
add_generated_mask_macro(
"TTMaskIntersect(m, n)",
"((m)->tt_words[{i}] & (n)->tt_words[{i}])",
connector=" ||",
)
add_generated_mask_macro(
"TTMaskCom(m)",
"((m)->tt_words[{i}] = ~(m)->tt_words[{i}])",
)
add_generated_mask_macro(
"TTMaskCom2(m, n)",
"((m)->tt_words[{i}] = ~(n)->tt_words[{i}])",
)
add_generated_mask_macro(
"TTMaskSetMask(m, n)",
"((m)->tt_words[{i}] |= (n)->tt_words[{i}])",
)
add_generated_mask_macro(
"TTMaskSetMask3(m, n, o)",
"((m)->tt_words[{i}] |= (n)->tt_words[{i}] | (o)->tt_words[{i}])",
)
add_generated_mask_macro(
"TTMaskAndMask(m, n)",
"((m)->tt_words[{i}] &= (n)->tt_words[{i}])",
)
add_generated_mask_macro(
"TTMaskAndMask3(m, n, o)",
"((m)->tt_words[{i}] = (n)->tt_words[{i}] & (o)->tt_words[{i}])",
)
add_generated_mask_macro(
"TTMaskClearMask(m, n)",
"((m)->tt_words[{i}] &= ~(n)->tt_words[{i}])",
)
add_generated_mask_macro(
"TTMaskClearMask3(m, n, o)",
"((m)->tt_words[{i}] = (n)->tt_words[{i}] & ~(o)->tt_words[{i}])",
)
printf "#define TTMaskIntersect(m, n) ( \\\n" >> $2
foreach i (${count})
printf " ((m)->tt_words[$i] & (n)->tt_words[$i])" >> $2
if ($i == 0) then
printf ")\n" >> $2
printf "\n" >> $2
else
printf " || \\\n" >> $2
endif
end
p("#endif /* _DATABASE_H */\n")
printf "#define TTMaskCom(m) ( \\\n" >> $2
foreach i (${count})
printf " ((m)->tt_words[$i] = ~(m)->tt_words[$i])" >> $2
if ($i == 0) then
printf ")\n" >> $2
printf "\n" >> $2
else
printf ", \\\n" >> $2
endif
end
printf "#define TTMaskCom2(m, n) ( \\\n" >> $2
foreach i (${count})
printf " ((m)->tt_words[$i] = ~(n)->tt_words[$i])" >> $2
if ($i == 0) then
printf ")\n" >> $2
printf "\n" >> $2
else
printf ", \\\n" >> $2
endif
end
printf "#define TTMaskSetMask(m, n) ( \\\n" >> $2
foreach i (${count})
printf " ((m)->tt_words[$i] |= (n)->tt_words[$i])" >> $2
if ($i == 0) then
printf ")\n" >> $2
printf "\n" >> $2
else
printf ", \\\n" >> $2
endif
end
printf "#define TTMaskSetMask3(m, n, o) ( \\\n" >> $2
foreach i (${count})
printf " ((m)->tt_words[$i] |= (n)->tt_words[$i] | (o)->tt_words[$i])" \
>> $2
if ($i == 0) then
printf ")\n" >> $2
printf "\n" >> $2
else
printf ", \\\n" >> $2
endif
end
printf "#define TTMaskAndMask(m, n) ( \\\n" >> $2
foreach i (${count})
printf " ((m)->tt_words[$i] &= (n)->tt_words[$i])" >> $2
if ($i == 0) then
printf ")\n" >> $2
printf "\n" >> $2
else
printf ", \\\n" >> $2
endif
end
printf "#define TTMaskAndMask3(m, n, o) ( \\\n" >> $2
foreach i (${count})
printf " ((m)->tt_words[$i] = (n)->tt_words[$i] & (o)->tt_words[$i])" \
>> $2
if ($i == 0) then
printf ")\n" >> $2
printf "\n" >> $2
else
printf ", \\\n" >> $2
endif
end
printf "#define TTMaskClearMask(m, n) ( \\\n" >> $2
foreach i (${count})
printf " ((m)->tt_words[$i] &= ~(n)->tt_words[$i])" >> $2
if ($i == 0) then
printf ")\n" >> $2
printf "\n" >> $2
else
printf ", \\\n" >> $2
endif
end
printf "#define TTMaskClearMask3(m, n, o) ( \\\n" >> $2
foreach i (${count})
printf " ((m)->tt_words[$i] = (n)->tt_words[$i] & ~(o)->tt_words[$i])" \
>> $2
if ($i == 0) then
printf ")\n" >> $2
else
printf ", \\\n" >> $2
endif
end
printf "\n" >> $2
printf "#endif /* _DATABASE_H */\n" >> $2
with open(sys.argv[2], "w", encoding="utf8") as f:
f.write(out_string)

View File

@ -1,9 +1,8 @@
#!/bin/csh -f
#!/bin/sh
cmd=$1
shift
set cmd=($1)
shift argv
foreach i ($argv)
echo cat $i \| $cmd
for i in "$@"; do
echo "cat $i | $cmd"
cat $i | $cmd
end
done