From 086870addd9599ef74bed8e81ebb353da7836709 Mon Sep 17 00:00:00 2001
From: grischka <grischka>
Date: Wed, 6 Sep 2023 22:21:15 +0200
Subject: [PATCH] configury update & bump VERSION to 0.9.28rc

configure:
- option --targetos=... for cross build
- cleanup

win32/build-tcc.bat:
- option -b <bindir>
- make 'libtcc1.a' and cross-prefix-libtcc1.a
  (same convention as with makefile)

Makefile:
- streamline tcov-tests, help, etc.

workflow/build.xml: simplify
- using "windows-2019" runner (instead of windows-latest)
  because its msys seems more complete and has no problems
  with the 96_nodata_wanted.test either.

Changelog,TODO,USES,tcc-doc.texi: update
---
 .github/workflows/build.yml |  74 ++-----
 .gitignore                  |   2 +-
 Changelog                   |  21 +-
 Makefile                    | 112 +++++-----
 TODO                        |   3 +-
 USES                        |  48 ++++
 VERSION                     |   2 +-
 configure                   | 421 ++++++++++++++++++++----------------
 conftest.c                  |  14 +-
 tcc-doc.texi                |  11 +-
 tests/pp/Makefile           |   4 +-
 tests/tests2/Makefile       |   8 +-
 win32/build-tcc.bat         |  81 +++----
 13 files changed, 435 insertions(+), 366 deletions(-)

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 4a1b62e1..e3c1b241 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,68 +1,32 @@
 name: build and run tests
+
 on:
   push:
     branches: [ mob ]
-  pull_request:
-    branches: [ mob ]
+
 jobs:
-  build-release-linux-i686-amd64:
-    name: tinycc master linux/amd64
+  test-x86_64-linux:
     runs-on: ubuntu-20.04
     steps:
-    - uses: actions/checkout@v2
-    - name: Install dependencies
-      run: sudo apt-get install -y
-        gcc
-    # see what's available in /usr/bin
-    - name: see what's available
-      run: ls -l /usr/bin
-    # build project amd64
-    - name: build amd64
-      run: |
-        ./configure
-        make
-    # run tests
-    - name: run test_exs amd64
-      run: |
-        make test
+    - uses: actions/checkout@v3
+    - name: make & test tcc
+      run: ./configure && make && make test -k
 
-  build-release-osx-amd64:
-    name: tinycc master osx/amd64
+  test-x86_64-osx:
     runs-on: macos-11
     steps:
-    - uses: actions/checkout@v2
-    # see what's available in /usr/bin
-    - name: see what's available
-      run: ls -l /usr/bin
-    # build project amd64
-    - name: build amd64
-      run: |
-        ./configure
-        make
-    # run tests
-    - name: run test_exs amd64
-      run: |
-        make test
+    - uses: actions/checkout@v3
+    - name: make & test tcc
+      run: ./configure && make && make test -k
 
-  build-release-windows-amd64-on-windows:
-    name: tinycc master windows/amd64 on Windows
-    runs-on: windows-latest
+  test-x86_64-win32:
+    runs-on: windows-2019
     steps:
-    - uses: actions/checkout@v2
-    - uses: msys2/setup-msys2@v2
-    # build project amd64
-    - name: build amd64
+    - uses: actions/checkout@v3
+    - name: make & test tcc
+      shell: cmd
       run: |
-        msys2 -c './configure'
-        make
-    # silency failing tests
-    - name: silence 96_nodata_wanted
-      run: |
-        pushd .\tests\tests2
-        Get-Content .\96_nodata_wanted.expect -TotalCount 2 | Out-File .\96_nodata_wanted.expect2 -Encoding default
-        mv .\96_nodata_wanted.expect2 .\96_nodata_wanted.expect -force
-        popd
-    # run tests
-    - name: run test_exs amd64
-      run: |
-        make test
+        set MSYS2_PATH_TYPE=inherit
+        set MSYSTEM=MINGW64
+        set CHERE_INVOKING=yes
+        C:\msys64\usr\bin\bash -l -c "./configure && make && make test -k"
diff --git a/.gitignore b/.gitignore
index d79c1c8a..24ee9612 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,9 +31,9 @@ tags
 TAGS
 tcc.1
 *.pod
+*.tcov
 tcc-doc.html
 tcc-doc.info
-tcc_c.tcov
 
 win32/doc
 win32/examples/libtcc_test.c
diff --git a/Changelog b/Changelog
index 342484c3..7ccf11da 100644
--- a/Changelog
+++ b/Changelog
@@ -1,19 +1,26 @@
 version 0.9.28:
 
 User interface:
-- new tcc -ar x and t flags (herman ten brugge)
+- -b : bounds checker much improved (herman ten brugge)
+- -bt : support for standalone backtraces also (grischka)
+- -gdwarf : debug format (herman ten brugge)
+- -M, -MM, and -MMD (Arthur Williams)
+- -W[no-]error=<option> (Steffen Nurpmeso)
 
 Platforms:
-- new RISC-V (riscv64) target
-- native macOS support for x86_64/arm64 (Herman ten Brugge)
+- new RISC-V (riscv64) target (Michael Matz)
+- native macOS support for x86_64 (Michael Matz, Herman ten Brugge)
+- arm and riscv64 assemblers (Danny Milosavljevic)
+- Android support with position independent executables (grischka)
 
 Features:
-- Improved support for C11
-- C11 _Static_assert support (matthias)
+- _Static_assert() (matthias)
+- __attribute__ ((cleanup(func))) (matthias)
+- stdatomic (Dmitry Selyutin)
+- asm goto ("jmp %l[label]" : : : : label) (Michael Matz)
 
 Fixes:
-- fix preprocessor line (#line) directive (Herman ten Brugge)
-Many more! see also git shortlog release_0_9_27...HEAD
+- ... many, see git shortlog release_0_9_27...release_0_9_27
 
 Version 0.9.27:
 
diff --git a/Makefile b/Makefile
index a117c8c1..ba6ec08f 100644
--- a/Makefile
+++ b/Makefile
@@ -30,13 +30,19 @@ ifdef CONFIG_WIN32
   LIBTCC = libtcc$(DLLSUF)
   LIBTCCDEF = libtcc.def
  endif
+ ifneq ($(CONFIG_debug),yes)
+  LDFLAGS += -s
+ endif
  NATIVE_TARGET = $(ARCH)-win$(if $(findstring arm,$(ARCH)),ce,32)
 else
  CFG = -unx
- LIBS=-lm -lpthread
+ LIBS+=-lm
  ifneq ($(CONFIG_ldl),no)
   LIBS+=-ldl
  endif
+ ifneq ($(CONFIG_pthread),no)
+  LIBS+=-lpthread
+ endif
  # make libtcc as static or dynamic library?
  ifeq ($(CONFIG_static),no)
   LIBTCC=libtcc$(DLLSUF)
@@ -68,11 +74,8 @@ endif
 TCCFLAGS-unx = -B$(TOP) -I$(TOPSRC)/include -I$(TOPSRC) -I$(TOP)
 TCCFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include -I$(TOPSRC) -I$(TOP) -L$(TOP)
 TCCFLAGS = $(TCCFLAGS$(CFG))
-ifdef USE_TCC_C
-TCC = $(TOP)/tcc_c$(EXESUF) $(TCCFLAGS)
-else
-TCC = $(TOP)/tcc$(EXESUF) $(TCCFLAGS)
-endif
+TCC_LOCAL = $(TOP)/tcc$(EXESUF)
+TCC = $(TCC_LOCAL) $(TCCFLAGS)
 
 CFLAGS_P = $(CFLAGS) -pg -static -DCONFIG_TCC_STATIC -DTCC_PROFILE
 LIBS_P = $(LIBS)
@@ -181,11 +184,8 @@ DEFINES += $(if $(ELF-$T),-DCONFIG_TCC_ELFINTERP="\"$(ELF-$T)\"")
 DEFINES += $(DEF-$(or $(findstring win,$T),unx))
 
 ifneq ($(X),)
-ifeq ($(CONFIG_WIN32),yes)
-DEF-win += -DCONFIG_TCC_CROSSPREFIX="\"$X\""
-DEF-unx += -DCONFIG_TCC_CROSSPREFIX="\"lib/$X\""
-else
 DEF-all += -DCONFIG_TCC_CROSSPREFIX="\"$X\""
+ifneq ($(CONFIG_WIN32),yes)
 DEF-win += -DCONFIG_TCCDIR="\"$(tccdir)/win32\""
 endif
 endif
@@ -249,17 +249,14 @@ endif
 
 GITHASH:=$(shell git rev-parse --abbrev-ref HEAD 2>/dev/null || echo no)
 ifneq ($(GITHASH),no)
-GITHASH:=$(shell git log -1 --pretty='format:%cs $(GITHASH)@%h')$(shell git diff --quiet || echo '*')
-DEF_GITHASH:= -DTCC_GITHASH="\"$(GITHASH)\""
+GITHASH:=$(shell git log -1 --date=short --pretty='format:%cd $(GITHASH)@%h')
+GITMODF:=$(shell git diff --quiet || echo '*')
+DEF_GITHASH:= -DTCC_GITHASH="\"$(GITHASH)$(GITMODF)\""
 endif
 
 ifeq ($(CONFIG_debug),yes)
 CFLAGS += -g
 LDFLAGS += -g
-else
-ifndef CONFIG_OSX
-LDFLAGS += -s
-endif
 endif
 
 # convert "include/tccdefs.h" to "tccdefs_.h"
@@ -335,7 +332,11 @@ libtcc1.a : tcc$(EXESUF) FORCE
 .PRECIOUS: %-libtcc1.a
 FORCE:
 
-run-if = $(if $(shell command -v $1),$S $1 $2)
+# WHICH = which $1 2>/dev/null
+# some versions of gnu-make do not recognize 'command' as a shell builtin
+WHICH = sh -c 'command -v $1'
+
+run-if = $(if $(shell $(call WHICH,$1)),$S $1 $2)
 S = $(if $(findstring yes,$(SILENT)),@$(info * $@))
 
 # --------------------------------------------------------------------------
@@ -348,7 +349,7 @@ tcc-doc.info: tcc-doc.texi
 
 tcc.1 : tcc-doc.pod
 	$(call run-if,pod2man,--section=1 --center="Tiny C Compiler" \
-		--release="$(VERSION)" $< >$@ && rm -f $<)
+		--release="$(VERSION)" $< >$@)
 %.pod : %.texi
 	$(call run-if,perl,$(TOPSRC)/texi2pod.pl $< $@)
 
@@ -392,8 +393,9 @@ endif
 
 # uninstall
 uninstall-unx:
-	@rm -fv $(foreach P,$(PROGS) $(PROGS_CROSS),"$(bindir)/$P")
-	@rm -fv "$(libdir)/libtcc.a" "$(libdir)/libtcc.so" "$(libdir)/libtcc.dylib" "$(includedir)/libtcc.h"
+	@rm -fv $(addprefix "$(bindir)/",$(PROGS) $(PROGS_CROSS))
+	@rm -fv $(addprefix "$(libdir)/", libtcc*.a libtcc*.so libtcc.dylib,$P)
+	@rm -fv $(addprefix "$(includedir)/", libtcc.h)
 	@rm -fv "$(mandir)/man1/tcc.1" "$(infodir)/tcc-doc.info"
 	@rm -fv "$(docdir)/tcc-doc.html"
 	@rm -frv "$(tccdir)"
@@ -415,17 +417,19 @@ ifneq "$(wildcard $(LIBTCC1_U))" ""
 	$(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/lib/include")
 endif
 
-# the msys-git shell works to configure && make except it does not have install
-ifeq ($(CONFIG_WIN32)-$(shell command -v install || echo no),yes-no)
-install-win : INSTALL = cp
-install-win : INSTALLBIN = cp
-endif
-
 # uninstall on windows
 uninstall-win:
-	@rm -fv $(foreach P,libtcc.dll $(PROGS) *-tcc.exe,"$(bindir)"/$P)
-	@rm -fr $(foreach P,doc examples include lib libtcc,"$(tccdir)/$P"/*)
-	@rm -frv $(foreach P,doc examples include lib libtcc,"$(tccdir)/$P")
+	@rm -fv $(addprefix "$(bindir)/", libtcc*.dll $(PROGS) *-tcc.exe)
+	@rm -fr $(foreach P,doc examples include lib libtcc,"$(tccdir)/$P/*")
+	@rm -frv $(addprefix "$(tccdir)/", doc examples include lib libtcc)
+
+# the msys-git shell works to configure && make except it does not have install
+ifeq ($(OS),Windows_NT)
+ifeq ($(shell $(call WHICH,install) || echo no),no)
+INSTALL = cp
+INSTALLBIN = cp
+endif
+endif
 
 # --------------------------------------------------------------------------
 # other stuff
@@ -459,66 +463,50 @@ test:
 # run test(s) from tests2 subdir (see make help)
 tests2.%:
 	@$(MAKE) -C tests/tests2 $@
-
+# run test(s) from testspp subdir (see make help)
 testspp.%:
 	@$(MAKE) -C tests/pp $@
-
-# run all tests with code coverage
+# run tests with code coverage
+tcov-tes% : tcc_c$(EXESUF)
+	@rm -f $<.tcov
+	@$(MAKE) --no-print-directory TCC_LOCAL=$(CURDIR)/$< tes$*
 tcc_c$(EXESUF): $($T_FILES)
-	@${TCC} -o $@ -ftest-coverage $< $(DEFINES) $(CFLAGS) $(LIBS) $(LDFLAGS)
-testc: tcc_c$(EXESUF)
-	@rm -f tcc_c.tcov
-	@USE_TCC_C=yes $(MAKE) -C tests
-testc2.%: tcc_c$(EXESUF)
-	@rm -f tcc_c.tcov
-	@USE_TCC_C=yes $(MAKE) -C tests/tests2 $@
-testcpp.%: tcc_c$(EXESUF)
-	@rm -f tcc_c.tcov
-	@USE_TCC_C=yes $(MAKE) -C tests/pp $@
+	$S$(TCC) tcc.c -o $@ -ftest-coverage $(DEFINES)
 
 clean:
-	@rm -f tcc$(EXESUF) tcc_c$(EXESUF) tcc_p$(EXESUF) *-tcc$(EXESUF) tags ETAGS *.pod
-	@rm -f *.o *.a *.so* *.out *.log lib*.def *.exe *.dll a.out *.dylib *_.h
+	@rm -f tcc$(EXESUF) tcc_c$(EXESUF) tcc_p$(EXESUF) *-tcc$(EXESUF)
+	@rm -f tags ETAGS *.o *.a *.so* *.out *.log lib*.def *.exe *.dll
+	@rm -f a.out *.dylib *_.h *.pod *.tcov
 	@$(MAKE) -s -C lib $@
 	@$(MAKE) -s -C tests $@
 
 distclean: clean
-	@rm -f config.h config.mak config.texi
-	@rm -f $(TCCDOCS)
+	@rm -vf config.h config.mak config.texi
+	@rm -vf $(TCCDOCS)
 
 .PHONY: all clean test tar tags ETAGS doc distclean install uninstall FORCE
 
 help:
 	@echo "make"
 	@echo "   build native compiler (from separate objects)"
-	@echo ""
 	@echo "make cross"
 	@echo "   build cross compilers (from one source)"
-	@echo ""
 	@echo "make ONE_SOURCE=no/yes SILENT=no/yes"
 	@echo "   force building from separate/one object(s), less/more silently"
-	@echo ""
 	@echo "make cross-TARGET"
 	@echo "   build one specific cross compiler for 'TARGET'. Currently supported:"
-	@echo "      $(wordlist 1,6,$(TCC_X))"
-	@echo "      $(wordlist 7,99,$(TCC_X))"
-	@echo ""
+	@echo "   $(wordlist 1,8,$(TCC_X))"
+	@echo "   $(wordlist 9,99,$(TCC_X))"
 	@echo "make test"
 	@echo "   run all tests"
-	@echo ""
-	@echo "make tests2.all / make tests2.37 / make tests2.37+ / make tests2.37-"
-	@echo "   run all/single test(s) from tests2, optionally update .expect, display"
-	@echo ""
+	@echo "make tests2.all / make tests2.37 / make tests2.37+"
+	@echo "   run all/single test(s) from tests2, optionally update .expect"
 	@echo "make testspp.all / make testspp.17"
 	@echo "   run all/single test(s) from tests/pp"
-	@echo ""
-	@echo "make testc / testc2.all / testc2.37 / testc2.37+ / testc2.37-"
-	@echo "make testcpp.all / make testcpp.17"
-	@echo "   run tests with code coverage. After test(s) see tcc_c.tcov"
-	@echo ""
+	@echo "make tcov-test / tcov-tests2... / tcov-testspp..."
+	@echo "   run tests as above with code coverage. After test(s) see tcc_c$(EXESUF).tcov"
 	@echo "Other supported make targets:"
 	@echo "   install install-strip doc clean tags ETAGS tar distclean help"
-	@echo ""
 	@echo "Custom configuration:"
 	@echo "   The makefile includes a file 'config-extra.mak' if it is present."
 	@echo "   This file may contain some custom configuration.  For example:"
diff --git a/TODO b/TODO
index 9a38b6b2..a09c1932 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,8 @@
 TODO list:
 
 Releases:
-- release tcc on a regular basis (which interval? 3 months?)
+
+- release tcc on a regular basis
 
 Bugs:
 
diff --git a/USES b/USES
index 6d7a2d1a..f74679a4 100644
--- a/USES
+++ b/USES
@@ -7,6 +7,7 @@ bigz                   An infinite precision Z & Q library.
 gawk                   GNU awk.
 gmp                    Library for arbitrary precision arithmetic.
 gnumake                GNU makefile.
+gnu mes                using tinycc to bootstrap a system
 mpfr                   Multiple-precision floating-point library.
 mpc                    Complex floating-point library with exact rounding.
 mpv                    A free, open source, and cross-platform media player.
@@ -18,3 +19,50 @@ tcc                    Tiny CC which compiles itself.
 zlib                   Lossless data-compression library.
 
 (*) This list is ordered by name.
+
+
+
+Forks & Experiments
+-------------------
+
+arm-thumb target
+ by Erlend Sveen <erlend.sveen@hotmail.com>
+ https://git.erlendjs.no/erlendjs/tinycc.git
+
+riscv32 target
+ by Sam Ellicott <sellicott@cedarville.edu>
+ https://github.com/sellicott/tcc-riscv32.git
+
+Transputer target
+ by David Smith <agentdavo@mac.com>
+ https://github.com/agentdavo/tinycc-transputer
+
+tcc-65816 -  Tiny C Compiler for 65816 CPU (based on V0.9.23) from SNES-SDK
+ https://github.com/nArnoSNES/tcc-65816
+
+PE-UEFI arm64
+ by Andrei Warkentin <andrey.warkentin@gmail.com>
+ https://github.com/andreiw/tinycc/
+
+TCCLS - global register allocator (proof of concept)
+ by Sebastian Falbesoner <sebastian.falbesoner@gmail.com>
+ https://bitbucket.org/theStack/tccls_poc.git
+
+softfloat
+ by Giovanni Mascellani <gio@debian.org>
+ https://gitlab.com/giomasce/tinycc.git
+
+optimize 386
+ by Jason Hood <jadoxa@yahoo.com.au>
+
+tcctcl : tcl binding
+ https://code.google.com/archive/p/tcltcc/
+
+tcc4tcl : tcl binding
+ https://chiselapp.com/user/rkeene/repository/tcc4tcl/index
+
+lua-tcc : allows a Lua script to compile C code
+ https://github.com/javierguerragiraldez/lua-tcc
+
+tcclua : semi-high-level bindings for `libtcc`
+ https://github.com/nucular/tcclua/blob/master/tcc.lua
diff --git a/VERSION b/VERSION
index 9a542234..7cdd3b46 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.9.27
+0.9.28rc
\ No newline at end of file
diff --git a/configure b/configure
index 6ec98f38..a407200b 100755
--- a/configure
+++ b/configure
@@ -47,70 +47,19 @@ gcc_major=0
 gcc_minor=0
 cc_name="gcc"
 ar_set=
-darwin=
+cpu=
 cpuver=
 dwarf=
+targetos=
+build_cross=
 
-# use CC from environment when set
+# use CC/AR from environment when set
 test -n "$CC" && cc="$CC"
-
-# OS specific
-cpu=`uname -m`
-cpu_sys="$cpu"
-targetos=`uname`
-if test "$targetos" = "Linux" ; then
-  test "$(uname -o)" = "Android" && targetos=Android
-fi
-
-case $targetos in
-  Darwin)
-    darwin=yes
-    dwarf=4
-    confvars="$confvars OSX"
-    cc=`command -v cc`
-    cc=`readlink $cc || echo clang`
-    tcc_usrinclude="`xcrun --show-sdk-path`/usr/include"
-    DLLSUF=".dylib"
-    case $* in *--config-new_macho*) ;; *)
-        # if new_macho was not specified and (known) ver <= 10, use old (=no)
-        osxver=$(sw_vers -productVersion 2>/dev/null)  # X.Y.Z
-        osxver=${osxver%%.*}  # major version (or empty on sw_vers error)
-        [ "${osxver:-11}" -ge 11 ] || confvars="$confvars new_macho=no"
-    esac
-    ;;
-  Windows_NT|MINGW*|MSYS*|CYGWIN*)
-    mingw32=yes
-    targetos=WIN32
-    ;;
-  DragonFly|OpenBSD|FreeBSD|NetBSD)
-    confvars="$confvars BSD ldl=no"
-    ;;
-  Android)
-    confvars="$confvars Android pie new-dtags"
-    if test -n "$TERMUX_VERSION"; then
-      prefix="$PREFIX" # "/data/data/com.termux/files/usr"
-      sysroot="$PREFIX"
-      test "$cpu" = "aarch64" -o "$cpu" = "x86_64" && S="64" || S=""
-      tcc_sysincludepaths="{B}/include:{R}/include/\\\"CONFIG_TRIPLET\\\":{R}/include"
-      tcc_libpaths="{B}:{R}/lib:/system/lib${S}"
-      tcc_crtprefix="{R}/lib"
-      tcc_elfinterp="/system/bin/linker${S}"
-      use_triplet="yes"
-      tcc_switches="-Wl,-rpath=$sysroot/lib,-section-alignment=0x1000"
-    fi
-    ;;
-  *)
-    ;;
-esac
+test -n "$AR" && ar="$AR"
 
 # find source path
 source_path=${0%configure}
 source_path=${source_path%/}
-source_path_used="yes"
-if test -z "$source_path" -o "$source_path" = "." ; then
-    source_path=`pwd`
-    source_path_used="no"
-fi
 
 for opt do
   eval opt=\"$opt\"
@@ -137,6 +86,8 @@ for opt do
   ;;
   --sysroot=*) sysroot=`echo $opt | cut -d '=' -f 2-`
   ;;
+  --targetos=*) targetos=`echo $opt | cut -d '=' -f 2-`
+  ;;
   --source-path=*) source_path=`echo $opt | cut -d '=' -f 2-`
   ;;
   --cross-prefix=*) cross_prefix=`echo $opt | cut -d '=' -f 2-`
@@ -192,16 +143,119 @@ for opt do
   esac
 done
 
-cc="${cross_prefix}${cc}"
-ar="${cross_prefix}${ar}"
+show_help() {
+cat << EOF
+Usage: configure [options]
+Options: [defaults in brackets after descriptions]
 
-# Checking for CFLAGS
-test -z "$CFLAGS" && CFLAGS="-Wall -O2"
+Standard options:
+  --help                   print this message
+  --prefix=PREFIX          install in PREFIX [$prefix]
+  --exec-prefix=EPREFIX    install architecture-dependent files in EPREFIX
+			   [same as prefix]
+  --bindir=DIR             user executables in DIR [EPREFIX/bin]
+  --libdir=DIR             object code libraries in DIR [EPREFIX/lib]
+  --tccdir=DIR             installation directory [EPREFIX/lib/tcc]
+  --includedir=DIR         C header files in DIR [PREFIX/include]
+  --sharedir=DIR           documentation root DIR [PREFIX/share]
+  --docdir=DIR             documentation in DIR [SHAREDIR/doc/tcc]
+  --mandir=DIR             man documentation in DIR [SHAREDIR/man]
+  --infodir=DIR            info documentation in DIR [SHAREDIR/info]
 
-# on OSX M1 with --cpu=x86_64, build a tcc to run under rosetta entirely
-if test "$darwin" = "yes" -a "$cpu" = "x86_64" -a "$cpu_sys" = "arm64"; then
-    CFLAGS="$CFLAGS -arch $cpu"
-    LDFLAGS="$LDFLAGS -arch $cpu"
+Advanced options (experts only):
+  --source-path=PATH       path of source code [$source_path]
+  --sysroot=PREFIX         prepend PREFIX to library/include paths [$sysroot]
+  --cc=CC                  use C compiler CC [$cc]
+  --ar=AR                  create archives using AR [$ar]
+  --extra-cflags=          specify compiler flags [$CFLAGS]
+  --extra-ldflags=         specify linker options [$LDFLAGS]
+
+  --debug                  include debug info with resulting binaries
+  --disable-static         make libtcc.so instead of libtcc.a
+  --enable-static          make libtcc.a instead of libtcc.dll (win32)
+  --disable-rpath          disable use of -rpath with libtcc.so
+  --with-libgcc            use libgcc_s.so.1 instead of libtcc1.a
+  --with-selinux           use mmap for executable memory (tcc -run)
+  --enable-cross           build cross compilers (see also 'make help')
+
+  --sysincludepaths=...    specify system include paths, colon separated
+  --libpaths=...           specify system library paths, colon separated
+  --crtprefix=...          specify locations of crt?.o, colon separated
+  --elfinterp=...          specify elf interpreter
+  --triplet=...            specify system library/include directory triplet
+  --tcc-switches=...       specify implicit switches passed to tcc
+
+  --config-uClibc,-musl    enable system specific configurations
+  --config-mingw32         build on windows using msys, busybox, etc.
+  --config-backtrace=no    disable stack backtraces (with -run or -bt)
+  --config-bcheck=no       disable bounds checker (-b)
+  --config-predefs=no      do not compile tccdefs.h, instead just include
+  --config-new_macho=no|yes Force apple object format (autodetect osx <= 10)
+  --config-codesign        Use codesign on apple to sign executables
+  --dwarf=x                Use dwarf debug info instead of stabs (x=2..5)
+
+Cross build options (experimental):
+  --cpu=CPU                target CPU [$cpu]
+  --targetos=...           target OS (Darwin,WIN32,Android/Termux) [$targetos]
+  --cross-prefix=PREFIX    use PREFIX for compile tools [$cross_prefix]
+EOF
+exit 1
+}
+
+default() # set variable unless already set
+{
+    local v
+    eval v=\"\$$1\"
+    test -z "$v" && eval $1=\"$2\"
+}
+
+default_conf() # add to confvars unless already present
+{
+    local v=${1%=*}
+    test "${confvars%$v*}" = "${confvars}" && confvars="$confvars $1"
+}
+
+if test -z "$source_path" -o "$source_path" = "." ; then
+  source_path=$(pwd)
+  source_path_used="no"
+else
+  source_path_used="yes"
+fi
+
+# OS specific
+buildos=$(uname)
+
+case $buildos in
+  Windows_NT|MINGW*|MSYS*|CYGWIN*)
+    buildos="WIN32"
+  ;;
+  Linux)
+    if test "$(uname -o)" = "Android"; then
+      buildos=Android
+      if test -n "$TERMUX_VERSION"; then
+        buildos=Termux
+      fi
+    fi
+  ;;
+esac
+
+if test "$mingw32" = "yes"; then
+  default targetos WIN32
+else
+  default targetos "$buildos"
+fi
+
+cpu_sys=$(uname -m)
+default cpu "$cpu_sys"
+cpu_set="$cpu"
+
+# check for crpss build
+if test "$cpu_set" != "$cpu_sys" \
+  -o "$targetos" != "$buildos" \
+  -o -n "$cross_prefix" ; then
+  build_cross="yes"
+  cc="${cross_prefix}${cc}"
+  ar="${cross_prefix}${ar}"
 fi
 
 case "$cpu" in
@@ -262,109 +316,101 @@ case "$cpu" in
   ;;
 esac
 
-if test "$mingw32" = "yes" ; then
-    if test "$source_path_used" = "no"; then
-      source_path="."
+case $targetos in
+  Darwin)
+    dwarf=4
+    confvars="$confvars OSX"
+    DLLSUF=".dylib"
+    if test -z "$build_cross"; then
+      cc=`command -v cc`
+      cc=`readlink $cc || echo clang`
+      tcc_usrinclude="`xcrun --show-sdk-path`/usr/include"
+      if test "${confvars%new_macho*}" = "${confvars}"; then
+          # if new_macho was not specified and (known) ver <= 10, use old (=no)
+          osxver=$(sw_vers -productVersion 2>/dev/null)  # X.Y.Z
+          osxver=${osxver%%.*}  # major version (or empty on sw_vers error)
+          [ "${osxver:-11}" -ge 11 ] || confvars="$confvars new_macho=no"
+      fi
     fi
-    test -z "$prefix" && prefix="C:/Program Files/tcc"
-    test -z "$tccdir" && tccdir="${prefix}" && tccdir_auto="yes"
-    test -z "$bindir" && bindir="${tccdir}"
-    test -z "$docdir" && docdir="${tccdir}/doc"
-    test -z "$libdir" && libdir="${tccdir}/libtcc"
+    # on OSX M1 with --cpu=x86_64, build a tcc to run under rosetta entirely
+    if test "$cpu" = "x86_64" -a "$cpu_sys" = "arm64"; then
+        CFLAGS="$CFLAGS -arch $cpu"
+        LDFLAGS="$LDFLAGS -arch $cpu"
+    fi
+    ;;
+  DragonFly|OpenBSD|FreeBSD|NetBSD)
+    confvars="$confvars BSD ldl=no"
+    ;;
+  Android|Termux)
+    if test "$targetos" = "Termux"; then
+      targetos=Android
+      default sysroot "/data/data/com.termux/files/usr"
+    else
+      default sysroot "/usr"
+    fi
+    default prefix "${sysroot}"
+    confvars="$confvars Android new-dtags rpath=no"
+    test "${cpu}" != "i386" && confvars="$confvars pie"
+    default_conf "static=no"
+    if test "${cpu}" = "arm"; then
+      default triplet "arm-linux-androideabi"
+      cpuver=7
+    else
+      default triplet "${cpu_set}-linux-android"
+    fi
+    test "${cpu%64}" != "${cpu}" && S="64" || S=""
+    default tcc_sysincludepaths "{B}/include:{R}/include:{R}/include/${triplet}"
+    default tcc_libpaths "{B}:{R}/lib:/system/lib${S}"
+    default tcc_crtprefix "{R}/lib"
+    default tcc_elfinterp "/system/bin/linker${S}"
+    default tcc_switches "-Wl,-rpath=$sysroot/lib,-section-alignment=0x1000"
+    ;;
+  WIN32)
+    mingw32="yes"
     confvars="$confvars WIN32"
+    default prefix "C:/Program Files/tcc"
+    default tccdir "${prefix}"
+    default bindir "${tccdir}"
+    default docdir "${tccdir}/doc"
+    default libdir "${tccdir}/libtcc"
+    test "$tccdir" = "$bindir" && tccdir_auto="yes"
     LIBSUF=".lib"
     EXESUF=".exe"
     DLLSUF=".dll"
-else
-    if test -z "$prefix" ; then
-      prefix="/usr/local"
+    if test "$source_path_used" = "no"; then
+      source_path="."
     fi
-    if test -z "$sharedir" ; then
-      sharedir="${prefix}/share"
-    fi
-    if test x"$execprefix" = x""; then
-      execprefix="${prefix}"
-    fi
-    if test x"$libdir" = x""; then
-      libdir="${execprefix}/lib"
-    fi
-    if test x"$bindir" = x""; then
-      bindir="${execprefix}/bin"
-    fi
-    if test x"$docdir" = x""; then
-      docdir="${sharedir}/doc"
-    fi
-    if test x"$mandir" = x""; then
-      mandir="${sharedir}/man"
-    fi
-    if test x"$infodir" = x""; then
-      infodir="${sharedir}/info"
-    fi
-    if test x"$tccdir" = x""; then
-      tccdir="${libdir}/tcc"
-    fi
-    if test x"$includedir" = x""; then
-      includedir="${prefix}/include"
-    fi
-fi # mingw32
+    ;;
+  *)
+    ;;
+esac
 
-if test x"$show_help" = "xyes" ; then
-cat << EOF
-Usage: configure [options]
-Options: [defaults in brackets after descriptions]
-
-Standard options:
-  --help                   print this message
-  --prefix=PREFIX          install in PREFIX [$prefix]
-  --exec-prefix=EPREFIX    install architecture-dependent files in EPREFIX
-			   [same as prefix]
-  --bindir=DIR             user executables in DIR [EPREFIX/bin]
-  --libdir=DIR             object code libraries in DIR [EPREFIX/lib]
-  --tccdir=DIR             installation directory [EPREFIX/lib/tcc]
-  --includedir=DIR         C header files in DIR [PREFIX/include]
-  --sharedir=DIR           documentation root DIR [PREFIX/share]
-  --docdir=DIR             documentation in DIR [SHAREDIR/doc/tcc]
-  --mandir=DIR             man documentation in DIR [SHAREDIR/man]
-  --infodir=DIR            info documentation in DIR [SHAREDIR/info]
-
-Advanced options (experts only):
-  --source-path=PATH       path of source code [$source_path]
-  --cross-prefix=PREFIX    use PREFIX for compile tools [$cross_prefix]
-  --sysroot=PREFIX         prepend PREFIX to library/include paths [$sysroot]
-  --cc=CC                  use C compiler CC [$cc]
-  --ar=AR                  create archives using AR [$ar]
-  --extra-cflags=          specify compiler flags [$CFLAGS]
-  --extra-ldflags=         specify linker options [$LDFLAGS]
-  --cpu=CPU                CPU [$cpu]
-
-  --debug                  include debug info with resulting binaries
-  --disable-static         make libtcc.so instead of libtcc.a
-  --enable-static          make libtcc.a instead of libtcc.dll (win32)
-  --disable-rpath          disable use of -rpath with libtcc.so
-  --with-libgcc            use libgcc_s.so.1 instead of libtcc1.a
-  --with-selinux           use mmap for executable memory (tcc -run)
-  --enable-cross           build cross compilers (see also 'make help')
-
-  --sysincludepaths=...    specify system include paths, colon separated
-  --libpaths=...           specify system library paths, colon separated
-  --crtprefix=...          specify locations of crt?.o, colon separated
-  --elfinterp=...          specify elf interpreter
-  --triplet=...            specify system library/include directory triplet
-  --tcc-switches=...       specify implicit switches passed to tcc
-
-  --config-uClibc,-musl    enable system specific configurations
-  --config-mingw32         build on windows using msys, busybox, etc.
-  --config-backtrace=no    disable stack backtraces (with -run or -bt)
-  --config-bcheck=no       disable bounds checker (-b)
-  --config-predefs=no      do not compile tccdefs.h, instead just include
-  --config-new_macho=no|yes Force apple object format (autodetect osx <= 10)
-  --config-codesign        Use codesign on apple to sign executables
-  --dwarf=x                Use dwarf debug info instead of stabs (x=2..5)
-EOF
-exit 1
+if test "$mingw32" = "no"; then
+  default prefix       "/usr/local"
+  default execprefix   "${prefix}"
+  default libdir       "${execprefix}/lib"
+  default bindir       "${execprefix}/bin"
+  default tccdir       "${libdir}/tcc"
+  default includedir   "${prefix}/include"
+  default sharedir     "${prefix}/share"
+  default docdir       "${sharedir}/doc"
+  default mandir       "${sharedir}/man"
+  default infodir      "${sharedir}/info"
 fi
 
-if test -z "$cross_prefix" ; then
+# set default CFLAGS
+default CFLAGS "-Wall -O2"
+
+if test "$mingw32" = "yes" -a "$cc_name" = "gcc"; then
+  # avoid mingw dependencies such as 'libgcc_s_dw2-1.dll'
+  default LDFLAGS "-static"
+fi
+
+if test x"$show_help" = "xyes" ; then
+    show_help
+fi
+
+if test -z "$build_cross"; then
   CONFTEST=./conftest$EXESUF
   if ! $cc -o $CONFTEST $source_path/conftest.c ; then
     echo "configure: error: '$cc' failed to compile conftest.c."
@@ -376,13 +422,11 @@ if test -z "$cross_prefix" ; then
     _triplet="$($CONFTEST triplet)"
   fi
   if test "$mingw32" = "no" ; then
-
       if test -z "$triplet" -a -n "$_triplet"; then
-        if test -f "/usr/lib/$_triplet/crti.o" -o -n "$use_triplet" ; then
+        if test -f "/usr/lib/$_triplet/crti.o"; then
           triplet="$_triplet"
         fi
       fi
-
       if test -z "$triplet"; then
         if test $cpu = "x86_64" -o $cpu = "arm64" -o $cpu = "riscv64" ; then
           if test -f "/usr/lib64/crti.o" ; then
@@ -390,21 +434,6 @@ if test -z "$cross_prefix" ; then
           fi
         fi
       fi
-
-      if test "$cpu" = "arm" ; then
-	if test "${triplet%eabihf}" != "$triplet" ; then
-	   confvars="$confvars arm_eabihf arm_vfp"
-	elif test "${triplet%eabi}" != "$triplet" ; then
-	   confvars="$confvars arm_eabi arm_vfp"
-	elif test "${_triplet%eabihf}" != "$_triplet" ; then
-	   confvars="$confvars arm_eabihf arm_vfp"
-	elif test "${_triplet%eabi}" != "$_triplet" ; then
-	   confvars="$confvars arm_eabi arm_vfp"
-	elif grep -s -q "^Features.* \(vfp\|iwmmxt\) " /proc/cpuinfo ; then
-	   confvars="$confvars arm_vfp"
-	fi
-      fi
-
       if test "$suggest" = "yes"; then
         if test -f "/lib/ld-uClibc.so.0" ; then
           echo "Perhaps you want ./configure --config-uClibc"
@@ -413,23 +442,43 @@ if test -z "$cross_prefix" ; then
           echo "Perhaps you want ./configure --config-musl"
         fi
       fi
-  else # mingw32 = yes
-      if test "$cc_name" = "gcc"; then
-        # avoid mingw dependencies such as 'libgcc_s_dw2-1.dll'
-        test -z "$LDFLAGS" && LDFLAGS="-static"
-      fi
   fi
 else
-  # if cross compiling, cannot launch a program, so make a static guess
+  # can only make guesses about compiler and target
+  if test "${cc%tcc*}" != "$cc"; then
+    cc_name="tcc"
+  elif test "${cc%clang*}" != "$cc"; then
+    cc_name="clang"
+  fi
   case $cpu in
     ppc|mips|s390)  bigendian=yes;;
   esac
+  case $targetos in
+    Linux)
+      default triplet "$cpu_set-linux-gnu"
+  esac
 fi
 
 if test "$bigendian" = "yes" ; then
   confvars="$confvars BIGENDIAN"
 fi
 
+if test "$cpu" = "arm"; then
+  if test "${triplet%eabihf}" != "$triplet" ; then
+    confvars="$confvars arm_eabihf arm_vfp"
+  elif test "${triplet%eabi}" != "$triplet" ; then
+    confvars="$confvars arm_eabi arm_vfp"
+  elif test -z "$build_cross"; then
+    if test "${_triplet%eabihf}" != "$_triplet" ; then
+      confvars="$confvars arm_eabihf arm_vfp"
+    elif test "${_triplet%eabi}" != "$_triplet" ; then
+      confvars="$confvars arm_eabi arm_vfp"
+    elif grep -s -q "^Features.* \(vfp\|iwmmxt\) " /proc/cpuinfo ; then
+      confvars="$confvars arm_vfp"
+    fi
+  fi
+fi
+
 # a final configuration tuning
 if test "$cc_name" != "tcc"; then
   OPT1="-Wdeclaration-after-statement -fno-strict-aliasing"
@@ -438,7 +487,7 @@ if test "$cc_name" != "tcc"; then
   OPT2="$OPT2 -Wstringop-truncation"
   if test "$cc_name" = "clang"; then
     OPT1="$OPT1 -fheinous-gnu-extensions"
-    OPT2="$OPT2 -Wstring-plus-int"
+    OPT2="$OPT2 -Wstring-plus-int -Wdeprecated-declarations"
   fi
   $cc $OPT1 $OPT2 -o a.out -c -xc - < /dev/null > cc_msg.txt 2>&1
   for o in $OPT1; do # enable these options
@@ -470,6 +519,11 @@ echo "C compiler          $cc ($gcc_major.$gcc_minor)"
 echo "Target OS           $targetos"
 echo "CPU                 $cpu"
 fcho "Triplet             " "$triplet"
+fcho "Libs                " "$tcc_libpaths"
+fcho "Sysinclude          " "$tcc_sysincludepaths"
+fcho "Crt                 " "$tcc_crtprefix"
+fcho "Elfinterp           " "$tcc_elfinterp"
+fcho "Switches            " "$tcc_switches"
 fcho "Config              " "${confvars# }"
 echo "Creating config.mak and config.h"
 
@@ -530,6 +584,7 @@ print_mak TCC_CPU_VERSION "$cpuver" num
 
 echo "ARCH=$cpu" >> config.mak
 echo "TARGETOS=$targetos" >> config.mak
+echo "BUILDOS=$buildos" >> config.mak
 
 predefs="1"
 for v in $confvars ; do
diff --git a/conftest.c b/conftest.c
index ad7275cf..a4450d51 100644
--- a/conftest.c
+++ b/conftest.c
@@ -1,8 +1,8 @@
 /* ----------------------------------------------------------------------- */
-#if C2STR
-
 /* with -D C2STR: convert tccdefs.h to C-strings */
 
+#if C2STR
+
 #include <stdio.h>
 #include <string.h>
 
@@ -166,14 +166,16 @@ int main(int argc, char **argv)
 }
 
 /* ----------------------------------------------------------------------- */
-#elif 1
-
 /* get some information from the host compiler for configure */
 
+#elif 1
+
 #include <stdio.h>
 
 #if defined(_WIN32)
 #include <fcntl.h>
+#include <io.h>
+int _CRT_glob = 0;
 #endif
 
 /* Define architecture */
@@ -233,10 +235,6 @@ int main(int argc, char **argv)
 # define TRIPLET TRIPLET_ARCH "-" TRIPLET_OS "-" TRIPLET_ABI
 #endif
 
-#if defined(_WIN32)
-int _CRT_glob = 0;
-#endif
-
 int main(int argc, char *argv[])
 {
 #if defined(_WIN32)
diff --git a/tcc-doc.texi b/tcc-doc.texi
index 411cdd56..8d172c2a 100644
--- a/tcc-doc.texi
+++ b/tcc-doc.texi
@@ -364,10 +364,11 @@ bounds (@pxref{Bounds}). @option{-g} is implied.
 
 @item -bt[N]
 Display N callers in stack traces. This is useful with @option{-g} or @option{-b}.
-With executables, additional support for stack traces is included.
+When activated, @code{__TCC_BACKTRACE__} is defined.
 
-A function @code{ int tcc_backtrace(const char *fmt, ...); } is provided
-to trigger a stack trace with a message on demand.
+With executables, additional support for stack traces is included. A function
+    @code{ int tcc_backtrace(const char *fmt, ...); }
+is provided to trigger a stack trace with a message on demand.
 
 @end table
 
@@ -937,7 +938,7 @@ Here are some examples of caught errors:
 @end example
 @end table
 
-TCC defines @code{__BOUNDS_CHECKING_ON} if activated.
+TCC defines @code{__TCC_BCHECK__} if activated.
 
 There are five environment variables that can be used to control the behavior:
 @itemize
@@ -984,7 +985,7 @@ for bounds checking errors.
 @end itemize
 
 @example
-#if defined(__TINYC__) && __BOUNDS_CHECKING_ON
+#ifdef __TCC_BCHECK__
 extern void __bounds_checking (int x);
 # define BOUNDS_CHECKING_OFF __bounds_checking(1)
 # define BOUNDS_CHECKING_ON  __bounds_checking(-1)
diff --git a/tests/pp/Makefile b/tests/pp/Makefile
index 39441507..224c866d 100644
--- a/tests/pp/Makefile
+++ b/tests/pp/Makefile
@@ -10,7 +10,7 @@ VPATH = $(SRC)
 files = $(patsubst %.$1,%.test,$(notdir $(wildcard $(SRC)/*.$1)))
 TESTS = $(call files,c) $(call files,S)
 
-all test testspp.all testcpp.all: $(sort $(TESTS))
+all test testspp.all: $(sort $(TESTS))
 
 DIFF_OPTS = -Nu -b
 
@@ -29,7 +29,7 @@ FILTER = 2>&1 | sed 's,$(SRC)/,,g'
 	    diff $(DIFF_OPTS) $(SRC)/$*.expect $*.output \
 	    && rm -f $*.output
 
-testspp.% testcpp.%: %.test ;
+testspp.%: %.test ;
 
 # automatically generate .expect files with gcc:
 %.expect: # %.c
diff --git a/tests/tests2/Makefile b/tests/tests2/Makefile
index 1d8ed72a..ebb271ab 100644
--- a/tests/tests2/Makefile
+++ b/tests/tests2/Makefile
@@ -124,7 +124,7 @@ endif
 # Filter source directory in warnings/errors (out-of-tree builds)
 FILTER = 2>&1 | sed -e 's,$(SRC)/,,g'
 
-all test tests2.all testc2.all: $(filter-out $(SKIP),$(TESTS))
+all test tests2.all: $(filter-out $(SKIP),$(TESTS))
 	@$(MAKE) clean --no-print-directory -s
 
 %.test: %.c %.expect
@@ -138,15 +138,15 @@ T3 = $(FILTER) >$*.output 2>&1 || true \
      && rm -f $*.output $(filter $*.expect,$(GEN-ALWAYS))
 
 # run single test and update .expect file, e.g. "make tests2.37+"
-tests2.%+ testc2.%+:
+tests2.%+:
 	@$(MAKE) $(call F2,$(call F1,$*)) --no-print-directory
 
 # just run tcc to see the output, e.g. "make tests2.37-"
-tests2.%- testc2.%-:
+tests2.%-:
 	@$(MAKE) $(call F1,$*) T3= --no-print-directory
 
 # run single test, e.g. "make tests2.37"
-tests2.% testc2.%:
+tests2.%:
 	@$(MAKE) $(call F1,$*) --no-print-directory
 
 F1 = $(or $(filter $1_%,$(TESTS)),$1_???.test)
diff --git a/win32/build-tcc.bat b/win32/build-tcc.bat
index 83730169..147823e2 100644
--- a/win32/build-tcc.bat
+++ b/win32/build-tcc.bat
@@ -7,7 +7,8 @@ setlocal
 if (%1)==(-clean) goto :cleanup
 set CC=gcc
 set /p VERSION= < ..\VERSION
-set INST=
+set TCCDIR=
+set BINDIR=
 set DOC=no
 set EXES_ONLY=no
 goto :a0
@@ -23,7 +24,8 @@ goto :a2
 :a1
 if (%1)==(-t) set T=%2&& goto :a2
 if (%1)==(-v) set VERSION=%~2&& goto :a2
-if (%1)==(-i) set INST=%2&& goto :a2
+if (%1)==(-i) set TCCDIR=%2&& goto :a2
+if (%1)==(-b) set BINDIR=%2&& goto :a2
 if (%1)==(-d) set DOC=yes&& goto :a3
 if (%1)==(-x) set EXES_ONLY=yes&& goto :a3
 if (%1)==() goto :p1
@@ -35,6 +37,7 @@ echo   -c "prog options"    use prog with options to compile tcc
 echo   -t 32/64             force 32/64 bit default target
 echo   -v "version"         set tcc version
 echo   -i tccdir            install tcc into tccdir
+echo   -b bindir            but install tcc.exe and libtcc.dll into bindir
 echo   -d                   create tcc-doc.html too (needs makeinfo)
 echo   -x                   just create the executables
 echo   -clean               delete all previously produced files and directories
@@ -87,18 +90,24 @@ if %PROCESSOR_ARCHITECTURE%_==AMD64_ set T=64
 if %PROCESSOR_ARCHITEW6432%_==AMD64_ set T=64
 :p2
 if "%CC:~-3%"=="gcc" set CC=%CC% -O2 -s -static
+if (%BINDIR%)==() set BINDIR=%TCCDIR%
+
 set D32=-DTCC_TARGET_PE -DTCC_TARGET_I386
 set D64=-DTCC_TARGET_PE -DTCC_TARGET_X86_64
 set P32=i386-win32
 set P64=x86_64-win32
+
 if %T%==64 goto :t64
 set D=%D32%
+set P=%P32%
 set DX=%D64%
 set PX=%P64%
 set TX=64
 goto :p3
+
 :t64
 set D=%D64%
+set P=%P64%
 set DX=%D32%
 set PX=%P32%
 set TX=32
@@ -111,17 +120,16 @@ for /f %%b in ('git.exe rev-parse --abbrev-ref HEAD') do set GITHASH=%%b
 for /f %%b in ('git.exe log -1 "--pretty=format:%%cs_%GITHASH%@%%h"') do set GITHASH=%%b
 git.exe diff --quiet
 if %ERRORLEVEL%==1 set GITHASH=%GITHASH%*
-set DEF_GITHASH=-DTCC_GITHASH="""%GITHASH%"""
 :git_done
-
 @echo on
 
 :config.h
 echo>..\config.h #define TCC_VERSION "%VERSION%"
-echo>> ..\config.h #ifdef TCC_TARGET_X86_64
-echo>> ..\config.h #define TCC_LIBTCC1 "libtcc1-64.a"
-echo>> ..\config.h #else
-echo>> ..\config.h #define TCC_LIBTCC1 "libtcc1-32.a"
+if not (%GITHASH%)==() echo>> ..\config.h #define TCC_GITHASH "%GITHASH%"
+@if not (%BINDIR%)==(%TCCDIR%) echo>> ..\config.h #define CONFIG_TCCDIR "%TCCDIR:\=/%"
+if %TX%==64 echo>> ..\config.h #ifdef TCC_TARGET_X86_64
+if %TX%==32 echo>> ..\config.h #ifdef TCC_TARGET_I386
+echo>> ..\config.h #define CONFIG_TCC_CROSSPREFIX "%PX%-"
 echo>> ..\config.h #endif
 
 for %%f in (*tcc.exe *tcc.dll) do @del %%f
@@ -135,7 +143,7 @@ for %%f in (*tcc.exe *tcc.dll) do @del %%f
 @if _%LIBTCC_C%_==__ set LIBTCC_C=..\libtcc.c
 %CC% -o libtcc.dll -shared %LIBTCC_C% %D% -DLIBTCC_AS_DLL
 @if errorlevel 1 goto :the_end
-%CC% -o tcc.exe ..\tcc.c libtcc.dll %D% -DONE_SOURCE"=0" %DEF_GITHASH%
+%CC% -o tcc.exe ..\tcc.c libtcc.dll %D% -DONE_SOURCE"=0"
 %CC% -o %PX%-tcc.exe ..\tcc.c %DX%
 :compiler_done
 @if (%EXES_ONLY%)==(yes) goto :files_done
@@ -151,15 +159,9 @@ copy>nul tcc-win32.txt doc
 if exist libtcc.dll .\tcc -impdef libtcc.dll -o libtcc\libtcc.def
 @if errorlevel 1 goto :the_end
 
-:libtcc1.a
-call :makelib %T%
-@if errorlevel 1 goto :the_end
-@if exist %PX%-tcc.exe call :makelib %TX%
-@if errorlevel 1 goto :the_end
-.\tcc -m%T% -c ../lib/bcheck.c -o lib/bcheck.o -bt
-.\tcc -m%T% -c ../lib/bt-exe.c -o lib/bt-exe.o
-.\tcc -m%T% -c ../lib/bt-log.c -o lib/bt-log.o
-.\tcc -m%T% -c ../lib/bt-dll.c -o lib/bt-dll.o
+:lib
+call :make_lib %T% || goto :the_end
+@if exist %PX%-tcc.exe call :make_lib %TX% %PX%- || goto :the_end
 
 :tcc-doc.html
 @if not (%DOC%)==(yes) goto :doc-done
@@ -171,27 +173,32 @@ cmd /c makeinfo --html --no-split ../tcc-doc.texi -o doc/tcc-doc.html
 for %%f in (*.o *.def) do @del %%f
 
 :copy-install
-@if (%INST%)==() goto :the_end
-if not exist %INST% mkdir %INST%
-for %%f in (*tcc.exe *tcc.dll) do @copy>nul %%f %INST%\%%f
-@if not exist %INST%\lib mkdir %INST%\lib
-for %%f in (lib\*.a lib\*.o lib\*.def) do @copy>nul %%f %INST%\%%f
-for %%f in (include examples libtcc doc) do @xcopy>nul /s/i/q/y %%f %INST%\%%f
+@if (%TCCDIR%)==() goto :the_end
+if not exist %BINDIR% mkdir %BINDIR%
+for %%f in (*tcc.exe *tcc.dll) do @copy>nul %%f %BINDIR%\%%f
+if not exist %TCCDIR% mkdir %TCCDIR%
+@if not exist %TCCDIR%\lib mkdir %TCCDIR%\lib
+for %%f in (lib\*.a lib\*.o lib\*.def) do @copy>nul %%f %TCCDIR%\%%f
+for %%f in (include examples libtcc doc) do @xcopy>nul /s/i/q/y %%f %TCCDIR%\%%f
 
 :the_end
 exit /B %ERRORLEVEL%
 
-:makelib
-.\tcc -m%1 -c ../lib/libtcc1.c
-.\tcc -m%1 -c lib/crt1.c
-.\tcc -m%1 -c lib/crt1w.c
-.\tcc -m%1 -c lib/wincrt1.c
-.\tcc -m%1 -c lib/wincrt1w.c
-.\tcc -m%1 -c lib/dllcrt1.c
-.\tcc -m%1 -c lib/dllmain.c
-.\tcc -m%1 -c lib/chkstk.S
-.\tcc -m%1 -c ../lib/alloca.S
-.\tcc -m%1 -c ../lib/alloca-bt.S
-.\tcc -m%1 -c ../lib/stdatomic.c
-.\tcc -m%1 -ar lib/libtcc1-%1.a libtcc1.o crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o chkstk.o alloca.o alloca-bt.o stdatomic.o
+:make_lib
+.\tcc -B. -m%1 -c ../lib/libtcc1.c
+.\tcc -B. -m%1 -c lib/crt1.c
+.\tcc -B. -m%1 -c lib/crt1w.c
+.\tcc -B. -m%1 -c lib/wincrt1.c
+.\tcc -B. -m%1 -c lib/wincrt1w.c
+.\tcc -B. -m%1 -c lib/dllcrt1.c
+.\tcc -B. -m%1 -c lib/dllmain.c
+.\tcc -B. -m%1 -c lib/chkstk.S
+.\tcc -B. -m%1 -c ../lib/alloca.S
+.\tcc -B. -m%1 -c ../lib/alloca-bt.S
+.\tcc -B. -m%1 -c ../lib/stdatomic.c
+.\tcc -B. -m%1 -ar lib/%2libtcc1.a libtcc1.o crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o chkstk.o alloca.o alloca-bt.o stdatomic.o
+.\tcc -B. -m%1 -c ../lib/bcheck.c -o lib/%2bcheck.o -bt
+.\tcc -B. -m%1 -c ../lib/bt-exe.c -o lib/%2bt-exe.o
+.\tcc -B. -m%1 -c ../lib/bt-log.c -o lib/%2bt-log.o
+.\tcc -B. -m%1 -c ../lib/bt-dll.c -o lib/%2bt-dll.o
 exit /B %ERRORLEVEL%