diff --git a/Makefile b/Makefile index 5f160a36e..fd1083b72 100644 --- a/Makefile +++ b/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))) 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 \ diff --git a/ape/ape.S b/ape/ape.S index b60487c54..60fcd5e13 100644 --- a/ape/ape.S +++ b/ape/ape.S @@ -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 diff --git a/ape/ape.mk b/ape/ape.mk index fa044dd45..26fefdaef 100644 --- a/ape/ape.mk +++ b/ape/ape.mk @@ -20,8 +20,8 @@ APE = $(APE_DEPS) \ o/$(MODE)/ape/ape.lds APELINK = \ - ACTION=LINK.ape \ $(COMPILE) \ + -ALINK.ape \ $(LINK) \ $(LINKARGS) \ $(OUTPUT_OPTION) diff --git a/build/archive b/build/archive deleted file mode 100755 index 486dfbaad..000000000 --- a/build/archive +++ /dev/null @@ -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 diff --git a/build/assemble b/build/assemble deleted file mode 100755 index 39678be39..000000000 --- a/build/assemble +++ /dev/null @@ -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 diff --git a/build/bootstrap/compile.com b/build/bootstrap/compile.com index 36c829008..ff0c7a674 100755 Binary files a/build/bootstrap/compile.com and b/build/bootstrap/compile.com differ diff --git a/build/compile b/build/compile deleted file mode 100755 index 660cfb499..000000000 --- a/build/compile +++ /dev/null @@ -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 diff --git a/build/definitions.mk b/build/definitions.mk index 4635a93db..d84862133 100644 --- a/build/definitions.mk +++ b/build/definitions.mk @@ -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) diff --git a/build/do b/build/do deleted file mode 100755 index 932a17f03..000000000 --- a/build/do +++ /dev/null @@ -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 "$@" diff --git a/build/getccname b/build/getccname deleted file mode 100755 index 00640525d..000000000 --- a/build/getccname +++ /dev/null @@ -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 diff --git a/build/getcompile b/build/getcompile index 3d330924a..7fbee1812 100755 --- a/build/getcompile +++ b/build/getcompile @@ -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 diff --git a/build/getlogfmt b/build/getlogfmt deleted file mode 100755 index 10003eb65..000000000 --- a/build/getlogfmt +++ /dev/null @@ -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 diff --git a/build/hello b/build/hello new file mode 100755 index 000000000..b62ca7693 --- /dev/null +++ b/build/hello @@ -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 diff --git a/build/link b/build/link deleted file mode 100755 index 6f0fc503d..000000000 --- a/build/link +++ /dev/null @@ -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 diff --git a/build/mkdeps b/build/mkdeps deleted file mode 100755 index a4cbc0da2..000000000 --- a/build/mkdeps +++ /dev/null @@ -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 "$@" diff --git a/build/objdump b/build/objdump deleted file mode 100755 index c1443828e..000000000 --- a/build/objdump +++ /dev/null @@ -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 "$@" diff --git a/build/online.mk b/build/online.mk index 6e891771c..ce19ed8f9 100644 --- a/build/online.mk +++ b/build/online.mk @@ -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) diff --git a/build/package b/build/package deleted file mode 100755 index 63ca44aaa..000000000 --- a/build/package +++ /dev/null @@ -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 "$@" diff --git a/build/rules.mk b/build/rules.mk index 84ce0da5d..4941db97e 100644 --- a/build/rules.mk +++ b/build/rules.mk @@ -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) >$@ diff --git a/build/runcom b/build/runcom deleted file mode 100755 index a5013b964..000000000 --- a/build/runcom +++ /dev/null @@ -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 diff --git a/build/zipobj b/build/zipobj deleted file mode 100755 index 02a9097d9..000000000 --- a/build/zipobj +++ /dev/null @@ -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 "$@" diff --git a/examples/examples.mk b/examples/examples.mk index d5f06fe15..1374b63a4 100644 --- a/examples/examples.mk +++ b/examples/examples.mk @@ -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 \ diff --git a/examples/touch.c b/examples/touch.c new file mode 100644 index 000000000..0325bfc92 --- /dev/null +++ b/examples/touch.c @@ -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; +} diff --git a/libc/calls/internal.h b/libc/calls/internal.h index 50c4b6dcf..7c9334bea 100644 --- a/libc/calls/internal.h +++ b/libc/calls/internal.h @@ -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; diff --git a/libc/calls/sys_utimes_nt.c b/libc/calls/sys_utimes_nt.c new file mode 100644 index 000000000..8a7638a14 --- /dev/null +++ b/libc/calls/sys_utimes_nt.c @@ -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); + } +} diff --git a/libc/calls/touch.c b/libc/calls/touch.c index f3b32fc14..ba27bff31 100644 --- a/libc/calls/touch.c +++ b/libc/calls/touch.c @@ -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; } diff --git a/libc/calls/utime.c b/libc/calls/utime.c index 31ebb615a..b17f1a388 100644 --- a/libc/calls/utime.c +++ b/libc/calls/utime.c @@ -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); } } diff --git a/libc/calls/utimensat-nt.c b/libc/calls/utimensat-nt.c index 1ba55e415..0a5972cde 100644 --- a/libc/calls/utimensat-nt.c +++ b/libc/calls/utimensat-nt.c @@ -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]; diff --git a/libc/calls/utimensat-sysv.c b/libc/calls/utimensat-sysv.c index 7df8fbdeb..217961104 100644 --- a/libc/calls/utimensat-sysv.c +++ b/libc/calls/utimensat-sysv.c @@ -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); } diff --git a/libc/calls/utimensat.c b/libc/calls/utimensat.c index 2b33be08f..0ea5d6b4c 100644 --- a/libc/calls/utimensat.c +++ b/libc/calls/utimensat.c @@ -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_FDCWD∨flagsβ‰ 0 + * @asyncsignalsafe */ int utimensat(int dirfd, const char *path, const struct timespec ts[hasatleast 2], int flags) { diff --git a/libc/calls/utimes.c b/libc/calls/utimes.c index 0bab34e8b..7fe812540 100644 --- a/libc/calls/utimes.c +++ b/libc/calls/utimes.c @@ -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); } } diff --git a/libc/nt/nt.mk b/libc/nt/nt.mk index 52d963e32..759a5073f 100644 --- a/libc/nt/nt.mk +++ b/libc/nt/nt.mk @@ -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) \ diff --git a/libc/unicode/unicode.mk b/libc/unicode/unicode.mk index 9d146723d..b4779a900 100644 --- a/libc/unicode/unicode.mk +++ b/libc/unicode/unicode.mk @@ -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 $@ $< diff --git a/test/libc/release/emulate.sh b/test/libc/release/emulate.sh index 1ac38898b..b925b1a5a 100755 --- a/test/libc/release/emulate.sh +++ b/test/libc/release/emulate.sh @@ -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 diff --git a/test/libc/release/metal.sh b/test/libc/release/metal.sh index c3ce7509a..f4893355e 100755 --- a/test/libc/release/metal.sh +++ b/test/libc/release/metal.sh @@ -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 diff --git a/test/libc/release/test.mk b/test/libc/release/test.mk index 2b9198805..3760d47a5 100644 --- a/test/libc/release/test.mk +++ b/test/libc/release/test.mk @@ -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: \ diff --git a/third_party/chibicc/chibicc.mk b/third_party/chibicc/chibicc.mk index 1a7c68a1d..074863c57 100644 --- a/third_party/chibicc/chibicc.mk +++ b/third_party/chibicc/chibicc.mk @@ -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)) diff --git a/tool/build/build.mk b/tool/build/build.mk index 6210e701f..f9448be1b 100644 --- a/tool/build/build.mk +++ b/tool/build/build.mk @@ -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) \ diff --git a/tool/build/compile.c b/tool/build/compile.c index ae174a3f8..92bfb75c4 100644 --- a/tool/build/compile.c +++ b/tool/build/compile.c @@ -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; }