From 02e16b8bce8f9d19fef32932a4742e797025cc19 Mon Sep 17 00:00:00 2001 From: Donn Date: Sun, 16 Jul 2023 19:37:48 +0300 Subject: [PATCH] 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 --- .github/workflows/main.yml | 7 +- .gitignore | 1 + INSTALL_MacOS.md | 2 +- Makefile | 1 - rules.mak | 5 +- scripts/.gitignore | 1 + scripts/configure | 63 +-------- scripts/configure.in | 10 -- scripts/defs.mak.in | 2 +- scripts/makedbh | 278 +++++++++++++------------------------ scripts/printmans | 13 +- 11 files changed, 115 insertions(+), 268 deletions(-) create mode 100644 scripts/.gitignore diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b21864e9..bb6c1b93 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,10 +17,10 @@ jobs: steps: - name: Pulling the docker image run: docker pull vezzal/vezzal:v1 - + - name: Start the container with the docker image run: docker run -id --name test_magic vezzal/vezzal:v1 bash | exit - + - name: Run the testing on the container and send the mail run: docker exec test_magic /vezzal/test_magic.sh "lankasaicharan123@gmail.com,tim@opencircuitdesign.com" ${{secrets.MAILING_KEY}} simple_build_linux: @@ -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 diff --git a/.gitignore b/.gitignore index f6595db9..c44feacd 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ magic/tclmagic.dylib tcltk/magicdnull.dSYM/ tcltk/magicexec.dSYM/ reconfigure.sh +pfx/ \ No newline at end of file diff --git a/INSTALL_MacOS.md b/INSTALL_MacOS.md index 4e866c89..37c9ea12 100644 --- a/INSTALL_MacOS.md +++ b/INSTALL_MacOS.md @@ -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 diff --git a/Makefile b/Makefile index 12a20220..b53b3e54 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/rules.mak b/rules.mak index 36006fb1..5a6c2cb5 100644 --- a/rules.mak +++ b/rules.mak @@ -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 diff --git a/scripts/.gitignore b/scripts/.gitignore new file mode 100644 index 00000000..6fd912cd --- /dev/null +++ b/scripts/.gitignore @@ -0,0 +1 @@ +autom4te.cache/ \ No newline at end of file diff --git a/scripts/configure b/scripts/configure index eee98cd9..6504d103 100755 --- a/scripts/configure +++ b/scripts/configure @@ -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*) diff --git a/scripts/configure.in b/scripts/configure.in index 56e85b43..5a7b1382 100644 --- a/scripts/configure.in +++ b/scripts/configure.in @@ -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]) diff --git a/scripts/defs.mak.in b/scripts/defs.mak.in index d1389e8b..3cbb6499 100755 --- a/scripts/defs.mak.in +++ b/scripts/defs.mak.in @@ -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} diff --git a/scripts/makedbh b/scripts/makedbh index 01e4fa52..f08eaa53 100755 --- a/scripts/makedbh +++ b/scripts/makedbh @@ -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 - -# @ 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 - - -# Generate the main part of the database.h file from database.h.in -cat $1 > $2 - -# 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. - -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 - -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 - -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 - -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 +bpw = 32 +maskwords = (maxtypes + bpw - 1) // bpw + +# Prepare Output String +out_string = database_h_in + + +def p(string): + global out_string + out_string += f"{string}" + + +# Generated macros +def add_generated_mask_macro(name, expression, *, connector=","): + global maskwords + + 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") + + +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}])", +) + +p("#endif /* _DATABASE_H */\n") + +with open(sys.argv[2], "w", encoding="utf8") as f: + f.write(out_string) diff --git a/scripts/printmans b/scripts/printmans index 05e2e1f5..3d5fb2f7 100755 --- a/scripts/printmans +++ b/scripts/printmans @@ -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 \ No newline at end of file