mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Improve build system
- Reduce full build latency from ~20s to ~18s - Bring back silent mode if `make V=0` is passed - Demodernize utimes() polyfill so it works RHEL5 - Delete some old shell scripts that are no longer needed - Truncate long lines when outputting builds to Emacs buffers
This commit is contained in:
parent
c797f139bb
commit
b740cca642
39 changed files with 440 additions and 916 deletions
8
Makefile
8
Makefile
|
@ -215,15 +215,15 @@ o/$(MODE)/hdrs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(HDRS) $(
|
||||||
$(file >$@) $(foreach x,$(HDRS) $(INCS),$(file >>$@,$(x)))
|
$(file >$@) $(foreach x,$(HDRS) $(INCS),$(file >>$@,$(x)))
|
||||||
|
|
||||||
o/$(MODE)/depend: o/$(MODE)/.x o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt $(SRCS) $(HDRS) $(INCS)
|
o/$(MODE)/depend: o/$(MODE)/.x o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt $(SRCS) $(HDRS) $(INCS)
|
||||||
@build/mkdeps -o $@ -r o/$(MODE)/ o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt
|
@$(COMPILE) -AMKDEPS $(MKDEPS) -o $@ -r o/$(MODE)/ o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt
|
||||||
|
|
||||||
TAGS: o/$(MODE)/srcs.txt $(SRCS)
|
TAGS: o/$(MODE)/srcs.txt $(SRCS)
|
||||||
@rm -f $@
|
@rm -f $@
|
||||||
@ACTION=TAGS TARGET=$@ build/do $(TAGS) $(TAGSFLAGS) -L $< -o $@
|
@$(COMPILE) -ATAGS -T$@ $(TAGS) $(TAGSFLAGS) -L $< -o $@
|
||||||
|
|
||||||
HTAGS: o/$(MODE)/hdrs.txt $(HDRS)
|
HTAGS: o/$(MODE)/hdrs.txt $(HDRS)
|
||||||
@rm -f $@
|
@rm -f $@
|
||||||
@ACTION=TAGS TARGET=$@ build/do build/htags -L $< -o $@
|
@$(COMPILE) -ATAGS -T$@ build/htags -L $< -o $@
|
||||||
|
|
||||||
loc: o/$(MODE)/tool/build/summy.com
|
loc: o/$(MODE)/tool/build/summy.com
|
||||||
find -name \*.h -or -name \*.c -or -name \*.S | \
|
find -name \*.h -or -name \*.c -or -name \*.S | \
|
||||||
|
@ -315,7 +315,7 @@ o/cosmopolitan.h: \
|
||||||
o/$(MODE)/tool/build/rollup.com \
|
o/$(MODE)/tool/build/rollup.com \
|
||||||
libc/integral/normalize.inc \
|
libc/integral/normalize.inc \
|
||||||
$(foreach x,$(COSMOPOLITAN_HEADERS),$($(x)_HDRS))
|
$(foreach x,$(COSMOPOLITAN_HEADERS),$($(x)_HDRS))
|
||||||
@ACTION=ROLLUP TARGET=$@ build/do $^ >$@
|
@$(COMPILE) -AROLLUP -T$@ $^ >$@
|
||||||
|
|
||||||
o/cosmopolitan.html: \
|
o/cosmopolitan.html: \
|
||||||
o/$(MODE)/third_party/chibicc/chibicc.com.dbg \
|
o/$(MODE)/third_party/chibicc/chibicc.com.dbg \
|
||||||
|
|
|
@ -1522,7 +1522,7 @@ metal.thunk:
|
||||||
.byte 0x0f,0x1f,0207 # nop rdi binbase
|
.byte 0x0f,0x1f,0207 # nop rdi binbase
|
||||||
.long (IMAGE_BASE_VIRTUAL-IMAGE_BASE_REAL)/512
|
.long (IMAGE_BASE_VIRTUAL-IMAGE_BASE_REAL)/512
|
||||||
#endif
|
#endif
|
||||||
/ 𝑠𝑙𝑖𝑑𝑒
|
// 𝑠𝑙𝑖𝑑𝑒
|
||||||
.endfn metal.thunk
|
.endfn metal.thunk
|
||||||
metal:
|
metal:
|
||||||
xor %eax,%eax # clear bss
|
xor %eax,%eax # clear bss
|
||||||
|
|
|
@ -20,8 +20,8 @@ APE = $(APE_DEPS) \
|
||||||
o/$(MODE)/ape/ape.lds
|
o/$(MODE)/ape/ape.lds
|
||||||
|
|
||||||
APELINK = \
|
APELINK = \
|
||||||
ACTION=LINK.ape \
|
|
||||||
$(COMPILE) \
|
$(COMPILE) \
|
||||||
|
-ALINK.ape \
|
||||||
$(LINK) \
|
$(LINK) \
|
||||||
$(LINKARGS) \
|
$(LINKARGS) \
|
||||||
$(OUTPUT_OPTION)
|
$(OUTPUT_OPTION)
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
|
||||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
|
||||||
#
|
|
||||||
# OVERVIEW
|
|
||||||
#
|
|
||||||
# Cosmopolitan Archiver
|
|
||||||
#
|
|
||||||
# DESCRIPTION
|
|
||||||
#
|
|
||||||
# This goes 100x faster than ar and ranlib.
|
|
||||||
#
|
|
||||||
# EXAMPLE
|
|
||||||
#
|
|
||||||
# build/archive rcsD library.a foo.o ...
|
|
||||||
|
|
||||||
MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit
|
|
||||||
if [ -x "o//tool/build/ar.com" ]; then
|
|
||||||
set -- "o//tool/build/ar.com" "$@"
|
|
||||||
else
|
|
||||||
if [ ! -x o/build/bootstrap/ar.com ]; then
|
|
||||||
mkdir -p o/build/bootstrap &&
|
|
||||||
cp -f build/bootstrap/ar.com o/build/bootstrap/ar.com.$$ &&
|
|
||||||
mv -f o/build/bootstrap/ar.com.$$ o/build/bootstrap/ar.com || exit
|
|
||||||
fi
|
|
||||||
set -- o/build/bootstrap/ar.com "$@"
|
|
||||||
fi
|
|
||||||
OUT=$3
|
|
||||||
|
|
||||||
printf "$LOGFMT" "${ACTION:-ARCHIVE.a}" "$OUT" >&2
|
|
||||||
# if [ "$V" = "0" ]; then
|
|
||||||
# printf "$LOGFMT" "${ACTION:-ARCHIVE.a}" "$OUT" >&2
|
|
||||||
# else
|
|
||||||
# # some of these windows nt archives are quite huge
|
|
||||||
# COLUMNS=${COLUMNS:-80}
|
|
||||||
# COLUMNS=$((COLUMNS - 4))
|
|
||||||
# printf "%s\n" "$*" |
|
|
||||||
# /usr/bin/fold -s -w $COLUMNS |
|
|
||||||
# sed -e '1bb' -e 's/^/ /' -e ':b' -e '$b' -e 's/$/ \\/' >&2
|
|
||||||
# fi
|
|
||||||
|
|
||||||
REASON=failed
|
|
||||||
trap REASON=interrupted INT
|
|
||||||
|
|
||||||
"$@" >/dev/null && exit
|
|
||||||
|
|
||||||
if [ "$TERM" = "dumb" ]; then
|
|
||||||
f='%s %s\r\n\r\n'
|
|
||||||
else
|
|
||||||
f='\033[91m%s\033[39m \033[94m%s\033[39m\r\n\r\n'
|
|
||||||
fi
|
|
||||||
printf "$f" "archive $REASON:" "$*" >&2
|
|
||||||
exit 1
|
|
|
@ -1,49 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
|
||||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
|
||||||
#
|
|
||||||
# OVERVIEW
|
|
||||||
#
|
|
||||||
# GNU Assembler Veneer
|
|
||||||
#
|
|
||||||
# DESCRIPTION
|
|
||||||
#
|
|
||||||
# This script wraps normal assembler commands that're transparently
|
|
||||||
# passed-through. It adds ephemeral logging and directory creation.
|
|
||||||
#
|
|
||||||
# EXAMPLE
|
|
||||||
#
|
|
||||||
# TARGET=program build/assemble as -o program program.o
|
|
||||||
#
|
|
||||||
# SEE ALSO
|
|
||||||
#
|
|
||||||
# https://justine.storage.googleapis.com/perm/as.pdf
|
|
||||||
|
|
||||||
if [ ! -d o/third_party/gcc ]; then
|
|
||||||
third_party/gcc/unbundle.sh
|
|
||||||
fi
|
|
||||||
|
|
||||||
MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit
|
|
||||||
|
|
||||||
if [ "$V" = "0" ]; then
|
|
||||||
printf "$LOGFMT" "${ACTION:-OBJECTIFY.s}" "$TARGET" >&2
|
|
||||||
else
|
|
||||||
printf "%s\n" "$*" >&2
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$TARGET" ]; then
|
|
||||||
TARGETDIR="${TARGET%/*}"
|
|
||||||
if [ "$TARGETDIR" != "$TARGET" ] && [ ! -d "$TARGETDIR" ]; then
|
|
||||||
$MKDIR "$TARGETDIR" || exit 2
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
"$@" && exit
|
|
||||||
|
|
||||||
if [ "$TERM" = "dumb" ]; then
|
|
||||||
f='%s %s\r\n\r\n'
|
|
||||||
else
|
|
||||||
f='\033[91m%s\033[39m \033[94m%s\033[39m\r\n\r\n'
|
|
||||||
fi
|
|
||||||
printf "$f" "assemble failed:" "$*" >&2
|
|
||||||
exit 1
|
|
Binary file not shown.
298
build/compile
298
build/compile
|
@ -1,298 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
|
||||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
|
||||||
#
|
|
||||||
# OVERVIEW
|
|
||||||
#
|
|
||||||
# GNU/LLVM Compiler Frontend Frontend
|
|
||||||
#
|
|
||||||
# DESCRIPTION
|
|
||||||
#
|
|
||||||
# This wrapper script filters out certain flags so the compiler won't
|
|
||||||
# whine, and passes extra information to the preprocessor.
|
|
||||||
#
|
|
||||||
# EXAMPLE
|
|
||||||
#
|
|
||||||
# build/compile cc -o program program.c
|
|
||||||
|
|
||||||
if [ ! -d o/third_party/gcc ]; then
|
|
||||||
third_party/gcc/unbundle.sh
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$1" = "clang-10" ]; then
|
|
||||||
if ! command -v clang-10 >/dev/null; then
|
|
||||||
shift
|
|
||||||
set -- o/third_party/gcc/bin/x86_64-linux-musl-gcc "$@"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$1" = "clang++-10" ]; then
|
|
||||||
if ! command -v clang++-10 >/dev/null; then
|
|
||||||
shift
|
|
||||||
set -- o/third_party/gcc/bin/x86_64-linux-musl-g++ "$@"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit
|
|
||||||
|
|
||||||
GZME=
|
|
||||||
ASAN=
|
|
||||||
UBSAN=
|
|
||||||
PLAT="${1%% *}"
|
|
||||||
FDIAGNOSTIC_COLOR=
|
|
||||||
CCNAME=${CCNAME:-gcc}
|
|
||||||
CCVERSION=${CCVERSION:-4}
|
|
||||||
COUNTERMAND=
|
|
||||||
|
|
||||||
# The GNU Compiler Collection passes a lot of CFLAGS to the preprocessor
|
|
||||||
# (which we call CCFLAGS) but it should pass more; and we do just that.
|
|
||||||
NOPG=0
|
|
||||||
FIRST=1
|
|
||||||
OUTARG=0
|
|
||||||
INVISIBLE=0
|
|
||||||
for x; do
|
|
||||||
if [ $FIRST -eq 1 ]; then
|
|
||||||
set --
|
|
||||||
FIRST=0
|
|
||||||
fi
|
|
||||||
if [ $OUTARG -eq 1 ]; then
|
|
||||||
OUTARG=0
|
|
||||||
OUT="$x"
|
|
||||||
fi
|
|
||||||
case "$x" in
|
|
||||||
-o)
|
|
||||||
set -- "$@" "$x"
|
|
||||||
OUTARG=1
|
|
||||||
;;
|
|
||||||
-w)
|
|
||||||
set -- "$@" "$x" -D__W__
|
|
||||||
;;
|
|
||||||
-x-no-pg)
|
|
||||||
NOPG=1
|
|
||||||
;;
|
|
||||||
-pg)
|
|
||||||
if [ $NOPG -eq 0 ] && [ $INVISIBLE -eq 0 ]; then
|
|
||||||
set -- "$@" "$x" -D__PG__ # @see libc/macros.h
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
-mfentry)
|
|
||||||
if [ $NOPG -eq 0 ] && [ $INVISIBLE -eq 0 ]; then
|
|
||||||
set -- "$@" "$x" -D__MFENTRY__
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
-fomit-frame-pointer)
|
|
||||||
INVISIBLE=1
|
|
||||||
set -- "$@" "$x"
|
|
||||||
;;
|
|
||||||
-mno-vzeroupper)
|
|
||||||
set -- "$@" "$x" -Wa,-msse2avx -D__MNO_VZEROUPPER__
|
|
||||||
;;
|
|
||||||
-fsanitize=address)
|
|
||||||
ASAN="$x -D__FSANITIZE_ADDRESS__"
|
|
||||||
;;
|
|
||||||
-fsanitize=undefined)
|
|
||||||
# UBSAN w/ -fdata-sections exceeds ELF's 65,280 section limit
|
|
||||||
UBSAN="$x -fno-data-sections"
|
|
||||||
;;
|
|
||||||
-fno-sanitize=address)
|
|
||||||
ASAN=
|
|
||||||
;;
|
|
||||||
-fno-sanitize=ubsan)
|
|
||||||
UBSAN=
|
|
||||||
;;
|
|
||||||
-fno-sanitize=all)
|
|
||||||
ASAN=
|
|
||||||
UBSAN=
|
|
||||||
;;
|
|
||||||
-mnop-mcount)
|
|
||||||
if [ "$CCNAME" = "gcc" ] && [ "$CCVERSION" -ge 6 ]; then
|
|
||||||
set -- "$@" "$x" -D__MNOP_MCOUNT__
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
-mrecord-mcount)
|
|
||||||
if [ "$CCNAME" = "gcc" ] && [ "$CCVERSION" -ge 6 ]; then
|
|
||||||
set -- "$@" "$x" -D__MRECORD_MCOUNT__
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
-fsanitize=implicit*integer*)
|
|
||||||
if ! [ "$CCNAME" = "gcc" ]; then
|
|
||||||
set -- "$@" "$x"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
-f*sanitize*|-gz*|-*stack-protector*|-fvect-cost*|-mstringop*)
|
|
||||||
if [ "$CCNAME" = "gcc" ] && [ "$CCVERSION" -ge 6 ]; then
|
|
||||||
set -- "$@" "$x"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
-freorder-blocks-and-partition|-fstack-clash-protection)
|
|
||||||
if [ "$CCNAME" = "gcc" ] && [ "$CCVERSION" -ge 8 ]; then
|
|
||||||
set -- "$@" "$x"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
-fdiagnostic-color=*)
|
|
||||||
FDIAGNOSTIC_COLOR=$x
|
|
||||||
;;
|
|
||||||
-fopt-info*=*.optinfo)
|
|
||||||
if [ "$CCNAME" = "gcc" ] && [ "$CCVERSION" -ge 9 ]; then
|
|
||||||
GZME="$GZME ${x##*=}"
|
|
||||||
set -- "$@" "$x"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
-R*) # e.g. clang's -Rpass-missed=all
|
|
||||||
if [ "${PLAT#*clang}" != "${PLAT}" ]; then
|
|
||||||
set -- "$@" "$x"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
-fsave-optimization-record) # clang only
|
|
||||||
if [ "${PLAT#*clang}" != "${PLAT}" ]; then
|
|
||||||
set -- "$@" "$x"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
set -- "$@" "$x"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
if [ -z "$FDIAGNOSTIC_COLOR" ] && [ "$TERM" != "dumb" ]; then
|
|
||||||
FDIAGNOSTIC_COLOR=-fdiagnostics-color=always
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${PLAT#*clang}" != "${PLAT}" ]; then
|
|
||||||
FIRST=1
|
|
||||||
for x; do
|
|
||||||
# clang's assembler isn't complete yet
|
|
||||||
if [ $FIRST -eq 1 ]; then
|
|
||||||
set -- \
|
|
||||||
"$x" \
|
|
||||||
-fno-integrated-as \
|
|
||||||
-Wno-unused-command-line-argument \
|
|
||||||
-Wno-incompatible-pointer-types-discards-qualifiers
|
|
||||||
FIRST=0
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
TRAPV= # clang handles -f{,no-}{trap,wrap}v weird
|
|
||||||
# removes flags clang whines about
|
|
||||||
case "$x" in
|
|
||||||
-gstabs) ;;
|
|
||||||
-ftrapv) ;;
|
|
||||||
-ffixed-*) ;;
|
|
||||||
-fcall-saved*) ;;
|
|
||||||
-fsignaling-nans) ;;
|
|
||||||
-fcx-limited-range) ;;
|
|
||||||
-fno-fp-int-builtin-inexact) ;;
|
|
||||||
-Wno-unused-but-set-variable) ;;
|
|
||||||
-Wunsafe-loop-optimizations) ;;
|
|
||||||
-mdispatch-scheduler) ;;
|
|
||||||
-ftracer) ;;
|
|
||||||
-frounding-math) ;;
|
|
||||||
-fmerge-constants) ;;
|
|
||||||
-fmodulo-sched) ;;
|
|
||||||
-msse2avx)
|
|
||||||
set -- "$@" -Wa,-msse2avx
|
|
||||||
;;
|
|
||||||
-fopt-info-vec) ;;
|
|
||||||
-fopt-info-vec-missed) ;;
|
|
||||||
-fmodulo-sched-allow-regmoves) ;;
|
|
||||||
-fgcse-*) ;;
|
|
||||||
-freschedule-modulo-scheduled-loops) ;;
|
|
||||||
-freschedule-modulo-scheduled-loops) ;;
|
|
||||||
-fipa-pta) ;;
|
|
||||||
-fsched2-use-superblocks) ;;
|
|
||||||
-fbranch-target-load-optimize) ;;
|
|
||||||
-fdelete-dead-exceptions) ;;
|
|
||||||
-funsafe-loop-optimizations) ;;
|
|
||||||
-fcall-used*) ;;
|
|
||||||
-mmitigate-rop) ;;
|
|
||||||
-mnop-mcount) ;;
|
|
||||||
-fno-align-jumps) ;;
|
|
||||||
-fno-align-labels) ;;
|
|
||||||
-fno-align-loops) ;;
|
|
||||||
-fivopts) ;;
|
|
||||||
-fschedule-insns) ;;
|
|
||||||
-fno-semantic-interposition) ;;
|
|
||||||
-mno-fentry) ;;
|
|
||||||
-f*shrink-wrap) ;;
|
|
||||||
-f*schedule-insns2) ;;
|
|
||||||
-fvect-cost-model=*) ;;
|
|
||||||
-fsimd-cost-model=*) ;;
|
|
||||||
-fversion-loops-for-strides) ;;
|
|
||||||
-fopt-info*) ;;
|
|
||||||
-f*var-tracking-assignments) ;;
|
|
||||||
-femit-struct-debug-baseonly) ;;
|
|
||||||
-ftree-loop-vectorize) ;;
|
|
||||||
-gdescribe-dies) ;;
|
|
||||||
-flimit-function-alignment) ;;
|
|
||||||
-ftree-loop-im) ;;
|
|
||||||
-fno-instrument-functions) ;;
|
|
||||||
-fstack-clash-protection) ;;
|
|
||||||
-mstringop-strategy=*) ;;
|
|
||||||
-mpreferred-stack-boundary=*) ;;
|
|
||||||
-*stack-protector*) ;; # clang requires segmented memory for this
|
|
||||||
-f*gnu-unique) ;;
|
|
||||||
-Wframe-larger-than=*) ;;
|
|
||||||
-f*whole-program) ;;
|
|
||||||
-Wa,--size-check=*) ;;
|
|
||||||
-Wa,--listing*) ;;
|
|
||||||
-mfpmath=sse+387) ;;
|
|
||||||
-Wa,--noexecstack) ;;
|
|
||||||
-freg-struct-return) ;;
|
|
||||||
-mcall-ms2sysv-xlogues) ;;
|
|
||||||
-mno-vzeroupper)
|
|
||||||
set -- "$@" -mllvm -x86-use-vzeroupper=0
|
|
||||||
;;
|
|
||||||
-Wa,-a*)
|
|
||||||
x="${x#*=}"
|
|
||||||
if [ "$x" ] && [ -p "$x" ]; then
|
|
||||||
printf '' >"$x"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
set -- "$@" "$x"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
set -- "$@" -fno-stack-protector
|
|
||||||
else
|
|
||||||
# removes flags only clang supports
|
|
||||||
FIRST=1
|
|
||||||
for x; do
|
|
||||||
if [ $FIRST -eq 1 ]; then
|
|
||||||
set --
|
|
||||||
FIRST=0
|
|
||||||
fi
|
|
||||||
case "$x" in
|
|
||||||
-Oz) set -- "$@" -Os ;;
|
|
||||||
*) set -- "$@" "$x" ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
set -- "$@" -no-canonical-prefixes $FDIAGNOSTIC_COLOR $ASAN $UBSAN $COUNTERMAND
|
|
||||||
|
|
||||||
if [ "$V" = "0" ]; then
|
|
||||||
printf "$LOGFMT" "${ACTION:-COMPILE}" "${TARGET:-$OUT}" >&2
|
|
||||||
else
|
|
||||||
printf "%s\n" "$*" >&2
|
|
||||||
fi
|
|
||||||
|
|
||||||
OUTDIR="${OUT%/*}"
|
|
||||||
if [ "$OUTDIR" != "$OUT" ] && [ ! -d "$OUTDIR" ]; then
|
|
||||||
$MKDIR "$OUTDIR" || exit 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
REASON=failed
|
|
||||||
trap REASON=interrupted INT
|
|
||||||
|
|
||||||
if "$@"; then
|
|
||||||
for f in $GZME; do
|
|
||||||
if GZ=${GZ:-$(command -v gzip)}; then
|
|
||||||
if [ -f "$f" ]; then
|
|
||||||
build/actuallynice $GZ $ZFLAGS -qf $f &
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
printf "\n$LOGFMT" "$CCNAME $CCVERSION: compile $REASON:" "$*" >&2
|
|
||||||
exit 1
|
|
|
@ -62,12 +62,15 @@ CLANG = clang-10
|
||||||
FC = gfortran #/opt/cross9f/bin/x86_64-linux-musl-gfortran
|
FC = gfortran #/opt/cross9f/bin/x86_64-linux-musl-gfortran
|
||||||
|
|
||||||
# see build/compile, etc. which run third_party/gcc/unbundle.sh
|
# see build/compile, etc. which run third_party/gcc/unbundle.sh
|
||||||
|
AR = build/bootstrap/ar.com
|
||||||
|
PKG = build/bootstrap/package.com
|
||||||
|
MKDEPS = build/bootstrap/mkdeps.com
|
||||||
|
ZIPOBJ = build/bootstrap/zipobj.com
|
||||||
AS = o/third_party/gcc/bin/x86_64-linux-musl-as
|
AS = o/third_party/gcc/bin/x86_64-linux-musl-as
|
||||||
CC = o/third_party/gcc/bin/x86_64-linux-musl-gcc
|
CC = o/third_party/gcc/bin/x86_64-linux-musl-gcc
|
||||||
CXX = o/third_party/gcc/bin/x86_64-linux-musl-g++
|
CXX = o/third_party/gcc/bin/x86_64-linux-musl-g++
|
||||||
CXXFILT = o/third_party/gcc/bin/x86_64-linux-musl-c++filt
|
CXXFILT = o/third_party/gcc/bin/x86_64-linux-musl-c++filt
|
||||||
LD = o/third_party/gcc/bin/x86_64-linux-musl-ld.bfd
|
LD = o/third_party/gcc/bin/x86_64-linux-musl-ld.bfd
|
||||||
AR = build/archive
|
|
||||||
NM = o/third_party/gcc/bin/x86_64-linux-musl-nm
|
NM = o/third_party/gcc/bin/x86_64-linux-musl-nm
|
||||||
GCC = o/third_party/gcc/bin/x86_64-linux-musl-gcc
|
GCC = o/third_party/gcc/bin/x86_64-linux-musl-gcc
|
||||||
STRIP = o/third_party/gcc/bin/x86_64-linux-musl-strip
|
STRIP = o/third_party/gcc/bin/x86_64-linux-musl-strip
|
||||||
|
@ -78,16 +81,12 @@ ADDR2LINE = o/third_party/gcc/bin/x86_64-linux-musl-addr2line
|
||||||
COMMA := ,
|
COMMA := ,
|
||||||
PWD := $(shell pwd)
|
PWD := $(shell pwd)
|
||||||
IMAGE_BASE_VIRTUAL ?= 0x400000
|
IMAGE_BASE_VIRTUAL ?= 0x400000
|
||||||
|
HELLO := $(shell build/hello)
|
||||||
TMPDIR := $(shell build/findtmp)
|
TMPDIR := $(shell build/findtmp)
|
||||||
LOGFMT := $(shell build/getlogfmt)
|
|
||||||
COMPILE := $(shell build/getcompile)
|
COMPILE := $(shell build/getcompile)
|
||||||
CCNAME := $(shell build/getccname $(CC))
|
|
||||||
CCVERSION := $(shell build/getccversion $(CC))
|
CCVERSION := $(shell build/getccversion $(CC))
|
||||||
BLAH1 := $(shell build/zipobj 2>/dev/null)
|
|
||||||
BLAH2 := $(shell build/package 2>/dev/null)
|
|
||||||
|
|
||||||
export ADDR2LINE
|
export ADDR2LINE
|
||||||
export CCNAME
|
|
||||||
export CCVERSION
|
export CCVERSION
|
||||||
export COMPILE
|
export COMPILE
|
||||||
export CP
|
export CP
|
||||||
|
@ -314,8 +313,7 @@ PREPROCESS = $(CC) $(PREPROCESS.flags)
|
||||||
PREPROCESS.lds = $(CC) $(PREPROCESS.lds.flags)
|
PREPROCESS.lds = $(CC) $(PREPROCESS.lds.flags)
|
||||||
LINK = $(LD) $(LINK.flags)
|
LINK = $(LD) $(LINK.flags)
|
||||||
ELF = o/libc/elf/elf.lds
|
ELF = o/libc/elf/elf.lds
|
||||||
ELFLINK = ACTION=LINK.elf $(LINK) $(LINKARGS) $(OUTPUT_OPTION)
|
ELFLINK = $(COMPILE) -ALINK.elf $(LINK) $(LINKARGS) $(OUTPUT_OPTION)
|
||||||
ARCHIVE = $(AR) $(ARFLAGS)
|
|
||||||
LINKARGS = $(patsubst %.lds,-T %.lds,$(call uniqr,$(LD.libs) $(filter-out %.pkg,$^)))
|
LINKARGS = $(patsubst %.lds,-T %.lds,$(call uniqr,$(LD.libs) $(filter-out %.pkg,$^)))
|
||||||
LOLSAN = build/lolsan -b $(IMAGE_BASE_VIRTUAL)
|
LOLSAN = build/lolsan -b $(IMAGE_BASE_VIRTUAL)
|
||||||
|
|
||||||
|
|
55
build/do
55
build/do
|
@ -1,55 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
|
||||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
|
||||||
#
|
|
||||||
# OVERVIEW
|
|
||||||
#
|
|
||||||
# Generic Command Runner
|
|
||||||
#
|
|
||||||
# DESCRIPTION
|
|
||||||
#
|
|
||||||
# This does auto mkdir and ephemeral logging.
|
|
||||||
#
|
|
||||||
# EXAMPLE
|
|
||||||
#
|
|
||||||
# build/do PROG [ARGS...]
|
|
||||||
|
|
||||||
MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit
|
|
||||||
|
|
||||||
# Ensure directory creation if -o PATH flag is passed.
|
|
||||||
OUT="$TARGET"
|
|
||||||
FIRST=1
|
|
||||||
OUTARG=0
|
|
||||||
for x; do
|
|
||||||
if [ $FIRST -eq 1 ]; then
|
|
||||||
set --
|
|
||||||
FIRST=0
|
|
||||||
elif [ $OUTARG -eq 1 ]; then
|
|
||||||
OUTARG=0
|
|
||||||
OUT="$x"
|
|
||||||
fi
|
|
||||||
case "$x" in
|
|
||||||
-o)
|
|
||||||
OUTARG=1
|
|
||||||
;;
|
|
||||||
-o*)
|
|
||||||
OUT=${x#-o}
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
set -- "$@" "$x"
|
|
||||||
done
|
|
||||||
if [ "$OUT" ]; then
|
|
||||||
OUTDIR="${OUT%/*}"
|
|
||||||
if [ "$OUTDIR" != "$OUT" ] && [ ! -d "$OUTDIR" ]; then
|
|
||||||
$MKDIR "$OUTDIR" || exit 2
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Log command.
|
|
||||||
if [ "$V" = "0" ]; then
|
|
||||||
printf "$LOGFMT" "${ACTION:-BUILD}" "$TARGET" >&2
|
|
||||||
else
|
|
||||||
printf "%s\n" "$*" >&2
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec "$@"
|
|
|
@ -1,46 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
|
||||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
|
||||||
#
|
|
||||||
# OVERVIEW
|
|
||||||
#
|
|
||||||
# Compiler Name Discovery
|
|
||||||
#
|
|
||||||
# DESCRIPTION
|
|
||||||
#
|
|
||||||
# Cosmopolitan itself may be built using either GCC and Clang, and our
|
|
||||||
# build irons out many of the differences between the two. This script
|
|
||||||
# determines which one's in play, which is nontrivial, since they tend
|
|
||||||
# to call themselves so many different names.
|
|
||||||
|
|
||||||
if [ ! -d o/third_party/gcc ]; then
|
|
||||||
third_party/gcc/unbundle.sh
|
|
||||||
fi
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
SPECIAL_TEXT=$(
|
|
||||||
$1 --version |
|
|
||||||
sed -n '
|
|
||||||
/chibicc/ {
|
|
||||||
i\
|
|
||||||
chibicc
|
|
||||||
q
|
|
||||||
}
|
|
||||||
/Free Software/ {
|
|
||||||
i\
|
|
||||||
gcc
|
|
||||||
q
|
|
||||||
}
|
|
||||||
/clang/ {
|
|
||||||
i\
|
|
||||||
clang
|
|
||||||
q
|
|
||||||
}
|
|
||||||
')
|
|
||||||
|
|
||||||
if [ -z "$SPECIAL_TEXT" ]; then
|
|
||||||
echo gcc
|
|
||||||
else
|
|
||||||
printf '%s\n' "$SPECIAL_TEXT"
|
|
||||||
fi
|
|
|
@ -5,7 +5,7 @@
|
||||||
if ! [ o/build/bootstrap/compile.com -nt build/bootstrap/compile.com ]; then
|
if ! [ o/build/bootstrap/compile.com -nt build/bootstrap/compile.com ]; then
|
||||||
mkdir -p o/build/bootstrap/
|
mkdir -p o/build/bootstrap/
|
||||||
cp -f build/bootstrap/compile.com o/build/bootstrap/compile.$$.com
|
cp -f build/bootstrap/compile.com o/build/bootstrap/compile.$$.com
|
||||||
o/build/bootstrap/compile.$$.com --do-nothing
|
o/build/bootstrap/compile.$$.com -n
|
||||||
mv -f o/build/bootstrap/compile.$$.com o/build/bootstrap/compile.com
|
mv -f o/build/bootstrap/compile.$$.com o/build/bootstrap/compile.com
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
|
||||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
|
||||||
#
|
|
||||||
# OVERVIEW
|
|
||||||
#
|
|
||||||
# Printf Logger Initializer
|
|
||||||
#
|
|
||||||
# DESCRIPTION
|
|
||||||
#
|
|
||||||
# This program is invoked once by build/definitions.mk to choose the
|
|
||||||
# most appropriate format string when logging command invocations.
|
|
||||||
|
|
||||||
W1=15
|
|
||||||
if [ "$TERM" = "dumb" ]; then
|
|
||||||
if [ "$COLUMNS" = "" ]; then
|
|
||||||
if TPUT=$(command -v tput); then
|
|
||||||
COLUMNS=$("$TPUT" cols)
|
|
||||||
else
|
|
||||||
COLUMNS=80
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
COLUMNS=$((COLUMNS - 1))
|
|
||||||
W2=$((COLUMNS - W1))
|
|
||||||
printf '%%-%ds%%-%ds\\r' "$W1" "$W2"
|
|
||||||
else
|
|
||||||
echo ♥cosmo >&2
|
|
||||||
printf '\\033[F\\033[K%%-%ds%%s\\r\\n' "$W1"
|
|
||||||
fi
|
|
20
build/hello
Executable file
20
build/hello
Executable file
|
@ -0,0 +1,20 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
||||||
|
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# HELLO BUILD
|
||||||
|
#
|
||||||
|
# OVERVIEW
|
||||||
|
#
|
||||||
|
# We generate a line at the start of each Makefile run, because if we
|
||||||
|
# use `make V=0` mode then the terminal logging trick we use in
|
||||||
|
# tool/build/compile.c will delete the previous line, and we'd rather
|
||||||
|
# have that line not be the bash prompt that ran make.
|
||||||
|
#
|
||||||
|
# This script is also useful for giving us an indicator each time the
|
||||||
|
# build restarts itself from scratch, which can happen in cases like
|
||||||
|
# when dependencies need to be regenerated by tool/build/mkdeps.c
|
||||||
|
|
||||||
|
echo ♥cosmo >&2
|
65
build/link
65
build/link
|
@ -1,65 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
|
||||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
|
||||||
#
|
|
||||||
# OVERVIEW
|
|
||||||
#
|
|
||||||
# GNU Linker Veneer
|
|
||||||
#
|
|
||||||
# DESCRIPTION
|
|
||||||
#
|
|
||||||
# This script wraps normal linker commands that're transparently
|
|
||||||
# passed-through. It adds ephemeral logging and directory creation.
|
|
||||||
#
|
|
||||||
# EXAMPLE
|
|
||||||
#
|
|
||||||
# build/linker ld -o program program.o
|
|
||||||
|
|
||||||
if [ ! -d o/third_party/gcc ]; then
|
|
||||||
third_party/gcc/unbundle.sh
|
|
||||||
fi
|
|
||||||
|
|
||||||
MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit
|
|
||||||
|
|
||||||
OUT=
|
|
||||||
FIRST=1
|
|
||||||
OUTARG=0
|
|
||||||
for x; do
|
|
||||||
if [ $FIRST -eq 1 ]; then
|
|
||||||
set --
|
|
||||||
FIRST=0
|
|
||||||
elif [ $OUTARG -eq 1 ]; then
|
|
||||||
OUTARG=0
|
|
||||||
OUT="$x"
|
|
||||||
fi
|
|
||||||
case "$x" in
|
|
||||||
-o)
|
|
||||||
OUTARG=1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
set -- "$@" "$x"
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ "$V" = "0" ]; then
|
|
||||||
printf "$LOGFMT" "${ACTION:-LINK.elf}" "$OUT" >&2
|
|
||||||
else
|
|
||||||
printf "%s\n" "$*" >&2
|
|
||||||
fi
|
|
||||||
|
|
||||||
OUTDIR="${OUT%/*}"
|
|
||||||
if [ "$OUTDIR" != "$OUT" ] && [ ! -d "$OUTDIR" ]; then
|
|
||||||
$MKDIR "$OUTDIR" || exit 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
REASON=failed
|
|
||||||
trap REASON=interrupted INT
|
|
||||||
|
|
||||||
"$@" && exit
|
|
||||||
|
|
||||||
if [ "$TERM" = "dumb" ]; then
|
|
||||||
f='%s %s\r\n\r\n'
|
|
||||||
else
|
|
||||||
f='\033[91m%s\033[39m \033[94m%s\033[39m\r\n\r\n'
|
|
||||||
fi
|
|
||||||
printf "$f" "link $REASON:" "$*" >&2
|
|
||||||
exit 1
|
|
22
build/mkdeps
22
build/mkdeps
|
@ -1,22 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
|
||||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
|
||||||
|
|
||||||
if [ -x "o/$MODE/tool/build/mkdeps.com" ]; then
|
|
||||||
set -- "o/$MODE/tool/build/mkdeps.com" "$@"
|
|
||||||
else
|
|
||||||
if [ ! -x o/build/bootstrap/mkdeps.com ]; then
|
|
||||||
mkdir -p o/build/bootstrap &&
|
|
||||||
cp -a build/bootstrap/mkdeps.com \
|
|
||||||
o/build/bootstrap/mkdeps.com || exit
|
|
||||||
fi
|
|
||||||
set -- o/build/bootstrap/mkdeps.com "$@"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$V" = "0" ]; then
|
|
||||||
printf "$LOGFMT" "${ACTION:-MKDEPS}" "$3" >&2
|
|
||||||
else
|
|
||||||
printf "%s\n" "$*" >&2
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec "$@"
|
|
|
@ -1,22 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
|
||||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
|
||||||
#
|
|
||||||
# OVERVIEW
|
|
||||||
#
|
|
||||||
# GNU Disassembly Veneer
|
|
||||||
#
|
|
||||||
# DESCRIPTION
|
|
||||||
#
|
|
||||||
# This script wraps normal objdump commands that're transparently
|
|
||||||
# passed-through.
|
|
||||||
#
|
|
||||||
# EXAMPLE
|
|
||||||
#
|
|
||||||
# build/objdump -xd o/tiny/examples/life.com.dbg
|
|
||||||
|
|
||||||
if [ ! -d o/third_party/gcc ]; then
|
|
||||||
third_party/gcc/unbundle.sh
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec o/third_party/gcc/bin/x86_64-linux-musl-objdump "$@"
|
|
|
@ -23,9 +23,8 @@
|
||||||
# - tool/build/runitd.c
|
# - tool/build/runitd.c
|
||||||
|
|
||||||
.PRECIOUS: o/$(MODE)/%.com.ok
|
.PRECIOUS: o/$(MODE)/%.com.ok
|
||||||
o/$(MODE)/%.com.ok: \
|
o/$(MODE)/%.com.ok: \
|
||||||
o/$(MODE)/tool/build/runit.com.dbg \
|
o/$(MODE)/tool/build/runit.com \
|
||||||
o/$(MODE)/tool/build/runitd.com \
|
o/$(MODE)/tool/build/runitd.com \
|
||||||
o/$(MODE)/%.com
|
o/$(MODE)/%.com
|
||||||
@ACTION=TEST TARGET=$@ build/do $^ $(HOSTS)
|
@$(COMPILE) -ATEST -tT$@ $^ $(HOSTS)
|
||||||
@touch $@
|
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
|
||||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
|
||||||
|
|
||||||
if [ "$TOOL_BUILD_PACKAGE" ]; then
|
|
||||||
set -- "$TOOL_BUILD_PACKAGE" "$@"
|
|
||||||
else
|
|
||||||
if [ -x "o/tool/build/package.com.dbg" ]; then
|
|
||||||
set -- "o/tool/build/package.com.dbg" "$@"
|
|
||||||
else
|
|
||||||
MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit
|
|
||||||
CP=${CP:-$(command -v cp) -f} || exit
|
|
||||||
if [ ! -x o/build/bootstrap/package.com ]; then
|
|
||||||
$MKDIR o/build/bootstrap &&
|
|
||||||
$CP -a build/bootstrap/package.com \
|
|
||||||
o/build/bootstrap/package.com || exit
|
|
||||||
fi
|
|
||||||
set -- o/build/bootstrap/package.com "$@"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
printf "$LOGFMT" "${ACTION:-PACKAGE}" "$3" >&2
|
|
||||||
# if [ "$V" = "0" ]; then
|
|
||||||
# printf "$LOGFMT" "${ACTION:-PACKAGE}" "$3" >&2
|
|
||||||
# else
|
|
||||||
# COLUMNS=${COLUMNS:-80}
|
|
||||||
# COLUMNS=$((COLUMNS - 4))
|
|
||||||
# printf "%s\n" "$*" |
|
|
||||||
# /usr/bin/fold -s -w $COLUMNS |
|
|
||||||
# sed -e '1bb' -e 's/^/ /' -e ':b' -e '$b' -e 's/$/ \\/' >&2
|
|
||||||
# fi
|
|
||||||
|
|
||||||
exec "$@"
|
|
128
build/rules.mk
128
build/rules.mk
|
@ -16,73 +16,67 @@
|
||||||
|
|
||||||
MAKEFLAGS += --no-builtin-rules
|
MAKEFLAGS += --no-builtin-rules
|
||||||
|
|
||||||
o/%.a:; @$(ARCHIVE) $@ $^
|
o/%.a: ; @$(COMPILE) -AARCHIVE -T$@ $(AR) $(ARFLAGS) $@ $^
|
||||||
o/%.o: %.s; @TARGET=$@ $(COMPILE) $(OBJECTIFY.s) $(OUTPUT_OPTION) $<
|
o/%.o: %.s ; @$(COMPILE) -AOBJECTIFY.s $(OBJECTIFY.s) $(OUTPUT_OPTION) $<
|
||||||
o/%.o: o/%.s; @TARGET=$@ $(COMPILE) $(OBJECTIFY.s) $(OUTPUT_OPTION) $<
|
o/%.o: o/%.s ; @$(COMPILE) -AOBJECTIFY.s $(OBJECTIFY.s) $(OUTPUT_OPTION) $<
|
||||||
o/%.s: %.S; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $<
|
o/%.s: %.S ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) $<
|
||||||
o/%.s: o/%.S; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $<
|
o/%.s: o/%.S ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) $<
|
||||||
o/%.i: %.S; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $<
|
o/%.i: %.S ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) $<
|
||||||
o/%.o: %.S; @ACTION=OBJECTIFY.S $(COMPILE) $(OBJECTIFY.S) $(OUTPUT_OPTION) $<
|
o/%.o: %.S ; @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $<
|
||||||
o/%.o: o/%.S; @ACTION=OBJECTIFY.S $(COMPILE) $(OBJECTIFY.S) $(OUTPUT_OPTION) $<
|
o/%.o: o/%.S ; @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $<
|
||||||
o/%.s: %.i; @ACTION=COMPILE.i $(COMPILE) $(COMPILE.i) $(OUTPUT_OPTION) $<
|
o/%.s: %.i ; @$(COMPILE) -ACOMPILE.i $(COMPILE.i) $(OUTPUT_OPTION) $<
|
||||||
o/%.s: o/%.i; @ACTION=COMPILE.i $(COMPILE) $(COMPILE.i) $(OUTPUT_OPTION) $<
|
o/%.s: o/%.i ; @$(COMPILE) -ACOMPILE.i $(COMPILE.i) $(OUTPUT_OPTION) $<
|
||||||
o/%.o: %.cc; @ACTION=OBJECTIFY.cxx $(COMPILE) $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
|
o/%.o: %.cc ; @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
|
||||||
o/%.o: o/%.cc; @ACTION=OBJECTIFY.cxx $(COMPILE) $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
|
o/%.o: o/%.cc ; @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
|
||||||
o/%.lds: %.lds; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS.lds) $(OUTPUT_OPTION) $<
|
o/%.lds: %.lds ; @$(COMPILE) -APREPROCESS $(PREPROCESS.lds) $(OUTPUT_OPTION) $<
|
||||||
o/%.inc: %.h; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) -D__ASSEMBLER__ -P $<
|
o/%.inc: %.h ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) -D__ASSEMBLER__ -P $<
|
||||||
o/%.pkg:; @build/package $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) $(filter %.o,$^)
|
o/%.pkg: ; @$(COMPILE) -APACKAGE -T$@ $(PKG) $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) $(filter %.o,$^)
|
||||||
o/%.h.ok: %.h; @ACTION=CHECK.h $(COMPILE) $(COMPILE.c) -x c -g0 -o $@ $<
|
o/%.h.ok: %.h ; @$(COMPILE) -ACHECK.h $(COMPILE.c) -x c -g0 -o $@ $<
|
||||||
o/%.h.okk: %.h; @ACTION=CHECK.h $(COMPILE) $(COMPILE.cxx) -x c++ -g0 -o $@ $<
|
o/%.h.okk: %.h ; @$(COMPILE) -ACHECK.h $(COMPILE.cxx) -x c++ -g0 -o $@ $<
|
||||||
o/%.greg.o: %.greg.c; @ACTION=OBJECTIFY.greg $(COMPILE) $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
|
o/%.greg.o: %.greg.c ; @$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
|
||||||
o/%.zip.o: o/%; @build/zipobj $(ZIPOBJ_FLAGS) $(OUTPUT_OPTION) $<
|
o/%.zip.o: o/% ; @$(COMPILE) -AZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) $(OUTPUT_OPTION) $<
|
||||||
|
|
||||||
o/$(MODE)/%.a:; @$(ARCHIVE) $@ $^
|
o/$(MODE)/%.a: ; @$(COMPILE) -AARCHIVE -T$@ $(AR) $(ARFLAGS) $@ $^
|
||||||
o/$(MODE)/%: o/$(MODE)/%.dbg; @ACTION=OBJCOPY TARGET=$@ $(COMPILE) $(OBJCOPY) -S -O binary $< $@
|
o/$(MODE)/%: o/$(MODE)/%.dbg ; @$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||||
o/$(MODE)/%.o: %.s; @TARGET=$@ $(COMPILE) $(OBJECTIFY.s) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.o: %.s ; @$(COMPILE) -AOBJECTIFY.s $(OBJECTIFY.s) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.o: o/$(MODE)/%.s; @TARGET=$@ $(COMPILE) $(OBJECTIFY.s) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.o: o/$(MODE)/%.s ; @$(COMPILE) -AOBJECTIFY.s $(OBJECTIFY.s) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.s: %.S; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.s: %.S ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.s: o/$(MODE)/%.S; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.s: o/$(MODE)/%.S ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.o: %.c; @ACTION=OBJECTIFY.c $(COMPILE) $(OBJECTIFY.c) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.o: %.c ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.o: %.f; @ACTION=OBJECTIFY.f $(COMPILE) $(OBJECTIFY.f) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.o: %.f ; @$(COMPILE) -AOBJECTIFY.f $(OBJECTIFY.f) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.o: %.F; @ACTION=OBJECTIFY.F $(COMPILE) $(OBJECTIFY.F) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.o: %.F ; @$(COMPILE) -AOBJECTIFY.F $(OBJECTIFY.F) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.o: o/$(MODE)/%.c; @ACTION=OBJECTIFY.c $(COMPILE) $(OBJECTIFY.c) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.o: o/$(MODE)/%.c ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.ss: %.c; @ACTION=COMPILE.c $(COMPILE) $(COMPILE.c) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.ss: %.c ; @$(COMPILE) -ACOMPILE.c $(COMPILE.c) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.ss: o/$(MODE)/%.c; @ACTION=OBJECTIFY.s $(COMPILE) $(COMPILE.c) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.ss: o/$(MODE)/%.c ; @$(COMPILE) -AOBJECTIFY.s $(COMPILE.c) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.i: %.S; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.i: %.S ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.i: %.c; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.i: %.c ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.i: %.cc; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.i: %.cc ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.i: o/$(MODE)/%.c; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.i: o/$(MODE)/%.c ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.h: %.c; @ACTION=AMALGAMATE $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) -fdirectives-only -P $<
|
o/$(MODE)/%.h: %.c ; @$(COMPILE) -AAMALGAMATE $(PREPROCESS) $(OUTPUT_OPTION) -fdirectives-only -P $<
|
||||||
o/$(MODE)/%.h: o/$(MODE)/%.c; @ACTION=AMALGAMATE $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) -fdirectives-only -P $<
|
o/$(MODE)/%.h: o/$(MODE)/%.c ; @$(COMPILE) -AAMALGAMATE $(PREPROCESS) $(OUTPUT_OPTION) -fdirectives-only -P $<
|
||||||
o/$(MODE)/%.o: %.S; @ACTION=OBJECTIFY.S $(COMPILE) $(OBJECTIFY.S) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.o: %.S ; @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.o: o/$(MODE)/%.S; @ACTION=OBJECTIFY.S $(COMPILE) $(OBJECTIFY.S) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.o: o/$(MODE)/%.S ; @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.s: %.i; @ACTION=COMPILE.i $(COMPILE) $(COMPILE.i) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.s: %.i ; @$(COMPILE) -ACOMPILE.i $(COMPILE.i) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.s: o/$(MODE)/%.i; @ACTION=COMPILE.i $(COMPILE) $(COMPILE.i) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.s: o/$(MODE)/%.i ; @$(COMPILE) -ACOMPILE.i $(COMPILE.i) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.o: %.cc; @ACTION=OBJECTIFY.cxx $(COMPILE) $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.o: %.cc ; @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.o: o/$(MODE)/%.cc; @ACTION=OBJECTIFY.cxx $(COMPILE) $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.o: o/$(MODE)/%.cc ; @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.lds: %.lds; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS.lds) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.lds: %.lds ; @$(COMPILE) -APREPROCESS $(PREPROCESS.lds) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.h.ok: %.h; @ACTION=CHECK.h $(COMPILE) $(COMPILE.c) -x c -g0 -o $@ $<
|
o/$(MODE)/%.h.ok: %.h ; @$(COMPILE) -ACHECK.h $(COMPILE.c) -x c -g0 -o $@ $<
|
||||||
o/$(MODE)/%.h.okk: %.h; @ACTION=CHECK.h $(COMPILE) $(COMPILE.cxx) -x c++ -g0 -o $@ $<
|
o/$(MODE)/%.h.okk: %.h ; @$(COMPILE) -ACHECK.h $(COMPILE.cxx) -x c++ -g0 -o $@ $<
|
||||||
o/$(MODE)/%.o: %.greg.c; @ACTION=OBJECTIFY.greg $(COMPILE) $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.o: %.greg.c ; @$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.greg.o: %.greg.c; @ACTION=OBJECTIFY.greg $(COMPILE) $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.greg.o: %.greg.c ; @$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.ansi.o: %.ansi.c; @ACTION=OBJECTIFY.ansi $(COMPILE) $(OBJECTIFY.ansi.c) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.ansi.o: %.ansi.c ; @$(COMPILE) -AOBJECTIFY.ansi $(OBJECTIFY.ansi.c) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.ansi.o: %.c; @ACTION=OBJECTIFY.ansi $(COMPILE) $(OBJECTIFY.ansi.c) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.ansi.o: %.c ; @$(COMPILE) -AOBJECTIFY.ansi $(OBJECTIFY.ansi.c) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.c99.o: %.c99.c; @ACTION=OBJECTIFY.c99 $(COMPILE) $(OBJECTIFY.c99.c) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.c99.o: %.c99.c ; @$(COMPILE) -AOBJECTIFY.c99 $(OBJECTIFY.c99.c) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.c11.o: %.c11.c; @ACTION=OBJECTIFY.c11 $(COMPILE) $(OBJECTIFY.c11.c) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.c11.o: %.c11.c ; @$(COMPILE) -AOBJECTIFY.c11 $(OBJECTIFY.c11.c) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.c2x.o: %.c2x.c; @ACTION=OBJECTIFY.c2x $(COMPILE) $(OBJECTIFY.c2x.c) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.c2x.o: %.c2x.c ; @$(COMPILE) -AOBJECTIFY.c2x $(OBJECTIFY.c2x.c) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.initabi.o: %.initabi.c; @ACTION=OBJECTIFY.init $(COMPILE) $(OBJECTIFY.initabi.c) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.initabi.o: %.initabi.c ; @$(COMPILE) -AOBJECTIFY.init $(OBJECTIFY.initabi.c) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.ncabi.o: %.ncabi.c; @ACTION=OBJECTIFY.nc $(COMPILE) $(OBJECTIFY.ncabi.c) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.ncabi.o: %.ncabi.c ; @$(COMPILE) -AOBJECTIFY.nc $(OBJECTIFY.ncabi.c) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.real.o: %.c; @ACTION=OBJECTIFY.real $(COMPILE) $(OBJECTIFY.real.c) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.real.o: %.c ; @$(COMPILE) -AOBJECTIFY.real $(OBJECTIFY.real.c) $(OUTPUT_OPTION) $<
|
||||||
o/$(MODE)/%.runs: o/$(MODE)/%; @ACTION=CHECK.runs TARGET=$< build/runcom $< $(TESTARGS) && touch $@
|
o/$(MODE)/%.runs: o/$(MODE)/% ; @$(COMPILE) -ACHECK -tT$@ $< $(TESTARGS)
|
||||||
o/$(MODE)/%.pkg:; @build/package $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) $(filter %.o,$^)
|
o/$(MODE)/%.pkg: ; @$(COMPILE) -APACKAGE -T$@ $(PKG) $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) $(filter %.o,$^)
|
||||||
o/$(MODE)/%.zip.o: %; @build/zipobj $(ZIPOBJ_FLAGS) $(OUTPUT_OPTION) $<
|
o/$(MODE)/%.zip.o: % ; @$(COMPILE) -AZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) $(OUTPUT_OPTION) $<
|
||||||
|
o/$(MODE)/%-gcc.asm: %.c ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $<
|
||||||
|
o/$(MODE)/%-clang.asm: %.c ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $< || echo / need $(CLANG) >$@
|
||||||
|
|
||||||
o/$(MODE)/%-gcc.asm: %.c; @ACTION=OBJECTIFY.c $(COMPILE) $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $<
|
|
||||||
o/$(MODE)/%-clang.asm: CC = $(CLANG)
|
o/$(MODE)/%-clang.asm: CC = $(CLANG)
|
||||||
o/$(MODE)/%-clang.asm: %.c; @ACTION=OBJECTIFY.c $(COMPILE) $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $< || echo / need $(CLANG) >$@
|
|
||||||
o/$(MODE)/%-gcc.asm: %.f; @ACTION=OBJECTIFY.f $(COMPILE) $(OBJECTIFY.f) -S -g0 $(OUTPUT_OPTION) $<
|
|
||||||
o/$(MODE)/%-clang.asm: CC = $(CLANG)
|
|
||||||
o/$(MODE)/%-clang.asm: %.f; @ACTION=OBJECTIFY.f $(COMPILE) $(OBJECTIFY.f) -S -g0 $(OUTPUT_OPTION) $< || echo / need $(CLANG) >$@
|
|
||||||
o/$(MODE)/%-gcc.asm: %.F; @ACTION=OBJECTIFY.F $(COMPILE) $(OBJECTIFY.F) -S -g0 $(OUTPUT_OPTION) $<
|
|
||||||
o/$(MODE)/%-clang.asm: CC = $(CLANG)
|
|
||||||
o/$(MODE)/%-clang.asm: %.F; @ACTION=OBJECTIFY.F $(COMPILE) $(OBJECTIFY.F) -S -g0 $(OUTPUT_OPTION) $< || echo / need $(CLANG) >$@
|
|
||||||
|
|
11
build/runcom
11
build/runcom
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
|
||||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
|
||||||
|
|
||||||
DD=${DD:-$(command -v dd)} || exit
|
|
||||||
$DD if="$1" of="$1.bak" bs=4096 count=1 conv=notrunc 2>/dev/null
|
|
||||||
"$@"
|
|
||||||
rc=$?
|
|
||||||
echo "$1"
|
|
||||||
$DD if="$1.bak" of="$1" bs=4096 count=1 conv=notrunc 2>/dev/null
|
|
||||||
exit $rc
|
|
51
build/zipobj
51
build/zipobj
|
@ -1,51 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
|
||||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
|
||||||
|
|
||||||
MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit
|
|
||||||
CP=${CP:-$(command -v cp) -f} || exit
|
|
||||||
SED=${SED:-$(command -v sed)} || exit
|
|
||||||
|
|
||||||
MODE=
|
|
||||||
|
|
||||||
OUT=
|
|
||||||
FIRST=1
|
|
||||||
OUTARG=0
|
|
||||||
for x; do
|
|
||||||
if [ $FIRST -eq 1 ]; then
|
|
||||||
set --
|
|
||||||
FIRST=0
|
|
||||||
elif [ $OUTARG -eq 1 ]; then
|
|
||||||
OUTARG=0
|
|
||||||
OUT="$x"
|
|
||||||
fi
|
|
||||||
case "$x" in
|
|
||||||
-o)
|
|
||||||
OUTARG=1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
set -- "$@" "$x"
|
|
||||||
done
|
|
||||||
OUTDIR="${OUT%/*}"
|
|
||||||
if [ "$OUTDIR" != "$OUT" ] && [ ! -d "$OUTDIR" ]; then
|
|
||||||
$MKDIR "$OUTDIR" || exit 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -x "o/$MODE/tool/build/zipobj.com.dbg" ]; then
|
|
||||||
set -- "o/$MODE/tool/build/zipobj.com.dbg" "$@"
|
|
||||||
else
|
|
||||||
if [ ! -x o/build/bootstrap/zipobj.com ]; then
|
|
||||||
$MKDIR o/build/bootstrap &&
|
|
||||||
$CP -a build/bootstrap/zipobj.com \
|
|
||||||
o/build/bootstrap/zipobj.com || exit
|
|
||||||
fi
|
|
||||||
set -- o/build/bootstrap/zipobj.com "$@"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$V" = "0" ]; then
|
|
||||||
printf "$LOGFMT" "${ACTION:-ZIPOBJ}" "$3" >&2
|
|
||||||
else
|
|
||||||
printf "%s\n" "$*" >&2
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec "$@"
|
|
|
@ -133,10 +133,6 @@ usr/share/dict/words: usr/share/dict/words.gz
|
||||||
@$(MKDIR) $(dir $@)
|
@$(MKDIR) $(dir $@)
|
||||||
@$(GZ) $(ZFLAGS) -d <$< >$@
|
@$(GZ) $(ZFLAGS) -d <$< >$@
|
||||||
|
|
||||||
o/$(MODE)/examples/ugh.ok: o/$(MODE)/examples/wut.com
|
|
||||||
$<
|
|
||||||
touch $@
|
|
||||||
|
|
||||||
.PHONY: o/$(MODE)/examples
|
.PHONY: o/$(MODE)/examples
|
||||||
o/$(MODE)/examples: \
|
o/$(MODE)/examples: \
|
||||||
o/$(MODE)/examples/package \
|
o/$(MODE)/examples/package \
|
||||||
|
|
29
examples/touch.c
Normal file
29
examples/touch.c
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#if 0
|
||||||
|
/*─────────────────────────────────────────────────────────────────╗
|
||||||
|
│ To the extent possible under law, Justine Tunney has waived │
|
||||||
|
│ all copyright and related or neighboring rights to this file, │
|
||||||
|
│ as it is written in the following disclaimers: │
|
||||||
|
│ • http://unlicense.org/ │
|
||||||
|
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||||
|
╚─────────────────────────────────────────────────────────────────*/
|
||||||
|
#endif
|
||||||
|
#include "libc/calls/calls.h"
|
||||||
|
#include "libc/errno.h"
|
||||||
|
#include "libc/runtime/runtime.h"
|
||||||
|
#include "libc/stdio/stdio.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fileoverview Command for updating timestamps on files.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
int i;
|
||||||
|
for (i = 1; i < argc; ++i) {
|
||||||
|
if (touch(argv[i], 0644) == -1) {
|
||||||
|
fprintf(stderr, "ERROR: %s: %s\n", argv[i], strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -263,6 +263,7 @@ int sys_sync_nt(void) hidden;
|
||||||
int sys_sysinfo_nt(struct sysinfo *) hidden;
|
int sys_sysinfo_nt(struct sysinfo *) hidden;
|
||||||
int sys_truncate_nt(const char *, u64) hidden;
|
int sys_truncate_nt(const char *, u64) hidden;
|
||||||
int sys_unlinkat_nt(int, const char *, int) hidden;
|
int sys_unlinkat_nt(int, const char *, int) hidden;
|
||||||
|
int sys_utimes_nt(const char *, const struct timeval[2]) hidden;
|
||||||
int sys_utimensat_nt(int, const char *, const struct timespec *, int) hidden;
|
int sys_utimensat_nt(int, const char *, const struct timespec *, int) hidden;
|
||||||
ssize_t sys_open_nt(int, const char *, u32, i32) nodiscard hidden;
|
ssize_t sys_open_nt(int, const char *, u32, i32) nodiscard hidden;
|
||||||
ssize_t sys_read_nt(struct Fd *, const struct iovec *, size_t, ssize_t) hidden;
|
ssize_t sys_read_nt(struct Fd *, const struct iovec *, size_t, ssize_t) hidden;
|
||||||
|
|
33
libc/calls/sys_utimes_nt.c
Normal file
33
libc/calls/sys_utimes_nt.c
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/sysv/consts/at.h"
|
||||||
|
|
||||||
|
textwindows int sys_utimes_nt(const char *path, const struct timeval tv[2]) {
|
||||||
|
struct timespec ts[2];
|
||||||
|
if (tv) {
|
||||||
|
ts[0].tv_sec = tv[0].tv_sec;
|
||||||
|
ts[0].tv_nsec = tv[0].tv_usec * 1000;
|
||||||
|
ts[1].tv_sec = tv[1].tv_sec;
|
||||||
|
ts[1].tv_nsec = tv[1].tv_usec * 1000;
|
||||||
|
return sys_utimensat_nt(AT_FDCWD, path, ts, 0);
|
||||||
|
} else {
|
||||||
|
return sys_utimensat_nt(AT_FDCWD, path, NULL, 0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,7 +17,9 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
|
#include "libc/errno.h"
|
||||||
#include "libc/sysv/consts/o.h"
|
#include "libc/sysv/consts/o.h"
|
||||||
|
#include "libc/time/time.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new file or changes modified time on existing one.
|
* Creates new file or changes modified time on existing one.
|
||||||
|
@ -28,7 +30,12 @@
|
||||||
* @see creat()
|
* @see creat()
|
||||||
*/
|
*/
|
||||||
int touch(const char *file, uint32_t mode) {
|
int touch(const char *file, uint32_t mode) {
|
||||||
int fd;
|
int rc, fd, olderr;
|
||||||
if ((fd = open(file, O_CREAT | O_WRONLY, mode)) == -1) return -1;
|
olderr = errno;
|
||||||
return close(fd);
|
if ((rc = utimes(file, NULL)) == -1 && errno == ENOENT) {
|
||||||
|
errno = olderr;
|
||||||
|
if ((fd = open(file, O_CREAT | O_WRONLY, mode)) == -1) return -1;
|
||||||
|
return close(fd);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,16 +26,17 @@
|
||||||
*
|
*
|
||||||
* @param times if NULL means now
|
* @param times if NULL means now
|
||||||
* @return 0 on success or -1 w/ errno
|
* @return 0 on success or -1 w/ errno
|
||||||
|
* @asyncsignalsafe
|
||||||
*/
|
*/
|
||||||
int utime(const char *path, const struct utimbuf *times) {
|
int utime(const char *path, const struct utimbuf *times) {
|
||||||
struct timespec ts[2];
|
struct timeval tv[2];
|
||||||
if (times) {
|
if (times) {
|
||||||
ts[0].tv_sec = times->actime;
|
tv[0].tv_sec = times->actime;
|
||||||
ts[0].tv_nsec = 0;
|
tv[0].tv_usec = 0;
|
||||||
ts[1].tv_sec = times->modtime;
|
tv[1].tv_sec = times->modtime;
|
||||||
ts[1].tv_nsec = 0;
|
tv[1].tv_usec = 0;
|
||||||
return utimensat(AT_FDCWD, path, ts, 0);
|
return utimes(path, tv);
|
||||||
} else {
|
} else {
|
||||||
return utimensat(AT_FDCWD, path, NULL, 0);
|
return utimes(path, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include "libc/time/time.h"
|
#include "libc/time/time.h"
|
||||||
|
|
||||||
textwindows int sys_utimensat_nt(int dirfd, const char *path,
|
textwindows int sys_utimensat_nt(int dirfd, const char *path,
|
||||||
const struct timespec ts[2], int flags) {
|
const struct timespec ts[2], int flags) {
|
||||||
int i, rc;
|
int i, rc;
|
||||||
int64_t fh;
|
int64_t fh;
|
||||||
uint16_t path16[PATH_MAX];
|
uint16_t path16[PATH_MAX];
|
||||||
|
|
|
@ -17,12 +17,33 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/errno.h"
|
||||||
|
#include "libc/sysv/consts/at.h"
|
||||||
#include "libc/time/time.h"
|
#include "libc/time/time.h"
|
||||||
|
|
||||||
|
#define __NR_utimensat_linux 0x118 /*RHEL5:CVE-2010-3301*/
|
||||||
|
|
||||||
int sys_utimensat(int dirfd, const char *path, const struct timespec ts[2],
|
int sys_utimensat(int dirfd, const char *path, const struct timespec ts[2],
|
||||||
int flags) {
|
int flags) {
|
||||||
|
int rc, olderr;
|
||||||
|
struct timeval tv[2];
|
||||||
if (!IsXnu()) {
|
if (!IsXnu()) {
|
||||||
return __sys_utimensat(dirfd, path, ts, flags);
|
olderr = errno;
|
||||||
|
rc = __sys_utimensat(dirfd, path, ts, flags);
|
||||||
|
if (((rc == -1 && errno == ENOSYS) || rc == __NR_utimensat_linux) &&
|
||||||
|
dirfd == AT_FDCWD && !flags) {
|
||||||
|
errno = olderr;
|
||||||
|
if (ts) {
|
||||||
|
tv[0].tv_sec = ts[0].tv_sec;
|
||||||
|
tv[0].tv_usec = ts[0].tv_nsec / 1000;
|
||||||
|
tv[1].tv_sec = ts[1].tv_sec;
|
||||||
|
tv[1].tv_usec = ts[1].tv_nsec / 1000;
|
||||||
|
rc = sys_utimes(path, tv);
|
||||||
|
} else {
|
||||||
|
rc = sys_utimes(path, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
} else {
|
} else {
|
||||||
return sys_utimensat_xnu(dirfd, path, ts, flags);
|
return sys_utimensat_xnu(dirfd, path, ts, flags);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,8 @@
|
||||||
*
|
*
|
||||||
* @param ts is atime/mtime, or null for current time
|
* @param ts is atime/mtime, or null for current time
|
||||||
* @param flags can have AT_SYMLINK_NOFOLLOW
|
* @param flags can have AT_SYMLINK_NOFOLLOW
|
||||||
* @note no rhel5 support
|
* @note no xnu/rhel5 support if dirfd≠AT_FDCWD∨flags≠0
|
||||||
|
* @asyncsignalsafe
|
||||||
*/
|
*/
|
||||||
int utimensat(int dirfd, const char *path,
|
int utimensat(int dirfd, const char *path,
|
||||||
const struct timespec ts[hasatleast 2], int flags) {
|
const struct timespec ts[hasatleast 2], int flags) {
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/dce.h"
|
||||||
#include "libc/sysv/consts/at.h"
|
#include "libc/sysv/consts/at.h"
|
||||||
#include "libc/time/time.h"
|
#include "libc/time/time.h"
|
||||||
|
|
||||||
|
@ -24,17 +26,17 @@
|
||||||
*
|
*
|
||||||
* @param times is access/modified and NULL means now
|
* @param times is access/modified and NULL means now
|
||||||
* @return 0 on success or -1 w/ errno
|
* @return 0 on success or -1 w/ errno
|
||||||
|
* @asyncsignalsafe
|
||||||
* @see stat()
|
* @see stat()
|
||||||
*/
|
*/
|
||||||
int utimes(const char *path, const struct timeval tv[hasatleast 2]) {
|
int utimes(const char *path, const struct timeval tv[2]) {
|
||||||
struct timespec ts[2];
|
if (!IsWindows()) {
|
||||||
if (tv) {
|
/*
|
||||||
ts[0].tv_sec = tv[0].tv_sec;
|
* we don't modernize utimes() into utimensat() because the
|
||||||
ts[0].tv_nsec = tv[0].tv_usec * 1000;
|
* latter is poorly supported and utimes() works everywhere
|
||||||
ts[1].tv_sec = tv[1].tv_sec;
|
*/
|
||||||
ts[1].tv_nsec = tv[1].tv_usec * 1000;
|
return sys_utimes(path, tv);
|
||||||
return utimensat(AT_FDCWD, path, ts, 0);
|
|
||||||
} else {
|
} else {
|
||||||
return utimensat(AT_FDCWD, path, NULL, 0);
|
return sys_utimes_nt(path, tv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,8 +151,6 @@ $(LIBC_NT_NTDLL_A): \
|
||||||
libc/nt/ntdll/ \
|
libc/nt/ntdll/ \
|
||||||
$(LIBC_NT_NTDLL_A).pkg \
|
$(LIBC_NT_NTDLL_A).pkg \
|
||||||
$(LIBC_NT_NTDLL_A_OBJS)
|
$(LIBC_NT_NTDLL_A_OBJS)
|
||||||
@$(file >$@.cmd) $(file >>$@.cmd,$(ARCHIVE) $@ $^ >$(LIBC_NT_NTDLL_A).cmd)
|
|
||||||
@$(ARCHIVE) $@ $^
|
|
||||||
|
|
||||||
$(LIBC_NT_NTDLL_A).pkg: \
|
$(LIBC_NT_NTDLL_A).pkg: \
|
||||||
$(LIBC_NT_NTDLL_A_OBJS) \
|
$(LIBC_NT_NTDLL_A_OBJS) \
|
||||||
|
|
|
@ -61,31 +61,25 @@ o/$(MODE)/libc/unicode: $(LIBC_UNICODE) $(LIBC_UNICODE_CHECKS)
|
||||||
o/$(MODE)/libc/unicode/eastasianwidth.bin: \
|
o/$(MODE)/libc/unicode/eastasianwidth.bin: \
|
||||||
libc/unicode/eastasianwidth.txt \
|
libc/unicode/eastasianwidth.txt \
|
||||||
o/$(MODE)/tool/decode/mkwides.com
|
o/$(MODE)/tool/decode/mkwides.com
|
||||||
@TARGET=$@ ACTION=MKWIDES build/do \
|
@$(COMPILE) -AMKWIDES -T$@ o/$(MODE)/tool/decode/mkwides.com -o $@ $<
|
||||||
o/$(MODE)/tool/decode/mkwides.com -o $@ $<
|
|
||||||
o/$(MODE)/libc/unicode/eastasianwidth.bin.lz4: \
|
o/$(MODE)/libc/unicode/eastasianwidth.bin.lz4: \
|
||||||
o/$(MODE)/libc/unicode/eastasianwidth.bin \
|
o/$(MODE)/libc/unicode/eastasianwidth.bin \
|
||||||
o/$(MODE)/third_party/lz4cli/lz4cli.com
|
o/$(MODE)/third_party/lz4cli/lz4cli.com
|
||||||
@TARGET=$@ ACTION=LZ4 build/do \
|
@$(COMPILE) -ALZ4 -T$@ o/$(MODE)/third_party/lz4cli/lz4cli.com -q -f -9 --content-size $< $@
|
||||||
o/$(MODE)/third_party/lz4cli/lz4cli.com -q -f -9 --content-size $< $@
|
|
||||||
o/$(MODE)/libc/unicode/eastasianwidth.s: \
|
o/$(MODE)/libc/unicode/eastasianwidth.s: \
|
||||||
o/$(MODE)/libc/unicode/eastasianwidth.bin.lz4 \
|
o/$(MODE)/libc/unicode/eastasianwidth.bin.lz4 \
|
||||||
o/$(MODE)/tool/build/lz4toasm.com
|
o/$(MODE)/tool/build/lz4toasm.com
|
||||||
@TARGET=$@ ACTION=BIN2ASM build/do \
|
@$(COMPILE) -ABIN2ASM -T$@ o/$(MODE)/tool/build/lz4toasm.com -s kEastAsianWidth -o $@ $<
|
||||||
o/$(MODE)/tool/build/lz4toasm.com -s kEastAsianWidth -o $@ $<
|
|
||||||
|
|
||||||
o/$(MODE)/libc/unicode/combiningchars.bin: \
|
o/$(MODE)/libc/unicode/combiningchars.bin: \
|
||||||
libc/unicode/unicodedata.txt \
|
libc/unicode/unicodedata.txt \
|
||||||
o/$(MODE)/tool/decode/mkcombos.com
|
o/$(MODE)/tool/decode/mkcombos.com
|
||||||
@TARGET=$@ ACTION=MKCOMBOS build/do \
|
@$(COMPILE) -AMKCOMBOS -T$@ o/$(MODE)/tool/decode/mkcombos.com -o $@ $<
|
||||||
o/$(MODE)/tool/decode/mkcombos.com -o $@ $<
|
|
||||||
o/$(MODE)/libc/unicode/combiningchars.bin.lz4: \
|
o/$(MODE)/libc/unicode/combiningchars.bin.lz4: \
|
||||||
o/$(MODE)/libc/unicode/combiningchars.bin \
|
o/$(MODE)/libc/unicode/combiningchars.bin \
|
||||||
o/$(MODE)/third_party/lz4cli/lz4cli.com
|
o/$(MODE)/third_party/lz4cli/lz4cli.com
|
||||||
@TARGET=$@ ACTION=LZ4 build/do \
|
@$(COMPILE) -ALZ4 -T$@ o/$(MODE)/third_party/lz4cli/lz4cli.com -q -f -9 --content-size $< $@
|
||||||
o/$(MODE)/third_party/lz4cli/lz4cli.com -q -f -9 --content-size $< $@
|
|
||||||
o/$(MODE)/libc/unicode/combiningchars.s: \
|
o/$(MODE)/libc/unicode/combiningchars.s: \
|
||||||
o/$(MODE)/libc/unicode/combiningchars.bin.lz4 \
|
o/$(MODE)/libc/unicode/combiningchars.bin.lz4 \
|
||||||
o/$(MODE)/tool/build/lz4toasm.com
|
o/$(MODE)/tool/build/lz4toasm.com
|
||||||
@TARGET=$@ ACTION=BIN2ASM build/do \
|
@$(COMPILE) -ABIN2ASM -T$@ o/$(MODE)/tool/build/lz4toasm.com -s kCombiningChars -o $@ $<
|
||||||
o/$(MODE)/tool/build/lz4toasm.com -s kCombiningChars -o $@ $<
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
# smoke test userspace binary emulation
|
# smoke test userspace binary emulation
|
||||||
CMD="o/$MODE/tool/build/blinkenlights.com.dbg o/$MODE/examples/hello.com"
|
CMD="o/$MODE/tool/build/blinkenlights.com.dbg o/$MODE/examples/hello.com"
|
||||||
printf '%s\n' "$CMD" >&2
|
|
||||||
if OUTPUT="$($CMD)"; then
|
if OUTPUT="$($CMD)"; then
|
||||||
if [ x"$OUTPUT" = x"hello world" ]; then
|
if [ x"$OUTPUT" = x"hello world" ]; then
|
||||||
touch o/$MODE/test/libc/release/emulate.ok
|
touch o/$MODE/test/libc/release/emulate.ok
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
# smoke test booting on bare metal and printing data to serial uart
|
# smoke test booting on bare metal and printing data to serial uart
|
||||||
CMD="o/$MODE/tool/build/blinkenlights.com.dbg -r o/$MODE/examples/hello.com"
|
CMD="o/$MODE/tool/build/blinkenlights.com.dbg -r o/$MODE/examples/hello.com"
|
||||||
printf '%s\n' "$CMD" >&2
|
|
||||||
if OUTPUT="$($CMD)"; then
|
if OUTPUT="$($CMD)"; then
|
||||||
if [ x"$OUTPUT" = x"hello world" ]; then
|
if [ x"$OUTPUT" = x"hello world" ]; then
|
||||||
touch o/$MODE/test/libc/release/metal.ok
|
touch o/$MODE/test/libc/release/metal.ok
|
||||||
|
|
|
@ -7,11 +7,11 @@ o/$(MODE)/test/libc/release/cosmopolitan.zip: \
|
||||||
o/$(MODE)/libc/crt/crt.o \
|
o/$(MODE)/libc/crt/crt.o \
|
||||||
o/$(MODE)/ape/ape.o \
|
o/$(MODE)/ape/ape.o \
|
||||||
o/$(MODE)/cosmopolitan.a
|
o/$(MODE)/cosmopolitan.a
|
||||||
@zip -j $@ $^
|
@$(COMPILE) -AZIP -T$@ zip -j $@ $^
|
||||||
|
|
||||||
o/$(MODE)/test/libc/release/smoke.com: \
|
o/$(MODE)/test/libc/release/smoke.com: \
|
||||||
o/$(MODE)/test/libc/release/smoke.com.dbg
|
o/$(MODE)/test/libc/release/smoke.com.dbg
|
||||||
@$(COMPILE) $(OBJCOPY) -S -O binary $< $@
|
@$(COMPILE) -AOBJCOPY -T$< $(OBJCOPY) -S -O binary $< $@
|
||||||
|
|
||||||
o/$(MODE)/test/libc/release/smoke.com.dbg: \
|
o/$(MODE)/test/libc/release/smoke.com.dbg: \
|
||||||
test/libc/release/smoke.c \
|
test/libc/release/smoke.c \
|
||||||
|
@ -20,7 +20,7 @@ o/$(MODE)/test/libc/release/smoke.com.dbg: \
|
||||||
o/$(MODE)/libc/crt/crt.o \
|
o/$(MODE)/libc/crt/crt.o \
|
||||||
o/$(MODE)/ape/ape.o \
|
o/$(MODE)/ape/ape.o \
|
||||||
o/$(MODE)/cosmopolitan.a
|
o/$(MODE)/cosmopolitan.a
|
||||||
@ACTION=CC $(COMPILE) $(CC) \
|
@$(COMPILE) -ACC $(CC) \
|
||||||
-o $@ \
|
-o $@ \
|
||||||
-Os \
|
-Os \
|
||||||
-static \
|
-static \
|
||||||
|
@ -38,7 +38,7 @@ o/$(MODE)/test/libc/release/smoke.com.dbg: \
|
||||||
|
|
||||||
o/$(MODE)/test/libc/release/smokecxx.com: \
|
o/$(MODE)/test/libc/release/smokecxx.com: \
|
||||||
o/$(MODE)/test/libc/release/smokecxx.com.dbg
|
o/$(MODE)/test/libc/release/smokecxx.com.dbg
|
||||||
@$(COMPILE) $(OBJCOPY) -S -O binary $< $@
|
@$(COMPILE) -AOBJCOPY -T$< $(OBJCOPY) -S -O binary $< $@
|
||||||
|
|
||||||
o/$(MODE)/test/libc/release/smokecxx.com.dbg: \
|
o/$(MODE)/test/libc/release/smokecxx.com.dbg: \
|
||||||
test/libc/release/smokecxx.cc \
|
test/libc/release/smokecxx.cc \
|
||||||
|
@ -47,7 +47,7 @@ o/$(MODE)/test/libc/release/smokecxx.com.dbg: \
|
||||||
o/$(MODE)/libc/crt/crt.o \
|
o/$(MODE)/libc/crt/crt.o \
|
||||||
o/$(MODE)/ape/ape.o \
|
o/$(MODE)/ape/ape.o \
|
||||||
o/$(MODE)/cosmopolitan.a
|
o/$(MODE)/cosmopolitan.a
|
||||||
@ACTION=CXX $(COMPILE) $(CXX) \
|
@$(COMPILE) -ACXX $(CXX) \
|
||||||
-o $@ \
|
-o $@ \
|
||||||
-Os \
|
-Os \
|
||||||
-static \
|
-static \
|
||||||
|
@ -70,7 +70,7 @@ o/$(MODE)/test/libc/release/smokeansi.com.dbg: \
|
||||||
o/$(MODE)/libc/crt/crt.o \
|
o/$(MODE)/libc/crt/crt.o \
|
||||||
o/$(MODE)/ape/ape.o \
|
o/$(MODE)/ape/ape.o \
|
||||||
o/$(MODE)/cosmopolitan.a
|
o/$(MODE)/cosmopolitan.a
|
||||||
@ACTION=ANSI $(COMPILE) $(CC) \
|
@$(COMPILE) -AANSI $(CC) \
|
||||||
-o $@ \
|
-o $@ \
|
||||||
-Os \
|
-Os \
|
||||||
-ansi \
|
-ansi \
|
||||||
|
@ -95,19 +95,19 @@ o/$(MODE)/test/libc/release/clang.ok: \
|
||||||
o/$(MODE)/libc/crt/crt.o \
|
o/$(MODE)/libc/crt/crt.o \
|
||||||
o/$(MODE)/ape/ape.o \
|
o/$(MODE)/ape/ape.o \
|
||||||
o/$(MODE)/cosmopolitan.a
|
o/$(MODE)/cosmopolitan.a
|
||||||
@$<
|
@$(COMPILE) -ASHTEST -T$< $<
|
||||||
|
|
||||||
o/$(MODE)/test/libc/release/metal.ok: \
|
o/$(MODE)/test/libc/release/metal.ok: \
|
||||||
test/libc/release/metal.sh \
|
test/libc/release/metal.sh \
|
||||||
o/$(MODE)/examples/hello.com \
|
o/$(MODE)/examples/hello.com \
|
||||||
o/$(MODE)/tool/build/blinkenlights.com.dbg
|
o/$(MODE)/tool/build/blinkenlights.com.dbg
|
||||||
@$<
|
@$(COMPILE) -ASHTEST -T$< $<
|
||||||
|
|
||||||
o/$(MODE)/test/libc/release/emulate.ok: \
|
o/$(MODE)/test/libc/release/emulate.ok: \
|
||||||
test/libc/release/emulate.sh \
|
test/libc/release/emulate.sh \
|
||||||
o/$(MODE)/examples/hello.com \
|
o/$(MODE)/examples/hello.com \
|
||||||
o/$(MODE)/tool/build/blinkenlights.com.dbg
|
o/$(MODE)/tool/build/blinkenlights.com.dbg
|
||||||
@$<
|
@$(COMPILE) -ASHTEST -T$< $<
|
||||||
|
|
||||||
.PHONY: o/$(MODE)/test/libc/release
|
.PHONY: o/$(MODE)/test/libc/release
|
||||||
o/$(MODE)/test/libc/release: \
|
o/$(MODE)/test/libc/release: \
|
||||||
|
|
4
third_party/chibicc/chibicc.mk
vendored
4
third_party/chibicc/chibicc.mk
vendored
|
@ -122,9 +122,9 @@ o/$(MODE)/third_party/chibicc/chibicc.chibicc.o: \
|
||||||
CHIBICC_FLAGS += $(THIRD_PARTY_CHIBICC_DEFINES)
|
CHIBICC_FLAGS += $(THIRD_PARTY_CHIBICC_DEFINES)
|
||||||
|
|
||||||
o/$(MODE)/%.chibicc.o: %.c o/$(MODE)/third_party/chibicc/chibicc.com.dbg
|
o/$(MODE)/%.chibicc.o: %.c o/$(MODE)/third_party/chibicc/chibicc.com.dbg
|
||||||
@ACTION=CHIBICC TARGET=$@ build/do $(CHIBICC) $(CHIBICC_FLAGS) -c -o $@ $<
|
@$(COMPILE) -ACHIBICC -T$@ $(CHIBICC) $(CHIBICC_FLAGS) -c -o $@ $<
|
||||||
o/$(MODE)/%.chibicc2.o: %.c o/$(MODE)/third_party/chibicc/chibicc2.com.dbg
|
o/$(MODE)/%.chibicc2.o: %.c o/$(MODE)/third_party/chibicc/chibicc2.com.dbg
|
||||||
@ACTION=CHIBICC2 TARGET=$@ build/do $(CHIBICC2) $(CHIBICC_FLAGS) -c -o $@ $<
|
@$(COMPILE) -ACHIBICC2 -T$@ $(CHIBICC2) $(CHIBICC_FLAGS) -c -o $@ $<
|
||||||
|
|
||||||
THIRD_PARTY_CHIBICC_LIBS = $(foreach x,$(THIRD_PARTY_CHIBICC_ARTIFACTS),$($(x)))
|
THIRD_PARTY_CHIBICC_LIBS = $(foreach x,$(THIRD_PARTY_CHIBICC_ARTIFACTS),$($(x)))
|
||||||
THIRD_PARTY_CHIBICC_SRCS = $(foreach x,$(THIRD_PARTY_CHIBICC_ARTIFACTS),$($(x)_SRCS))
|
THIRD_PARTY_CHIBICC_SRCS = $(foreach x,$(THIRD_PARTY_CHIBICC_ARTIFACTS),$($(x)_SRCS))
|
||||||
|
|
|
@ -68,9 +68,7 @@ o/$(MODE)/tool/build/build.pkg: \
|
||||||
o/$(MODE)/%.ctest.ok: \
|
o/$(MODE)/%.ctest.ok: \
|
||||||
%.ctest \
|
%.ctest \
|
||||||
$(TOOL_BUILD_CALCULATOR)
|
$(TOOL_BUILD_CALCULATOR)
|
||||||
@TARGET=$@ ACTION=MKWIDES build/do \
|
@$(COMPILE) -AMKWIDES -tT$@ $(TOOL_BUILD_CALCULATOR) $<
|
||||||
$(TOOL_BUILD_CALCULATOR) $< && \
|
|
||||||
touch $@
|
|
||||||
|
|
||||||
o/$(MODE)/tool/build/%.com.dbg: \
|
o/$(MODE)/tool/build/%.com.dbg: \
|
||||||
$(TOOL_BUILD_DEPS) \
|
$(TOOL_BUILD_DEPS) \
|
||||||
|
|
|
@ -18,30 +18,54 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/bits/safemacros.h"
|
#include "libc/bits/safemacros.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
|
#include "libc/calls/copyfile.h"
|
||||||
#include "libc/calls/sigbits.h"
|
#include "libc/calls/sigbits.h"
|
||||||
#include "libc/calls/struct/sigset.h"
|
#include "libc/calls/struct/sigset.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/fmt/conv.h"
|
#include "libc/fmt/conv.h"
|
||||||
|
#include "libc/log/color.internal.h"
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/consts/sig.h"
|
#include "libc/sysv/consts/sig.h"
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
#include "third_party/getopt/getopt.h"
|
||||||
|
|
||||||
#define MANUAL \
|
#define MANUAL \
|
||||||
"\
|
"\
|
||||||
|
SYNOPSIS\n\
|
||||||
|
\n\
|
||||||
|
compile.com [FLAGS] COMMAND [ARGS...]\n\
|
||||||
|
\n\
|
||||||
OVERVIEW\n\
|
OVERVIEW\n\
|
||||||
\n\
|
\n\
|
||||||
GNU/LLVM Compiler Collection Frontend Frontend\n\
|
Compiler Collection Frontend Frontend\n\
|
||||||
\n\
|
\n\
|
||||||
DESCRIPTION\n\
|
DESCRIPTION\n\
|
||||||
\n\
|
\n\
|
||||||
This launches gcc or clang after scrubbing flags.\n\
|
This is a generic command wrapper, e.g.\n\
|
||||||
\n\
|
\n\
|
||||||
EXAMPLE\n\
|
compile.com gcc -o program program.c\n\
|
||||||
\n\
|
\n\
|
||||||
compile.com gcc -o program program.c\n\
|
This wrapper provides the following services:\n\
|
||||||
|
\n\
|
||||||
|
- Ensures the output directory exists\n\
|
||||||
|
- Echo the launched subcommand (silent mode supported if V=0)\n\
|
||||||
|
- Magic filtering of GCC vs. Clang flag incompatibilities\n\
|
||||||
|
- Unzips the vendored GCC toolchain if it hasn't happened yet\n\
|
||||||
|
- Making temporary copies of APE executables w/o side-effects\n\
|
||||||
|
- Truncating long lines in \"TERM=dumb\" terminals like emacs\n\
|
||||||
|
\n\
|
||||||
|
This wrapper is extremely fast.\n\
|
||||||
|
\n\
|
||||||
|
FLAGS\n\
|
||||||
|
\n\
|
||||||
|
-A ACTION specifies short command name for V=0 logging\n\
|
||||||
|
-T TARGET specifies target name for V=0 logging\n\
|
||||||
|
-t touch target on success\n\
|
||||||
|
-n do nothing (used to prime the executable)\n\
|
||||||
|
-? print help\n\
|
||||||
\n"
|
\n"
|
||||||
|
|
||||||
struct Flags {
|
struct Flags {
|
||||||
|
@ -65,13 +89,22 @@ bool wantnopg;
|
||||||
bool wantpg;
|
bool wantpg;
|
||||||
bool wantrecord;
|
bool wantrecord;
|
||||||
bool wantubsan;
|
bool wantubsan;
|
||||||
|
bool touchtarget;
|
||||||
|
|
||||||
char *cc;
|
char *cmd;
|
||||||
|
char *cachedcmd;
|
||||||
|
char *originalcmd;
|
||||||
char *colorflag;
|
char *colorflag;
|
||||||
char *outdir;
|
char *outdir;
|
||||||
char *outpath;
|
char *outpath;
|
||||||
|
char *action;
|
||||||
|
char *target;
|
||||||
char ccpath[PATH_MAX];
|
char ccpath[PATH_MAX];
|
||||||
int ccversion;
|
int ccversion;
|
||||||
|
int columns;
|
||||||
|
|
||||||
|
sigset_t mask;
|
||||||
|
sigset_t savemask;
|
||||||
|
|
||||||
struct Flags flags;
|
struct Flags flags;
|
||||||
struct Command command;
|
struct Command command;
|
||||||
|
@ -129,6 +162,17 @@ const char *const kGccOnlyFlags[] = {
|
||||||
"-mno-fentry",
|
"-mno-fentry",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
char *DescribeCommand(void) {
|
||||||
|
if (iscc) {
|
||||||
|
if (isgcc) {
|
||||||
|
return xasprintf("gcc %d", ccversion);
|
||||||
|
} else if (isclang) {
|
||||||
|
return xasprintf("clang %d", ccversion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return basename(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
bool IsGccOnlyFlag(const char *s) {
|
bool IsGccOnlyFlag(const char *s) {
|
||||||
int m, l, r, x;
|
int m, l, r, x;
|
||||||
l = 0;
|
l = 0;
|
||||||
|
@ -174,40 +218,75 @@ void AddFlag(char *s) {
|
||||||
command.n += n;
|
command.n += n;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
command.p = realloc(command.p, command.n + 1);
|
command.p = realloc(command.p, command.n + 2);
|
||||||
command.p[command.n] = '\n';
|
command.p[command.n++] = '\r';
|
||||||
command.n += 1;
|
command.p[command.n++] = '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int Launch(void) {
|
||||||
int i, ws, pid;
|
int ws, pid;
|
||||||
sigset_t mask, savemask;
|
if ((pid = vfork()) == -1) exit(errno);
|
||||||
|
if (!pid) {
|
||||||
|
sigprocmask(SIG_SETMASK, &savemask, NULL);
|
||||||
|
execv(cmd, flags.p);
|
||||||
|
_exit(127);
|
||||||
|
}
|
||||||
|
while (waitpid(pid, &ws, 0) == -1) {
|
||||||
|
if (errno != EINTR) exit(errno);
|
||||||
|
}
|
||||||
|
return ws;
|
||||||
|
}
|
||||||
|
|
||||||
if (argc == 1) {
|
int main(int argc, char *argv[]) {
|
||||||
|
char *p;
|
||||||
|
size_t n;
|
||||||
|
int i, ws, rc, opt;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* parse prefix arguments
|
||||||
|
*/
|
||||||
|
while ((opt = getopt(argc, argv, "?hntA:T:")) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'n':
|
||||||
|
exit(0);
|
||||||
|
case 't':
|
||||||
|
touchtarget = true;
|
||||||
|
break;
|
||||||
|
case 'A':
|
||||||
|
action = optarg;
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
target = optarg;
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
case 'h':
|
||||||
|
write(1, MANUAL, sizeof(MANUAL) - 1);
|
||||||
|
exit(0);
|
||||||
|
default:
|
||||||
|
write(2, MANUAL, sizeof(MANUAL) - 1);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (optind == argc) {
|
||||||
write(2, MANUAL, sizeof(MANUAL) - 1);
|
write(2, MANUAL, sizeof(MANUAL) - 1);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc == 2 && !strcmp(argv[1], "--do-nothing")) {
|
cmd = argv[optind];
|
||||||
exit(0);
|
if (!strchr(cmd, '/')) {
|
||||||
}
|
if (!(cmd = commandv(cmd, ccpath))) exit(127);
|
||||||
|
|
||||||
if (!isdirectory("o/third_party/gcc")) {
|
|
||||||
system("third_party/gcc/unbundle.sh");
|
|
||||||
}
|
|
||||||
|
|
||||||
cc = argv[1];
|
|
||||||
if (!strchr(cc, '/')) {
|
|
||||||
if (!(cc = commandv(argv[1], ccpath))) exit(127);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ccversion = atoi(firstnonnull(emptytonull(getenv("CCVERSION")), "4"));
|
ccversion = atoi(firstnonnull(emptytonull(getenv("CCVERSION")), "4"));
|
||||||
isgcc = !!strstr(basename(cc), "gcc");
|
isgcc = !!strstr(basename(cmd), "gcc");
|
||||||
isclang = !!strstr(basename(cc), "clang");
|
isclang = !!strstr(basename(cmd), "clang");
|
||||||
iscc = isgcc | isclang;
|
iscc = isgcc | isclang;
|
||||||
|
|
||||||
for (i = 1; i < argc; ++i) {
|
/*
|
||||||
|
* ingest flag arguments
|
||||||
|
*/
|
||||||
|
for (i = optind; i < argc; ++i) {
|
||||||
if (argv[i][0] != '-') {
|
if (argv[i][0] != '-') {
|
||||||
AddFlag(argv[i]);
|
AddFlag(argv[i]);
|
||||||
continue;
|
continue;
|
||||||
|
@ -297,7 +376,13 @@ int main(int argc, char *argv[]) {
|
||||||
AddFlag(argv[i]);
|
AddFlag(argv[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!outpath) {
|
||||||
|
outpath = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* append special flags
|
||||||
|
*/
|
||||||
if (iscc) {
|
if (iscc) {
|
||||||
if (isclang) {
|
if (isclang) {
|
||||||
/* AddFlag("-fno-integrated-as"); */
|
/* AddFlag("-fno-integrated-as"); */
|
||||||
|
@ -337,8 +422,14 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* terminate argument list passed to subprocess
|
||||||
|
*/
|
||||||
AddFlag(NULL);
|
AddFlag(NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ensure output directory exists
|
||||||
|
*/
|
||||||
if (outpath) {
|
if (outpath) {
|
||||||
outdir = xdirname(outpath);
|
outdir = xdirname(outpath);
|
||||||
if (!isdirectory(outdir)) {
|
if (!isdirectory(outdir)) {
|
||||||
|
@ -346,23 +437,100 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
write(2, command.p, command.n);
|
/*
|
||||||
|
* log command being run
|
||||||
|
*/
|
||||||
|
if (!strcmp(nulltoempty(getenv("V")), "0") && !IsTerminalInarticulate()) {
|
||||||
|
p = xasprintf("\e[F\e[K%-15s%s\r\n", firstnonnull(action, "BUILD"),
|
||||||
|
firstnonnull(target, nulltoempty(outpath)));
|
||||||
|
n = strlen(p);
|
||||||
|
} else {
|
||||||
|
if (IsTerminalInarticulate() &&
|
||||||
|
(columns = atoi(nulltoempty(getenv("COLUMNS")))) > 25 &&
|
||||||
|
command.n > columns + 2) {
|
||||||
|
/* emacs command window is very slow so truncate lines */
|
||||||
|
command.n = columns + 2;
|
||||||
|
command.p[command.n - 5] = '.';
|
||||||
|
command.p[command.n - 4] = '.';
|
||||||
|
command.p[command.n - 3] = '.';
|
||||||
|
command.p[command.n - 2] = '\r';
|
||||||
|
command.p[command.n - 1] = '\n';
|
||||||
|
}
|
||||||
|
p = command.p;
|
||||||
|
n = command.n;
|
||||||
|
}
|
||||||
|
write(2, p, n);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* create temporary copy when launching APE binaries
|
||||||
|
*/
|
||||||
|
if (!IsWindows() && endswith(cmd, ".com")) {
|
||||||
|
cachedcmd = xasprintf("o/%s", cmd);
|
||||||
|
if (fileexists(cachedcmd)) {
|
||||||
|
cmd = cachedcmd;
|
||||||
|
} else {
|
||||||
|
if (startswith(cmd, "o/")) {
|
||||||
|
cachedcmd = NULL;
|
||||||
|
}
|
||||||
|
originalcmd = cmd;
|
||||||
|
cmd = xasprintf("%s.tmp.%d", originalcmd, getpid());
|
||||||
|
copyfile(originalcmd, cmd, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* launch command
|
||||||
|
*/
|
||||||
sigfillset(&mask);
|
sigfillset(&mask);
|
||||||
sigprocmask(SIG_BLOCK, &mask, &savemask);
|
sigprocmask(SIG_BLOCK, &mask, &savemask);
|
||||||
if ((pid = vfork()) == -1) exit(errno);
|
ws = Launch();
|
||||||
if (!pid) {
|
|
||||||
sigprocmask(SIG_SETMASK, &savemask, NULL);
|
/*
|
||||||
execv(cc, flags.p);
|
* if execve() failed unzip gcc and try again
|
||||||
_exit(127);
|
*/
|
||||||
}
|
if (WIFEXITED(ws) && WEXITSTATUS(ws) == 127 &&
|
||||||
while (waitpid(pid, &ws, 0) == -1) {
|
startswith(cmd, "o/third_party/gcc") &&
|
||||||
if (errno != EINTR) exit(errno);
|
fileexists("third_party/gcc/unbundle.sh")) {
|
||||||
|
system("third_party/gcc/unbundle.sh");
|
||||||
|
ws = Launch();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WIFEXITED(ws)) {
|
/*
|
||||||
return WEXITSTATUS(ws);
|
* cleanup temporary copy of ape executable
|
||||||
} else {
|
*/
|
||||||
return 128 + WTERMSIG(ws);
|
if (originalcmd) {
|
||||||
|
if (cachedcmd && WIFEXITED(ws) && !WEXITSTATUS(ws)) {
|
||||||
|
makedirs(xdirname(cachedcmd), 0755);
|
||||||
|
rename(cmd, cachedcmd);
|
||||||
|
} else {
|
||||||
|
unlink(cmd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* propagate exit
|
||||||
|
*/
|
||||||
|
if (WIFEXITED(ws)) {
|
||||||
|
if (!WEXITSTATUS(ws)) {
|
||||||
|
if (touchtarget && target) {
|
||||||
|
makedirs(xdirname(target), 0755);
|
||||||
|
touch(target, 0644);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
p = xasprintf("%s%s EXITED WITH %d%s: %.*s\r\n", RED2, DescribeCommand(),
|
||||||
|
WEXITSTATUS(ws), RESET, command.n, command.p);
|
||||||
|
rc = WEXITSTATUS(ws);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p = xasprintf("%s%s TERMINATED BY %s%s: %.*s\r\n", RED2, DescribeCommand(),
|
||||||
|
strsignal(WTERMSIG(ws)), RESET, command.n, command.p);
|
||||||
|
rc = 128 + WTERMSIG(ws);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* print full command in the event of error
|
||||||
|
*/
|
||||||
|
write(2, p, strlen(p));
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue