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:
Justine Tunney
2021-02-19 22:20:38 -08:00
parent c797f139bb
commit b740cca642
39 changed files with 440 additions and 916 deletions

View File

@ -215,15 +215,15 @@ o/$(MODE)/hdrs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(HDRS) $(
$(file >$@) $(foreach x,$(HDRS) $(INCS),$(file >>$@,$(x)))
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)
@rm -f $@
@ACTION=TAGS TARGET=$@ build/do $(TAGS) $(TAGSFLAGS) -L $< -o $@
@$(COMPILE) -ATAGS -T$@ $(TAGS) $(TAGSFLAGS) -L $< -o $@
HTAGS: o/$(MODE)/hdrs.txt $(HDRS)
@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
find -name \*.h -or -name \*.c -or -name \*.S | \
@ -315,7 +315,7 @@ o/cosmopolitan.h: \
o/$(MODE)/tool/build/rollup.com \
libc/integral/normalize.inc \
$(foreach x,$(COSMOPOLITAN_HEADERS),$($(x)_HDRS))
@ACTION=ROLLUP TARGET=$@ build/do $^ >$@
@$(COMPILE) -AROLLUP -T$@ $^ >$@
o/cosmopolitan.html: \
o/$(MODE)/third_party/chibicc/chibicc.com.dbg \

View File

@ -1522,7 +1522,7 @@ metal.thunk:
.byte 0x0f,0x1f,0207 # nop rdi binbase
.long (IMAGE_BASE_VIRTUAL-IMAGE_BASE_REAL)/512
#endif
/ 𝑠𝑙𝑖𝑑𝑒
// 𝑠𝑙𝑖𝑑𝑒
.endfn metal.thunk
metal:
xor %eax,%eax # clear bss

View File

@ -20,8 +20,8 @@ APE = $(APE_DEPS) \
o/$(MODE)/ape/ape.lds
APELINK = \
ACTION=LINK.ape \
$(COMPILE) \
-ALINK.ape \
$(LINK) \
$(LINKARGS) \
$(OUTPUT_OPTION)

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -62,12 +62,15 @@ CLANG = clang-10
FC = gfortran #/opt/cross9f/bin/x86_64-linux-musl-gfortran
# 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
CC = o/third_party/gcc/bin/x86_64-linux-musl-gcc
CXX = o/third_party/gcc/bin/x86_64-linux-musl-g++
CXXFILT = o/third_party/gcc/bin/x86_64-linux-musl-c++filt
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
GCC = o/third_party/gcc/bin/x86_64-linux-musl-gcc
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 := ,
PWD := $(shell pwd)
IMAGE_BASE_VIRTUAL ?= 0x400000
HELLO := $(shell build/hello)
TMPDIR := $(shell build/findtmp)
LOGFMT := $(shell build/getlogfmt)
COMPILE := $(shell build/getcompile)
CCNAME := $(shell build/getccname $(CC))
CCVERSION := $(shell build/getccversion $(CC))
BLAH1 := $(shell build/zipobj 2>/dev/null)
BLAH2 := $(shell build/package 2>/dev/null)
export ADDR2LINE
export CCNAME
export CCVERSION
export COMPILE
export CP
@ -314,8 +313,7 @@ PREPROCESS = $(CC) $(PREPROCESS.flags)
PREPROCESS.lds = $(CC) $(PREPROCESS.lds.flags)
LINK = $(LD) $(LINK.flags)
ELF = o/libc/elf/elf.lds
ELFLINK = ACTION=LINK.elf $(LINK) $(LINKARGS) $(OUTPUT_OPTION)
ARCHIVE = $(AR) $(ARFLAGS)
ELFLINK = $(COMPILE) -ALINK.elf $(LINK) $(LINKARGS) $(OUTPUT_OPTION)
LINKARGS = $(patsubst %.lds,-T %.lds,$(call uniqr,$(LD.libs) $(filter-out %.pkg,$^)))
LOLSAN = build/lolsan -b $(IMAGE_BASE_VIRTUAL)

View File

@ -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 "$@"

View File

@ -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

View File

@ -5,7 +5,7 @@
if ! [ o/build/bootstrap/compile.com -nt build/bootstrap/compile.com ]; then
mkdir -p o/build/bootstrap/
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
fi

View File

@ -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
View 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

View File

@ -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

View File

@ -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 "$@"

View File

@ -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 "$@"

View File

@ -23,9 +23,8 @@
# - tool/build/runitd.c
.PRECIOUS: o/$(MODE)/%.com.ok
o/$(MODE)/%.com.ok: \
o/$(MODE)/tool/build/runit.com.dbg \
o/$(MODE)/tool/build/runitd.com \
o/$(MODE)/%.com.ok: \
o/$(MODE)/tool/build/runit.com \
o/$(MODE)/tool/build/runitd.com \
o/$(MODE)/%.com
@ACTION=TEST TARGET=$@ build/do $^ $(HOSTS)
@touch $@
@$(COMPILE) -ATEST -tT$@ $^ $(HOSTS)

View File

@ -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 "$@"

View File

@ -16,73 +16,67 @@
MAKEFLAGS += --no-builtin-rules
o/%.a:; @$(ARCHIVE) $@ $^
o/%.o: %.s; @TARGET=$@ $(COMPILE) $(OBJECTIFY.s) $(OUTPUT_OPTION) $<
o/%.o: o/%.s; @TARGET=$@ $(COMPILE) $(OBJECTIFY.s) $(OUTPUT_OPTION) $<
o/%.s: %.S; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $<
o/%.s: o/%.S; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $<
o/%.i: %.S; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $<
o/%.o: %.S; @ACTION=OBJECTIFY.S $(COMPILE) $(OBJECTIFY.S) $(OUTPUT_OPTION) $<
o/%.o: o/%.S; @ACTION=OBJECTIFY.S $(COMPILE) $(OBJECTIFY.S) $(OUTPUT_OPTION) $<
o/%.s: %.i; @ACTION=COMPILE.i $(COMPILE) $(COMPILE.i) $(OUTPUT_OPTION) $<
o/%.s: o/%.i; @ACTION=COMPILE.i $(COMPILE) $(COMPILE.i) $(OUTPUT_OPTION) $<
o/%.o: %.cc; @ACTION=OBJECTIFY.cxx $(COMPILE) $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
o/%.o: o/%.cc; @ACTION=OBJECTIFY.cxx $(COMPILE) $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
o/%.lds: %.lds; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS.lds) $(OUTPUT_OPTION) $<
o/%.inc: %.h; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) -D__ASSEMBLER__ -P $<
o/%.pkg:; @build/package $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) $(filter %.o,$^)
o/%.h.ok: %.h; @ACTION=CHECK.h $(COMPILE) $(COMPILE.c) -x c -g0 -o $@ $<
o/%.h.okk: %.h; @ACTION=CHECK.h $(COMPILE) $(COMPILE.cxx) -x c++ -g0 -o $@ $<
o/%.greg.o: %.greg.c; @ACTION=OBJECTIFY.greg $(COMPILE) $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
o/%.zip.o: o/%; @build/zipobj $(ZIPOBJ_FLAGS) $(OUTPUT_OPTION) $<
o/%.a: ; @$(COMPILE) -AARCHIVE -T$@ $(AR) $(ARFLAGS) $@ $^
o/%.o: %.s ; @$(COMPILE) -AOBJECTIFY.s $(OBJECTIFY.s) $(OUTPUT_OPTION) $<
o/%.o: o/%.s ; @$(COMPILE) -AOBJECTIFY.s $(OBJECTIFY.s) $(OUTPUT_OPTION) $<
o/%.s: %.S ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) $<
o/%.s: o/%.S ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) $<
o/%.i: %.S ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) $<
o/%.o: %.S ; @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $<
o/%.o: o/%.S ; @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $<
o/%.s: %.i ; @$(COMPILE) -ACOMPILE.i $(COMPILE.i) $(OUTPUT_OPTION) $<
o/%.s: o/%.i ; @$(COMPILE) -ACOMPILE.i $(COMPILE.i) $(OUTPUT_OPTION) $<
o/%.o: %.cc ; @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
o/%.o: o/%.cc ; @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
o/%.lds: %.lds ; @$(COMPILE) -APREPROCESS $(PREPROCESS.lds) $(OUTPUT_OPTION) $<
o/%.inc: %.h ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) -D__ASSEMBLER__ -P $<
o/%.pkg: ; @$(COMPILE) -APACKAGE -T$@ $(PKG) $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) $(filter %.o,$^)
o/%.h.ok: %.h ; @$(COMPILE) -ACHECK.h $(COMPILE.c) -x c -g0 -o $@ $<
o/%.h.okk: %.h ; @$(COMPILE) -ACHECK.h $(COMPILE.cxx) -x c++ -g0 -o $@ $<
o/%.greg.o: %.greg.c ; @$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
o/%.zip.o: o/% ; @$(COMPILE) -AZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) $(OUTPUT_OPTION) $<
o/$(MODE)/%.a:; @$(ARCHIVE) $@ $^
o/$(MODE)/%: o/$(MODE)/%.dbg; @ACTION=OBJCOPY TARGET=$@ $(COMPILE) $(OBJCOPY) -S -O binary $< $@
o/$(MODE)/%.o: %.s; @TARGET=$@ $(COMPILE) $(OBJECTIFY.s) $(OUTPUT_OPTION) $<
o/$(MODE)/%.o: o/$(MODE)/%.s; @TARGET=$@ $(COMPILE) $(OBJECTIFY.s) $(OUTPUT_OPTION) $<
o/$(MODE)/%.s: %.S; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $<
o/$(MODE)/%.s: o/$(MODE)/%.S; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $<
o/$(MODE)/%.o: %.c; @ACTION=OBJECTIFY.c $(COMPILE) $(OBJECTIFY.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.o: %.f; @ACTION=OBJECTIFY.f $(COMPILE) $(OBJECTIFY.f) $(OUTPUT_OPTION) $<
o/$(MODE)/%.o: %.F; @ACTION=OBJECTIFY.F $(COMPILE) $(OBJECTIFY.F) $(OUTPUT_OPTION) $<
o/$(MODE)/%.o: o/$(MODE)/%.c; @ACTION=OBJECTIFY.c $(COMPILE) $(OBJECTIFY.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.ss: %.c; @ACTION=COMPILE.c $(COMPILE) $(COMPILE.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.ss: o/$(MODE)/%.c; @ACTION=OBJECTIFY.s $(COMPILE) $(COMPILE.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.i: %.S; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $<
o/$(MODE)/%.i: %.c; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $<
o/$(MODE)/%.i: %.cc; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $<
o/$(MODE)/%.i: o/$(MODE)/%.c; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $<
o/$(MODE)/%.h: %.c; @ACTION=AMALGAMATE $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) -fdirectives-only -P $<
o/$(MODE)/%.h: o/$(MODE)/%.c; @ACTION=AMALGAMATE $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) -fdirectives-only -P $<
o/$(MODE)/%.o: %.S; @ACTION=OBJECTIFY.S $(COMPILE) $(OBJECTIFY.S) $(OUTPUT_OPTION) $<
o/$(MODE)/%.o: o/$(MODE)/%.S; @ACTION=OBJECTIFY.S $(COMPILE) $(OBJECTIFY.S) $(OUTPUT_OPTION) $<
o/$(MODE)/%.s: %.i; @ACTION=COMPILE.i $(COMPILE) $(COMPILE.i) $(OUTPUT_OPTION) $<
o/$(MODE)/%.s: o/$(MODE)/%.i; @ACTION=COMPILE.i $(COMPILE) $(COMPILE.i) $(OUTPUT_OPTION) $<
o/$(MODE)/%.o: %.cc; @ACTION=OBJECTIFY.cxx $(COMPILE) $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
o/$(MODE)/%.o: o/$(MODE)/%.cc; @ACTION=OBJECTIFY.cxx $(COMPILE) $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
o/$(MODE)/%.lds: %.lds; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS.lds) $(OUTPUT_OPTION) $<
o/$(MODE)/%.h.ok: %.h; @ACTION=CHECK.h $(COMPILE) $(COMPILE.c) -x c -g0 -o $@ $<
o/$(MODE)/%.h.okk: %.h; @ACTION=CHECK.h $(COMPILE) $(COMPILE.cxx) -x c++ -g0 -o $@ $<
o/$(MODE)/%.o: %.greg.c; @ACTION=OBJECTIFY.greg $(COMPILE) $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.greg.o: %.greg.c; @ACTION=OBJECTIFY.greg $(COMPILE) $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.ansi.o: %.ansi.c; @ACTION=OBJECTIFY.ansi $(COMPILE) $(OBJECTIFY.ansi.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.ansi.o: %.c; @ACTION=OBJECTIFY.ansi $(COMPILE) $(OBJECTIFY.ansi.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.c99.o: %.c99.c; @ACTION=OBJECTIFY.c99 $(COMPILE) $(OBJECTIFY.c99.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.c11.o: %.c11.c; @ACTION=OBJECTIFY.c11 $(COMPILE) $(OBJECTIFY.c11.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.c2x.o: %.c2x.c; @ACTION=OBJECTIFY.c2x $(COMPILE) $(OBJECTIFY.c2x.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.initabi.o: %.initabi.c; @ACTION=OBJECTIFY.init $(COMPILE) $(OBJECTIFY.initabi.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.ncabi.o: %.ncabi.c; @ACTION=OBJECTIFY.nc $(COMPILE) $(OBJECTIFY.ncabi.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.real.o: %.c; @ACTION=OBJECTIFY.real $(COMPILE) $(OBJECTIFY.real.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.runs: o/$(MODE)/%; @ACTION=CHECK.runs TARGET=$< build/runcom $< $(TESTARGS) && touch $@
o/$(MODE)/%.pkg:; @build/package $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) $(filter %.o,$^)
o/$(MODE)/%.zip.o: %; @build/zipobj $(ZIPOBJ_FLAGS) $(OUTPUT_OPTION) $<
o/$(MODE)/%.a: ; @$(COMPILE) -AARCHIVE -T$@ $(AR) $(ARFLAGS) $@ $^
o/$(MODE)/%: o/$(MODE)/%.dbg ; @$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
o/$(MODE)/%.o: %.s ; @$(COMPILE) -AOBJECTIFY.s $(OBJECTIFY.s) $(OUTPUT_OPTION) $<
o/$(MODE)/%.o: o/$(MODE)/%.s ; @$(COMPILE) -AOBJECTIFY.s $(OBJECTIFY.s) $(OUTPUT_OPTION) $<
o/$(MODE)/%.s: %.S ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) $<
o/$(MODE)/%.s: o/$(MODE)/%.S ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) $<
o/$(MODE)/%.o: %.c ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.o: %.f ; @$(COMPILE) -AOBJECTIFY.f $(OBJECTIFY.f) $(OUTPUT_OPTION) $<
o/$(MODE)/%.o: %.F ; @$(COMPILE) -AOBJECTIFY.F $(OBJECTIFY.F) $(OUTPUT_OPTION) $<
o/$(MODE)/%.o: o/$(MODE)/%.c ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.ss: %.c ; @$(COMPILE) -ACOMPILE.c $(COMPILE.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.ss: o/$(MODE)/%.c ; @$(COMPILE) -AOBJECTIFY.s $(COMPILE.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.i: %.S ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) $<
o/$(MODE)/%.i: %.c ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) $<
o/$(MODE)/%.i: %.cc ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) $<
o/$(MODE)/%.i: o/$(MODE)/%.c ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) $<
o/$(MODE)/%.h: %.c ; @$(COMPILE) -AAMALGAMATE $(PREPROCESS) $(OUTPUT_OPTION) -fdirectives-only -P $<
o/$(MODE)/%.h: o/$(MODE)/%.c ; @$(COMPILE) -AAMALGAMATE $(PREPROCESS) $(OUTPUT_OPTION) -fdirectives-only -P $<
o/$(MODE)/%.o: %.S ; @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $<
o/$(MODE)/%.o: o/$(MODE)/%.S ; @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $<
o/$(MODE)/%.s: %.i ; @$(COMPILE) -ACOMPILE.i $(COMPILE.i) $(OUTPUT_OPTION) $<
o/$(MODE)/%.s: o/$(MODE)/%.i ; @$(COMPILE) -ACOMPILE.i $(COMPILE.i) $(OUTPUT_OPTION) $<
o/$(MODE)/%.o: %.cc ; @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
o/$(MODE)/%.o: o/$(MODE)/%.cc ; @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
o/$(MODE)/%.lds: %.lds ; @$(COMPILE) -APREPROCESS $(PREPROCESS.lds) $(OUTPUT_OPTION) $<
o/$(MODE)/%.h.ok: %.h ; @$(COMPILE) -ACHECK.h $(COMPILE.c) -x c -g0 -o $@ $<
o/$(MODE)/%.h.okk: %.h ; @$(COMPILE) -ACHECK.h $(COMPILE.cxx) -x c++ -g0 -o $@ $<
o/$(MODE)/%.o: %.greg.c ; @$(COMPILE) -AOBJECTIFY.greg $(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 ; @$(COMPILE) -AOBJECTIFY.ansi $(OBJECTIFY.ansi.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.ansi.o: %.c ; @$(COMPILE) -AOBJECTIFY.ansi $(OBJECTIFY.ansi.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.c99.o: %.c99.c ; @$(COMPILE) -AOBJECTIFY.c99 $(OBJECTIFY.c99.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.c11.o: %.c11.c ; @$(COMPILE) -AOBJECTIFY.c11 $(OBJECTIFY.c11.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.c2x.o: %.c2x.c ; @$(COMPILE) -AOBJECTIFY.c2x $(OBJECTIFY.c2x.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.initabi.o: %.initabi.c ; @$(COMPILE) -AOBJECTIFY.init $(OBJECTIFY.initabi.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.ncabi.o: %.ncabi.c ; @$(COMPILE) -AOBJECTIFY.nc $(OBJECTIFY.ncabi.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.real.o: %.c ; @$(COMPILE) -AOBJECTIFY.real $(OBJECTIFY.real.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.runs: o/$(MODE)/% ; @$(COMPILE) -ACHECK -tT$@ $< $(TESTARGS)
o/$(MODE)/%.pkg: ; @$(COMPILE) -APACKAGE -T$@ $(PKG) $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) $(filter %.o,$^)
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: %.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) >$@

View File

@ -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

View File

@ -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 "$@"

View File

@ -133,10 +133,6 @@ usr/share/dict/words: usr/share/dict/words.gz
@$(MKDIR) $(dir $@)
@$(GZ) $(ZFLAGS) -d <$< >$@
o/$(MODE)/examples/ugh.ok: o/$(MODE)/examples/wut.com
$<
touch $@
.PHONY: o/$(MODE)/examples
o/$(MODE)/examples: \
o/$(MODE)/examples/package \

29
examples/touch.c Normal file
View 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;
}

View File

@ -263,6 +263,7 @@ int sys_sync_nt(void) hidden;
int sys_sysinfo_nt(struct sysinfo *) hidden;
int sys_truncate_nt(const char *, u64) 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;
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;

View 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);
}
}

View File

@ -17,7 +17,9 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/errno.h"
#include "libc/sysv/consts/o.h"
#include "libc/time/time.h"
/**
* Creates new file or changes modified time on existing one.
@ -28,7 +30,12 @@
* @see creat()
*/
int touch(const char *file, uint32_t mode) {
int fd;
if ((fd = open(file, O_CREAT | O_WRONLY, mode)) == -1) return -1;
return close(fd);
int rc, fd, olderr;
olderr = errno;
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;
}

View File

@ -26,16 +26,17 @@
*
* @param times if NULL means now
* @return 0 on success or -1 w/ errno
* @asyncsignalsafe
*/
int utime(const char *path, const struct utimbuf *times) {
struct timespec ts[2];
struct timeval tv[2];
if (times) {
ts[0].tv_sec = times->actime;
ts[0].tv_nsec = 0;
ts[1].tv_sec = times->modtime;
ts[1].tv_nsec = 0;
return utimensat(AT_FDCWD, path, ts, 0);
tv[0].tv_sec = times->actime;
tv[0].tv_usec = 0;
tv[1].tv_sec = times->modtime;
tv[1].tv_usec = 0;
return utimes(path, tv);
} else {
return utimensat(AT_FDCWD, path, NULL, 0);
return utimes(path, NULL);
}
}

View File

@ -32,7 +32,7 @@
#include "libc/time/time.h"
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;
int64_t fh;
uint16_t path16[PATH_MAX];

View File

@ -17,12 +17,33 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/internal.h"
#include "libc/errno.h"
#include "libc/sysv/consts/at.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 flags) {
int rc, olderr;
struct timeval tv[2];
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 {
return sys_utimensat_xnu(dirfd, path, ts, flags);
}

View File

@ -24,7 +24,8 @@
*
* @param ts is atime/mtime, or null for current time
* @param flags can have AT_SYMLINK_NOFOLLOW
* @note no rhel5 support
* @note no xnu/rhel5 support if dirfd≠AT_FDCWDflags≠0
* @asyncsignalsafe
*/
int utimensat(int dirfd, const char *path,
const struct timespec ts[hasatleast 2], int flags) {

View File

@ -16,6 +16,8 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/internal.h"
#include "libc/dce.h"
#include "libc/sysv/consts/at.h"
#include "libc/time/time.h"
@ -24,17 +26,17 @@
*
* @param times is access/modified and NULL means now
* @return 0 on success or -1 w/ errno
* @asyncsignalsafe
* @see stat()
*/
int utimes(const char *path, const struct timeval tv[hasatleast 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 utimensat(AT_FDCWD, path, ts, 0);
int utimes(const char *path, const struct timeval tv[2]) {
if (!IsWindows()) {
/*
* we don't modernize utimes() into utimensat() because the
* latter is poorly supported and utimes() works everywhere
*/
return sys_utimes(path, tv);
} else {
return utimensat(AT_FDCWD, path, NULL, 0);
return sys_utimes_nt(path, tv);
}
}

View File

@ -151,8 +151,6 @@ $(LIBC_NT_NTDLL_A): \
libc/nt/ntdll/ \
$(LIBC_NT_NTDLL_A).pkg \
$(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_OBJS) \

View File

@ -61,31 +61,25 @@ o/$(MODE)/libc/unicode: $(LIBC_UNICODE) $(LIBC_UNICODE_CHECKS)
o/$(MODE)/libc/unicode/eastasianwidth.bin: \
libc/unicode/eastasianwidth.txt \
o/$(MODE)/tool/decode/mkwides.com
@TARGET=$@ ACTION=MKWIDES build/do \
o/$(MODE)/tool/decode/mkwides.com -o $@ $<
@$(COMPILE) -AMKWIDES -T$@ o/$(MODE)/tool/decode/mkwides.com -o $@ $<
o/$(MODE)/libc/unicode/eastasianwidth.bin.lz4: \
o/$(MODE)/libc/unicode/eastasianwidth.bin \
o/$(MODE)/third_party/lz4cli/lz4cli.com
@TARGET=$@ ACTION=LZ4 build/do \
o/$(MODE)/third_party/lz4cli/lz4cli.com -q -f -9 --content-size $< $@
@$(COMPILE) -ALZ4 -T$@ o/$(MODE)/third_party/lz4cli/lz4cli.com -q -f -9 --content-size $< $@
o/$(MODE)/libc/unicode/eastasianwidth.s: \
o/$(MODE)/libc/unicode/eastasianwidth.bin.lz4 \
o/$(MODE)/tool/build/lz4toasm.com
@TARGET=$@ ACTION=BIN2ASM build/do \
o/$(MODE)/tool/build/lz4toasm.com -s kEastAsianWidth -o $@ $<
@$(COMPILE) -ABIN2ASM -T$@ o/$(MODE)/tool/build/lz4toasm.com -s kEastAsianWidth -o $@ $<
o/$(MODE)/libc/unicode/combiningchars.bin: \
libc/unicode/unicodedata.txt \
o/$(MODE)/tool/decode/mkcombos.com
@TARGET=$@ ACTION=MKCOMBOS build/do \
o/$(MODE)/tool/decode/mkcombos.com -o $@ $<
@$(COMPILE) -AMKCOMBOS -T$@ o/$(MODE)/tool/decode/mkcombos.com -o $@ $<
o/$(MODE)/libc/unicode/combiningchars.bin.lz4: \
o/$(MODE)/libc/unicode/combiningchars.bin \
o/$(MODE)/third_party/lz4cli/lz4cli.com
@TARGET=$@ ACTION=LZ4 build/do \
o/$(MODE)/third_party/lz4cli/lz4cli.com -q -f -9 --content-size $< $@
@$(COMPILE) -ALZ4 -T$@ o/$(MODE)/third_party/lz4cli/lz4cli.com -q -f -9 --content-size $< $@
o/$(MODE)/libc/unicode/combiningchars.s: \
o/$(MODE)/libc/unicode/combiningchars.bin.lz4 \
o/$(MODE)/tool/build/lz4toasm.com
@TARGET=$@ ACTION=BIN2ASM build/do \
o/$(MODE)/tool/build/lz4toasm.com -s kCombiningChars -o $@ $<
@$(COMPILE) -ABIN2ASM -T$@ o/$(MODE)/tool/build/lz4toasm.com -s kCombiningChars -o $@ $<

View File

@ -2,7 +2,6 @@
# smoke test userspace binary emulation
CMD="o/$MODE/tool/build/blinkenlights.com.dbg o/$MODE/examples/hello.com"
printf '%s\n' "$CMD" >&2
if OUTPUT="$($CMD)"; then
if [ x"$OUTPUT" = x"hello world" ]; then
touch o/$MODE/test/libc/release/emulate.ok

View File

@ -2,7 +2,6 @@
# 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"
printf '%s\n' "$CMD" >&2
if OUTPUT="$($CMD)"; then
if [ x"$OUTPUT" = x"hello world" ]; then
touch o/$MODE/test/libc/release/metal.ok

View File

@ -7,11 +7,11 @@ o/$(MODE)/test/libc/release/cosmopolitan.zip: \
o/$(MODE)/libc/crt/crt.o \
o/$(MODE)/ape/ape.o \
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.dbg
@$(COMPILE) $(OBJCOPY) -S -O binary $< $@
@$(COMPILE) -AOBJCOPY -T$< $(OBJCOPY) -S -O binary $< $@
o/$(MODE)/test/libc/release/smoke.com.dbg: \
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)/ape/ape.o \
o/$(MODE)/cosmopolitan.a
@ACTION=CC $(COMPILE) $(CC) \
@$(COMPILE) -ACC $(CC) \
-o $@ \
-Os \
-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.dbg
@$(COMPILE) $(OBJCOPY) -S -O binary $< $@
@$(COMPILE) -AOBJCOPY -T$< $(OBJCOPY) -S -O binary $< $@
o/$(MODE)/test/libc/release/smokecxx.com.dbg: \
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)/ape/ape.o \
o/$(MODE)/cosmopolitan.a
@ACTION=CXX $(COMPILE) $(CXX) \
@$(COMPILE) -ACXX $(CXX) \
-o $@ \
-Os \
-static \
@ -70,7 +70,7 @@ o/$(MODE)/test/libc/release/smokeansi.com.dbg: \
o/$(MODE)/libc/crt/crt.o \
o/$(MODE)/ape/ape.o \
o/$(MODE)/cosmopolitan.a
@ACTION=ANSI $(COMPILE) $(CC) \
@$(COMPILE) -AANSI $(CC) \
-o $@ \
-Os \
-ansi \
@ -95,19 +95,19 @@ o/$(MODE)/test/libc/release/clang.ok: \
o/$(MODE)/libc/crt/crt.o \
o/$(MODE)/ape/ape.o \
o/$(MODE)/cosmopolitan.a
@$<
@$(COMPILE) -ASHTEST -T$< $<
o/$(MODE)/test/libc/release/metal.ok: \
test/libc/release/metal.sh \
o/$(MODE)/examples/hello.com \
o/$(MODE)/tool/build/blinkenlights.com.dbg
@$<
@$(COMPILE) -ASHTEST -T$< $<
o/$(MODE)/test/libc/release/emulate.ok: \
test/libc/release/emulate.sh \
o/$(MODE)/examples/hello.com \
o/$(MODE)/tool/build/blinkenlights.com.dbg
@$<
@$(COMPILE) -ASHTEST -T$< $<
.PHONY: o/$(MODE)/test/libc/release
o/$(MODE)/test/libc/release: \

View File

@ -122,9 +122,9 @@ o/$(MODE)/third_party/chibicc/chibicc.chibicc.o: \
CHIBICC_FLAGS += $(THIRD_PARTY_CHIBICC_DEFINES)
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
@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_SRCS = $(foreach x,$(THIRD_PARTY_CHIBICC_ARTIFACTS),$($(x)_SRCS))

View File

@ -68,9 +68,7 @@ o/$(MODE)/tool/build/build.pkg: \
o/$(MODE)/%.ctest.ok: \
%.ctest \
$(TOOL_BUILD_CALCULATOR)
@TARGET=$@ ACTION=MKWIDES build/do \
$(TOOL_BUILD_CALCULATOR) $< && \
touch $@
@$(COMPILE) -AMKWIDES -tT$@ $(TOOL_BUILD_CALCULATOR) $<
o/$(MODE)/tool/build/%.com.dbg: \
$(TOOL_BUILD_DEPS) \

View File

@ -18,30 +18,54 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/safemacros.h"
#include "libc/calls/calls.h"
#include "libc/calls/copyfile.h"
#include "libc/calls/sigbits.h"
#include "libc/calls/struct/sigset.h"
#include "libc/errno.h"
#include "libc/fmt/conv.h"
#include "libc/log/color.internal.h"
#include "libc/log/log.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/sig.h"
#include "libc/x/x.h"
#include "third_party/getopt/getopt.h"
#define MANUAL \
"\
SYNOPSIS\n\
\n\
compile.com [FLAGS] COMMAND [ARGS...]\n\
\n\
OVERVIEW\n\
\n\
GNU/LLVM Compiler Collection Frontend Frontend\n\
Compiler Collection Frontend Frontend\n\
\n\
DESCRIPTION\n\
\n\
This launches gcc or clang after scrubbing flags.\n\
This is a generic command wrapper, e.g.\n\
\n\
EXAMPLE\n\
compile.com gcc -o program program.c\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"
struct Flags {
@ -65,13 +89,22 @@ bool wantnopg;
bool wantpg;
bool wantrecord;
bool wantubsan;
bool touchtarget;
char *cc;
char *cmd;
char *cachedcmd;
char *originalcmd;
char *colorflag;
char *outdir;
char *outpath;
char *action;
char *target;
char ccpath[PATH_MAX];
int ccversion;
int columns;
sigset_t mask;
sigset_t savemask;
struct Flags flags;
struct Command command;
@ -129,6 +162,17 @@ const char *const kGccOnlyFlags[] = {
"-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) {
int m, l, r, x;
l = 0;
@ -174,40 +218,75 @@ void AddFlag(char *s) {
command.n += n;
}
} else {
command.p = realloc(command.p, command.n + 1);
command.p[command.n] = '\n';
command.n += 1;
command.p = realloc(command.p, command.n + 2);
command.p[command.n++] = '\r';
command.p[command.n++] = '\n';
}
}
int main(int argc, char *argv[]) {
int i, ws, pid;
sigset_t mask, savemask;
int Launch(void) {
int ws, pid;
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);
exit(1);
}
if (argc == 2 && !strcmp(argv[1], "--do-nothing")) {
exit(0);
}
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);
cmd = argv[optind];
if (!strchr(cmd, '/')) {
if (!(cmd = commandv(cmd, ccpath))) exit(127);
}
ccversion = atoi(firstnonnull(emptytonull(getenv("CCVERSION")), "4"));
isgcc = !!strstr(basename(cc), "gcc");
isclang = !!strstr(basename(cc), "clang");
isgcc = !!strstr(basename(cmd), "gcc");
isclang = !!strstr(basename(cmd), "clang");
iscc = isgcc | isclang;
for (i = 1; i < argc; ++i) {
/*
* ingest flag arguments
*/
for (i = optind; i < argc; ++i) {
if (argv[i][0] != '-') {
AddFlag(argv[i]);
continue;
@ -297,7 +376,13 @@ int main(int argc, char *argv[]) {
AddFlag(argv[i]);
}
}
if (!outpath) {
outpath = target;
}
/*
* append special flags
*/
if (iscc) {
if (isclang) {
/* AddFlag("-fno-integrated-as"); */
@ -337,8 +422,14 @@ int main(int argc, char *argv[]) {
}
}
/*
* terminate argument list passed to subprocess
*/
AddFlag(NULL);
/*
* ensure output directory exists
*/
if (outpath) {
outdir = xdirname(outpath);
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);
sigprocmask(SIG_BLOCK, &mask, &savemask);
if ((pid = vfork()) == -1) exit(errno);
if (!pid) {
sigprocmask(SIG_SETMASK, &savemask, NULL);
execv(cc, flags.p);
_exit(127);
}
while (waitpid(pid, &ws, 0) == -1) {
if (errno != EINTR) exit(errno);
ws = Launch();
/*
* if execve() failed unzip gcc and try again
*/
if (WIFEXITED(ws) && WEXITSTATUS(ws) == 127 &&
startswith(cmd, "o/third_party/gcc") &&
fileexists("third_party/gcc/unbundle.sh")) {
system("third_party/gcc/unbundle.sh");
ws = Launch();
}
if (WIFEXITED(ws)) {
return WEXITSTATUS(ws);
} else {
return 128 + WTERMSIG(ws);
/*
* cleanup temporary copy of ape executable
*/
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;
}