From b740cca64291c7d31b2d188d677eb0bd7611813b Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Fri, 19 Feb 2021 22:20:38 -0800 Subject: [PATCH] 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 --- Makefile | 8 +- ape/ape.S | 2 +- ape/ape.mk | 2 +- build/archive | 53 ------ build/assemble | 49 ------ build/bootstrap/compile.com | Bin 53248 -> 65536 bytes build/compile | 298 --------------------------------- build/definitions.mk | 14 +- build/do | 55 ------ build/getccname | 46 ----- build/getcompile | 2 +- build/getlogfmt | 29 ---- build/hello | 20 +++ build/link | 65 ------- build/mkdeps | 22 --- build/objdump | 22 --- build/online.mk | 9 +- build/package | 33 ---- build/rules.mk | 128 +++++++------- build/runcom | 11 -- build/zipobj | 51 ------ examples/examples.mk | 4 - examples/touch.c | 29 ++++ libc/calls/internal.h | 1 + libc/calls/sys_utimes_nt.c | 33 ++++ libc/calls/touch.c | 13 +- libc/calls/utime.c | 15 +- libc/calls/utimensat-nt.c | 2 +- libc/calls/utimensat-sysv.c | 23 ++- libc/calls/utimensat.c | 3 +- libc/calls/utimes.c | 20 ++- libc/nt/nt.mk | 2 - libc/unicode/unicode.mk | 18 +- test/libc/release/emulate.sh | 1 - test/libc/release/metal.sh | 1 - test/libc/release/test.mk | 18 +- third_party/chibicc/chibicc.mk | 4 +- tool/build/build.mk | 4 +- tool/build/compile.c | 246 ++++++++++++++++++++++----- 39 files changed, 440 insertions(+), 916 deletions(-) delete mode 100755 build/archive delete mode 100755 build/assemble delete mode 100755 build/compile delete mode 100755 build/do delete mode 100755 build/getccname delete mode 100755 build/getlogfmt create mode 100755 build/hello delete mode 100755 build/link delete mode 100755 build/mkdeps delete mode 100755 build/objdump delete mode 100755 build/package delete mode 100755 build/runcom delete mode 100755 build/zipobj create mode 100644 examples/touch.c create mode 100644 libc/calls/sys_utimes_nt.c 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 36c8290085c29a3a1c07811169c479d67d26fd0f..ff0c7a674cdb1f74015744d82ee077fdc3334b79 100755 GIT binary patch delta 26709 zcmc(|dt6ji_dkB-z>&K%Dkxr%K|#U1fQpHT&LD$lY)};Nnx-Nuia;=@?Q z*2%KVQ|6OpR%V)oH!h-F)Dkt#N6qk(9vpkpEF>-G`(9@bWZ9JZWo$8=yArsK|V z?yyEvvh#YoH#LtiMrJp|Xqeku%bVI68NRH_>Q&3Ii|} zfqvRjou{Zl((YmSO@pVREmiRtokr^9m)2n&n53U|eg;n}J?R%NZSaeg8vUZ#Z)2pp ze$g6M>g}Jz87?x+NXe+l2U>HMTd83a{t@XW>AHV-kPd7BNrBvyItTo# z1C<{BxhWkE7_DiN`~ydKc)%JlkDr^;^uW=<51<|((F;VM-KF}#2!BY+^P`b&2M*A6 zt~zQ>I#TjZTe>qg=m;wfY9Fjw_p)wUPc)5dspQat7k-e}yWMWS?f}EE3}07^-j?a! zW2=6Z!a9VtL#Ml|Zb^m?-Pw{~rI{VNCa!1?nFrKzGk;|mU)P&ipis%6`-=3-21XnA z(aRq#(o7Y&>|Pp1;HKes9rq}HHw`f|(uNLCbm5B(4F6F%KUYcaE~jMA;wq_q$DUrt zA~e#Vj>8^*^#a4lzi1g|kzqP7a<5VG2P*2P?deo)U|P6UKSG%D3Y`Zg9UzzkFulAG zu-zZV8JIAd5H-W{?A&3VT`y;(G&FKKVb;j`|7SC;{r#8xQT_(hK_@~-&&3ZVTK zjb5a$s3wH)MG1>^6)OlDylBWGL&XTn`YoEa$hX4(2S{dit$~@!e>9cX)bk%rsceOw z?oIbKN)tP!+V=%A%&aHM_1%o%Dho-XAJ0@S$}EJt@WRfT@s! zaF`d;V|jsF)K0@pnJjMzAQBBVBxBxz)+<03$_=f2Sv8P*w$$*MMU7BjmNeNXLWw*#7_~xRe)xWpLaB zd84~l&Kk}z+R`4VZw@A;P?gSC9-P2h zZW|<_X?9~mDmtl^+aFZEtW;j2${uQ^^q_LNQhA6fqtwc!?_)|ZYS5jg)NY~L!D{Wa z2Tc={N|7p))yk0%D)mZbK2=UvE5jdDdZChOo=BAiY9;Hb98r?g{4<08t-+OcRLMUK zgM6IGHTML%B8YCtRBocmdaC@8Dm6sQfgH*7%gqY^`jVu#f2Nr!Yl2cLGleM*v+C=KkTU!vNPpo7$aF+f8`TZkW=pv_xrk z^rq6RSZNllG+RK;uBpvJJiP{zZCb?OBni0^WfB)zGiZ$s0HF>0+tLARw=Oi%$u9zcA> zbOP8R#5o>FWW_8MWxR)?tz$*L3ZdDiK0-^9hEpHf(r5A8k@WRX82_rLTm==&RLo!x zdwwtlS0NnN%nDJhxx0xNw{@sks{;N2D#mZ~p*1wj)t{2S6(6d#M-_By=gNHmn4Q*0 zHm*wk18WFN-{nP zgjPaLTGDAL=RO!~bCYL#=FF`DHTLV*Ey`C_BMx zQyTfQ78_SFiMFQKK^~Lu4GYT)wU~c-(-z7eXx<9Zm7dd`kg@A zJfL?xpg#!orU˷odnKx;gpr#v9HKgMKJKq2#yDEp}V^-~OdnN!yp##?JIqaj$t zs59WNqQiF{aqW1UB&{u7OT+r?YZ|>pxGHmyHH}T+HUV3{Qb1T%9T6luE%*X z>;T%5}7zkG3(4nDiBfu%`s&3I#Y6KzZh1n*A+y+eqyf2OX_;+fY#Y9b>Pk z0eSfkWn|Xy%2QP8T>$%!A$0H*!!f~fm_ooPoHshI*s-j)qb*|{3o4%?M~XQ}`$b)f zUz4q`>;R*R8j?;-!@|N)1i})NUO*yyLm6BlD6ODU{8DTyWmmLiUw|TL7=?o+_G@mN zsU&G0>R}|Jq0zwZLL|zt5r>k7hd?SF!t(!U^c)Cduu07OK=0@tNRyL_Uz5~3rKG31Pv}&T# zzeTuZoTBuoJw`nm9XCqk*J-pu?Nna4GhL3yUZyB87M`plr_GsjCPiqPVSL;;(>Tlc z#LODVuIwJ<0dX){n7a>90D&LKu{A4>tt}$%1P&%IPB!2q!j;~`{BI!t+4n`x3S>ED z7O@vK8+oX8E)uiz@kp5Wdv0rI-Why`cOT&$E6(^bHkU={7gyyJkpMYud(=-*@!;zLk!h3&>%F?(>BWGdF6zshy^C6_$``-3g%sBlId1cu;98iN*$ zZ89iLZvq>2+-L&epo(mN%IXwooC5X6!K0}aHT{(0MilFP>$pgiIH1;Xo9=sZSe~xC z4C8V2h2PD>uV&%2St}fqpT6aGm-Cl#+DN}F*}I27e&n{>{hG`}6qrkk@E?otvqkvL z(-Lz0m5v5-7It7d545)kKMAHA@|);QG~K{4DAYJ}rUyAQW3M3=#}Mb3P+l0L6S?%O z(pTLRSW~0q+asyHqT`DpnJkez{KL+ddo0jMrXHiceh*vC-aRkbdxqG{L78Te z8~{#!{d}ccKJqR)*0h!1dr*E`sek1``BkM{`nR(6L3yoGKkq^L zIi*~X`2es=0i--AFICDz|5lECP|jECga20cR?A1T;#&5UsAF>+Ea9CiOXS42rFX-F z10TtTvOkA9x$nDDb@;mQAr=GU+PwSO$B?{jab`yP@{TK2#`6Ba+5Pi3QlY;05c?6x z3CB>JG)iBASRJj8EcLH^hNxsjQPmASP_epB>}7fx8Fxtgqf)Kj96|+N+|S^YE)T~q zOG5nc-=)Zi$JpMH(vuOLH4~&Y5u@!jhZXV$v%8je)Py#t0Cf+;B;&ZjfWT^)0x0$T z`|yTTVz2i`3vs_M5q2UEYyiqmSUV}afJHEo*PxKqS5T36?$;6auh=taea|pX_bl(3 zW+}B-Br7bC@_L1j?DQ5{`M9dGbK0`USZoswdp4djpvA88KhV8%|8^vDZ*)nrhy;ek zx%mQM75Bf9>U#BJC#{rRy}F0SuLM&I(Jv|S1*|y9SHs8^Z%93Rr*<2ra3A6ms9{WT z4KVFd=NKm4SibR;w5oU5glBPfhO}ed=wTpu$3T@{zmHJz^~AwR%~e&A=3T|r`QOO8p?-4z5o^(I5dvH5Qd3PTYHP)jN`}m+v8W1&bE)xY97AWg(tmTfM zhi|cmc+cTQ@2J_xh$Xa{IqrIC%dVif7cnQTqt#ElmUcd(1h3&pErKmA)7&SqH7)v8 zNe?di1u6Ek=WC_yQ6Y9CI8$_|`47^a2DIRvS&bH<*&X7If~e$IAJ$^Z-64CZ8ViD2 zScHp4_h~9QT3Ks1rAy)8e}c4SZ-7Cwa9;k7G?>`DmA%7fH zxE&6BQ(P7Bgz7!L&@97)BXDoEq!9*1oOXZ>UN}R;spEtehVcO+UoGndt^g%RRR_d) zkP$fsbK$6G1#U5l2%KRbFd^p-Id)L`y-&F2yws!bAolHpQd-~M+LydN9VqflIVjot zcGI_n8_<>M4E$*LW+78BdCSlnUwt{Uc`HOEebl!%`$>(|*f*NR(zx4qBC7+n=&5XN zjr2iuB->geeHCq>I&Dl+sJ4c>IA|chy94>=?RvmIop?=}7qf`<`G?dPvyhSz{a#_8 z6n8fEdtbvoAxO*n&#?!_8<^%p-DqpamY!wIGz-6A5irpI4B;fd`bH}>PQHeTa97!U z9rfx+D~J_ODnBUaEBzW1*S=!2D)~&f*{w_TDeD8#dgVsphQDlh!jo< zC&xG5R`#PcfIv}j-y8|ai?8W_^y{rm8#Tw0^EyaY_hK_SwY1I<2*?;`)|KO~<)1N#m{ zzBrm+TocNBaWN=3hBMYqqQRRl<8~Z}6nt>Hd2_Dx_@Gf8c6S1A;{J3f5xSPwg-9O_ z(zCif(pQ7J+4E2-?zf;$ZX`TxY*5dK99Ko75q5Rl(3QEDr|{WsJ~1g3>RUXVU;KS2 zHVz{SyylE!xW*R6i_3kX`-)E)*8=+|^K~W})ZOw+!OGP6xn|3WH(=6dp=moi+T#2c z*MQTMxFXb7&I1-sA28S5P=Boz=aRT9o~i_efKj{tAZors4KLc{KU)q)bzBurF*Z(K zh~we(X&42(JvyiTkU`6cj3<^N6kfiXLpITE9g$01?x!mGnU2(T715}&O_aw%96}8a z#EIPN$Dj(sDjxT&4+Z&+=cL)O!CgK;8=~{g7M-=77-j^b5azxoiLp5W`=PtMkX0|A zcwy(g*clqOs9Bmi*xv2VT&Tgdw6Yc}jLcQVgZ-Y2`}cFDTZ4aKf4(N286vSyJ|`_1 z8p9?8NgIa7#or24gcl@BP+!PLIo^BhZRqEa1nfdZd%DALt}mw*ibJ0qDBU00jdcb} z-Qq{GBLbzV@e%fO4LHn|jmLbrydYR?@xYcpm_bTF4du6xg%aGv>4m%-)mxro7QQu3 zHVgOZu<{i};T<>lG&%>qPcm_=!lA>Dchu_4?qjZN7Uz85xO1ks6KSG%B=59shw@v5 ztaTQ_ZrUK{z(SkF%*a-=INsOdO#65;4s{#SJ%cITsSG9-^RE|8A6vw%b-boVu|ZyD z%^|bnpw66_5_z+@y(?Hw4kF<%vHH8h%t)3d(^f#r2M>}=aRnyxfueEpW8jWoeUNCXA~y@I&{>iQ zZx@pusYgAuWe_j6gR|$%YT^Y`6Q7&vE29bWGB2j;klq9=RE4#=ylH7zaK3#NQ>5Ob zVB*wukbPDe$W2-di)MM0cphICR$B+-k!sur50cr7N<^X5XTsK z7@N-MK57jRzSo?S^MK)M6u5VO0X+yMq^;>Ke?@x_$#b7mhDyD97AJ;DCtz@;?00m% zb5dapx{R%NCi;iAlOG#^HtBGtk*FKkB6Yu0wlH+1>{~O@742JxXveYz$+yZ#)(4x9 zq8VRy&e|WBH-RM3gfYI>a6WNNsI@CE7W-PVAtczL=A)FD@S{VLKpxP*VPn!SUBt?Nn$JGV_YQj*4q{!|$IwVG2$h5ru2@s& zu14@cN*sq_C$Xrsb#3-X0`HLY{6T#Oe`)iuaP0@%&|L9MAn?l$>Ey7{zFkYmksGp2 z>h@@V%MwBmch#dSa1Yd2xv!4`sshODT&a`0pgb=7t^JJvz`Q$tR2*J@@j2`;v@c9o z@VUi5N-sZJ)^h`xF^j=H%;JRqG9l61r1;^MfpqS{;%>wEbCFknqHr7g&SPc>| zq0n%tVz{0SoF+95??38IU_H=GYp6wNAuD|mdJdU@n4AU#m#^Ff%~1peSvA7OSu<;- zm=XQ#a4gl8qI#7WqdaFS;a4HJ;x^Jk!S0XpzlAeK;X7mXMc*iRc-l1KhH>>p)Z8@s zRYSfj4ghI&Lx~=}N641mQP}`MJE3SPsJ5ZB2NI`BEF_JoE23UacGidxv8z9hfLTDW zL|o?`ch$Q4sNx8<>j}ptAD6GO9K7K;pT7FC7QOEFoPm`!x`+`j$hmOmr%zKBX{6i> zBd4f%h@&;#rn8g{XsIR_Mt<`<<>+_Ot_W1ND{jf3Thbkv4%(88nXt>WC56gkc^W(x zKZF6tRa-g%Y?!kTf#u81ptAT3!ab&X2(~vj7oA{pcOcQ0p^~W}Z_^@R6=qe*#Y<5u zW>vx6E>nz$lnn)O2>PJU6HZgy&!jGFZAwa z5$>l5m(U|5QYF6wTsTx!ypT#=SpSI@JCqiXAo^KZ?~Y9ovb`Zp>$6bKwzwb#H{m1x z#>0{;K0B{m&=z!zD&TTzX4AZ@DyISBn7iaHcK~?I zmLC$*n!mMtYqO*^bd3@I3;TJ(PW>D9)0?G zem_A)K;x>K$8)4INiF-p$KF#o@i!T;vz#pcv0_5ixf0CyF70M%e(^B+qXX1hi)b!7Onup*w=gHbvQHOd-;i*ye|&LEf& zpF&CXRWErG_G(zUp;RtAhmc@5%Gm|(5e4z_##W2SX_42KzKr40?Uw@=G&tdtZ#ju~ zT4Oa9Y)AnfI^XRkoC^raoI|eGTc-yf^#l|{8YpqDV1a*0&MYDr_X%KTXNos?a~$Xf zjYAfk;4+aLtw7TO4H-&VF(h88Wc?rbmCA--mlwf~i%I9NcwF3RLJhXKL1NPAa@w6L z=!#B$H<>6Ttsp^(@qeI3UO5svhHZzDS+pmo$94k}8wy>A`3;2^_W~$l_jv6~Bto6_ zynK8hI`Z5y%ux5J$woRpAeLc7ECZe`jFHZf6p5CM&A*NdMFxuPrpz_Ob zpB=vqutk(S%`&!Zca^|>h+169(ES0uN`pt&JOVtFHP})r1}HszkLm?#wcN5;@%rEw zXiGZ+ua29IDng{#i6Z~e0B9?4+c6FqF(?JU5fqI<;`nWZ-5Mf%4P6t`&dVQxmY8;) ze2h`Xl2MGUotx`UXi1^?%~-=r5=YRfKjgwLEXQ@<7-&+aH$ePV^7}CIyGH}7*@<5z z%QYhqsITMd$;RPFA-B}EfKn@hKk++J;Yt%Z`(9*d+ypQt99*U2H<-ngLy#o5j&S;c z$}`B2FsT0ljwBI9#`-cCnM{mq1tZPHI57irqKfI}vZ*n*djwFY3-uIgpqsun--H~K z7II87D2ioFmq$aN=s@xWIVaiNB(#R|JP-P|2`~VTBW}3~q!15)GMTXmIzd=C1P7%E zh^e{d_tC$A3sSe7*G`%_CX_vwC@mZFsr}iB9vd&e$AKaw%gJ*Z-EM`CpLyXvECwkZ zOm3_EIZ&XyoIDyByl84|fYH@nM7OrbOOiMxW67#KPJ+kF$TbO|=y`k=QgIqU`9Lo5 zga=}0!KV+Y2^h1 zIJSDB6A%4t(4UD8Ua3+dfjDP3G7KaAb4+UBdb<3nE2G~!>8CNhxxOs6L}^`0_pWPp z&})G*+F-@_w@|1&N6d~IA{|VLwa-Wb0JyLr2qido%?1TI4bxWXi=PoZ#t3b};|6qB}sJVGoKN<%XRH3+Ekz8H!XLHwzTsaWTE&2Tk=ndPw^RZ4I2 zX^dM;$_EkU7)4~{uR)kLs4}qQu{a}edZd_AAN4dg5@@hJ6Aa4qb%XkpUjQ44+@a5; z2ly;+(0 zI@vZK-v7C8q^wlEy%Ob84M*fVSP zlyrmaL>5BKlJtH5dkBqZ3bFJfNQ)F^tJ0qMf2cHHnqSSB%5Up$c)Cx<$D zjWAxfrUxsg>Jw6R)_&SA+KptbevW(ow&0N(8;t+hSXvK0?ndgsOZx?G-0cT_Ax^}1 zsLFP=Zmf5}N;t;Z`AT&Nyn5;9b8L2VgEk{lBLXywd?q+I= zr$b)Ii(`GU(8kx|JW#TAjEe9QsfIn+mfWg*OP4C-)q z3eMxVgH&@a_;W|y`T+VJbq~MWG(fl~M~sIZv^ZzO)wm{qLSu%6+LKulE|B+OS}0vk zoy2}KMS65>LZ{cKC_;%=&x!7+s1GE^*hksC>Ye+>uGg?<`|ivzCu`VWdP}d3dxve> zFAaap*!klqw1Q#mVis3od0en)?#ORPNiRP3D%&nT(a3pg%ZsY11cr}6J892h4coq{ypKm>%aiAb7b zeaVvaLzaTDMX>Bb>zy+Zt=fH62nC3Nhn9zdRndq?x{_(q)*vd{V#f)=KSqPO-zW8E zANfLx$goBo#}=e;H4a&eoq0@B80rKOS+KJ zjh(bhx|@;i1-epN<|ZZmIdcdb^SRVFOZ>CD@2I=VtlsRxozj)8r+dn{IN;zyvJ8SleglX!6`!K8>OCG9_f zjpGx}7R`f6*!`LG>69LJ2Z0>N$T3_;S>b7jpndafYysH6=Kw@MyyLJJii_Hcbg%6g z@2hDx5T3}HsA&TWbOoPVof&n^e(D9Bc#RB|f#zT!l8?y1}Ye2eB%^CW7L82>Jc#gIn)24u!LNA@Y-&=VXd{H85i1TR2L zYW+-VnjRihNwe;xP|fKQZ0~m@UTQ z#U1vbokE|tE0sS6L(8Uiu_oLoH>pC>LbZMbC9wqu!z4>7Ddw9kBGZ*SQO*Lkpz>z znz?T>iQJrUK#_l%Hu<=G4fk(a9T$c{nCp^#hhXZ=&SafY+aXz})dhtBj{G=11oWH2 zebikfbsU2VWy%Ha)+f^UvnF&8-3ng4{Z3wmY8R=*=w9oc=@cQ;EPWshNJBjA!fw0p13{~r?c z+boTqm&3pR9){vHKW1^NlYE@78yii0l7iHY)l)X5tk%{g#jjR~Uj}sO)K@g;7Ga8_ z2}7wQ-I!+$=!sfe&~zGwv^ZxaJL2P=*K^`DUR3V6U?|(TRmxm2SSbn%MzV9pN_7in zu)l1SA{UNgYkYUkTR6fibm6-gFs?py5Y$xUWh|Y&_$7U@_z}M-09-!ui1(%Ii^sC3 zHcCVCvh1s;8pycNdmD=|pl~BlUZy*64smYRD^u0YS=r>3(CzOT>E%DK^tADgbGsYM z>1!(Ee)?@rI8+?KJEyj~Ptw&Mt|hO@hf~{Jgo!PjZVkMDTezGM2@wegTR6A8? z?MyyY_Y~(`HzM;Q2&X8t<7yLvWf0_W z+_cieS6e5uIEnI{|u_aad0~P(i$;n^z+iaylnO?F3Xq1 zusb(N;*v17zD(M>gzvMbo?_bdNp4Jr{aPhG9W^^kBi-m4i@9VYB#54+(EQ2lsCua| zzcbsXURsmihrRHwv^~EYySY?4nm?M2FOz}_(sjh790L}W6Yk^5(vpI{tna(hs|7La z%8gQWLBwFEgH#0$K8_&b%GQSFFg=A;d1vOMZob;B+dcSs1A`-T^>xpfn}3#q3nP+7 zP%~>748L;7(5lyKufT4@3G{9La*NxoC{em4yUI9GeiM^##LdQGw{d!d^nG!nR9qOv z{+cAcQ8<8oair8x81MZkHYQy08@z907m-q*DGu^Zu=BqE^Dwr4cL=U9he@85mwp(VLzcTjf2`+N2o25P0sU2so zBF?+wGe6}Sh5XuJDbf~^`Pgts5o=lx4;IgjQ!N^o^3;D1%Ge7o(^;*rit{^|15Pi% zDsJEus^G|ep4zstHJ|pDUbpp{T1lsQ9GQINFWg-!&)!%xb-hgM((;$r;#oNQ zL$=D@xaTpMaNl#~hX=Y)yZF=<@LNKLg9F^($W@_a{0`CW-|y&}$8!TH7~K&)LEpF1 zld~i4=5J6XIz!1PvWp=>}`$H>dJU@fRVSr%4>Bv?}Jn4`X;oDJEx5)ql`Ajc@v4;0p}mu3qrdv zj9(2AZm;BU=ZPo;2`NSJJTRl6TnqQp(==CH^JX+|{$jHol*N!>IK9ope+$>B)_Bo39YI^nK~tvXN{*PKsI{ zZoj?!!6Z~7OOrGlTs1#~NpK|nvY8kgj+bXc`Rs2&#CsEbc|3eOKu;Xp@4`<70(ug; zODH7NtqjDAE$wF^-=Jh`uA!GSV$zEs3~w5bVT8NtglDLIJwB2;+w-Yv!|@iyxF5R3 zAOeMtEnWl_bM|?h_MFI>gsa7UV3)CTr)6KUXg`Z802E_ed=lJ*6rqr!{j8s@)}Gh}jCm7;rar#<2;w9boS6?+?wV5_j>Pn_Hi>KSBEl_4NjS<0w0X%{U zz)Y`|?mwkxpL<@?KW$?N)Jm^CJ%EkqB-K8BcF;c{M4Vda%Dv0DY-JZfG|XpJJ0A0A zfVb`)N$c1*Rp_tm5XYX0Wp}(JX;$>^Uu|WWEx|Ueaq4bGOpniOuIK=e4vZkSq_5O~ zGzBi@4?0NcE5hu`)`)QUX}XWmrwD1X7`7dfg5%Q&-wMZTTa&QzhC53quDrpEwk8TQ z!N)oSkEbz3Op|SWpiQgL0<(Vvz1unqVI+6bYCHp-fd$^Yubrn%1$74{6^18 zYwhdQcctkInfIW``B2*F(;EJQwCPWro11_$PQ_8emiNV^3&qOj_$nNgw$Zf2wRm2^ z;mo@7j2QO)MreNq3ogW!czA&qOJoDM`i6l_Cqx%3_e0H))r0^*-URtWom z8tMX&ts^t5rM-amG7M@2CWDHe5G0KZ0evxPB5`v zDCW~P*OL8{C1JoB(6CL$Rna6N?B+Y*qJ=bQm>IA9b}P@$ob-Iagf}-S_y**4{tg}m z*iH3R#F^TJtE&`50zGhgw0%c@2j&(pf`h;nMjG3;iPw}hSlh|%U;O)%;6Ja?5Dq}$>76O%)&Y4kz|Z@FdxY)-gu?PUkfbOonXTlyaLBjUmV?;UnMf;^mW zm#;QDZM!xmtqM&;EeUsQ(c0)N0J0igiS#&h<#t&MRi`u1zqHXN)R?O9uhA6-(r$=^ zPpG4Q$0%czXL{(K!IIqiB*QE=XCI`)Pd5sSw#PMM6?qmPLh7z?dF@&(_E6Lyq=_0b z8t*_BkVr6U{vweUZYZeHR4+l>=1$5M6`_I_5h(5>>7^Be!#;6BYKW5<-vDRXb$mj7 z@lXq1gds#R>2)ZC4<7PZIUHQ@!YTU% zeHGCB!pG9+mEG8D|Bz;^9K`NvGWS#Maib>QD&hHR}0We3-Vlj;y%}WykP#HXl%c5C*ky2bK_z z{v?-jEIyZ+&`0x&-Na~TpcA7$wm_vpiXdHb=_2!1KF<0o{I&>XwHXDptxmYBPAq?CL2g?v`upNjAEtlILna00>ycPOH86C3Y<##dm9{16SVM8?&( z4M|%%owyZ#ayK@oBPVCBQM4fp3B9TN)0%od%aoiYojcah=8+x3ZvZP*uzZfi(yo$G zX(uCTnS6}1)NE@E^n-yVtSmoefO~C?gq^;6Q$B=u?Bwxt<#gr93tlcCzRrvC7NHn7 zV2L=S<3d4>ZYLR559~}76eEwd(dOvgep@PCJ!@J`E@?WBB{<_idndpt1hZ`y87S9KDQ7C}}3FS-YBS3ckvk5<{b?3QeQ`!$7RLCol|7RWorO&@;UlRuBAorJS}d zknP#9F3=rSu9WTWO5aO?X@%X~QCk#1UxOxD6Kv49qc$kz*#@6vpD}vWuTjeEXJKsk zsN?8hxl;B^4?GceC>;bBD&>H6-YTc~T)$#02Qj z!4?G}c%9G7K2NO!0~=7z+T)MOqloVhvIW_hHL@doXH;1ijr8ieo`ct}g<;m3uJPK6 zL<9ZNq;cLj)s?uTtX*J+jP7rgfDpbx911w^u5q2-d41gxja^%TXvS0xFqddccVZ>k z3y`0yEj@|e>_d=G^~9Hq+r7&#Vj~1(sFj!=m`9dQ*D0G_8U6{xuu z`D|@zFOY4%gkLDm*OqScw9U0HZ2oGJ2U?^pT|j;J21cRPfZtDQOQ!;2-0oH0=;^h< zYEk|M5h`ugIATYwSZ*aYi?yZw(4hGlX|~jBkW!bH-7qCZ`^5#E!hO;q1+2@7Dfq^A zq9yyVMYt=w;X%U+>ziYx{nEJZlYwu^#x35p$#}8~{Bt8Cl~X`-wKU+BK}i>DfcJTP2_xQ2L2t`4Zcp9R5W#+@@(Bm=?h_{t58l9gYMwnaih;7T6RReDD3 z#d>#@-VwWW@K>=^_J8ak)rmRYMS%>nGxi^+HN7@KXQ6{t&Aafi2i?3Vbek8zw=jOG zF;@6*m7>=svZDi~oVBZ2FQX){wX+L!Qtpd~24wNM?vhtGVDH9N#a`wm9kGVb58IyH z$jYCfz{41PkvK!@zpiiBBijwYwzXnMqmL190-cc;<4hpst?MU^eC`qU?MNy2x&CZB zKk2pSBzBUo)c^TJc3bbAxzCFlHiDB{)}*rk_LfEo5q9HblTfQX?1M*mhI$s(>#?-O znb^Uc(a7;)nUVyQ5j;iA(c`6*5_A=mh?%Vu{+@~B;!nnsD|(}FR9nVERq-MxMQDKc z18JPRS|$4+0CeZ{nz8_p5OxLPw+Y8?6XLeJJbmmZ;udFFEE4!)WDimVr#DLS6s&4b ztTshdAUHh`HaMlWuF*IhsEjHc3Jq~?aTjHKD?RbrPa64?*Gn!Mc&+IG{(bu=0XsD; z*-vaS)}BU(+shVe60RGaX&R#v`AM!V4Kbj$zpI_mU6&#>BRUnG;>^_;UKkqtSJ4>O zd>%xo+Ol5wO`jwFXcDeL2F8+WtZfng#*GG>rp{D)#TsBLZLxW83AEZ-_mLF%)SgFq zyyk97!V=xmVB_jPu(dPG0&3Ye;>XhP!x<5 zt?9bU7b9|c8R1cS*wemxU|9zs<4xyvRZPoW!A5t3tz+p4D?aIHgU-bm+JX z{}<_13TeFW)P7NQ=Zp(~whVqht)hodlWDj`X**4-F*eZ@Y7`D^(Od0!ly?bVtu#g& z)|l#SRJtv)CBKbc8tZ87yR1FFgTnh0i&wHvVDUg%Ovcw?2CdoAbkpp_+Y}+$*DQvn z;nvO-XhwX z$1M@JEfEN?oxznF!lgR5O^?k@W1KWmd2o5aIMF2hTb_VDf<9xFW(lLnuZ2&K;D=ej zr&G$;y!fDu4wDJr@?GnTLl8ODmR`qvn1$hHq0qM(?@W;S>Dky zns?k99dpa9-F(t~@)D$-rZt_#zvFRLaV>Et${LoNEcE%v_xM5pXC(+bp~ceGjk6;i z2CMJmj{c70nuhngi;N}Wf+gZxbIg5n*E?z2kI!n{4Tdi?=Ho6`k1q|SEo9S(r+_pe zHceRWOG+4bV%jXJ$NDtQX=%~=9wX)Uel+T8Y|=m=9p@@>5n-_LPLI# z-@-WXS{Yh#018NjWx(>k!>H-X!GaY)s}>Yq8o8i`&XA~ zmhOD+)kHS!Q=I-q+bGPYNr#2L5SjH%&zL7fmGar7>u{#-;H@^vwXcT#gxJKC%@a?|} zll;H^7k>wq)q4c4%t!Opt?l@j*1sGnQW)vQHzHVXN#l~GrnfuW=O*K*!in5C zCBgV*;ly48#F(0^nO=yM%V zGpmK`0N8R{Pc1h&Npq7zeH%ftG8$rmqIkQF+NW5zPYtTI&yp|O!d*1b6O#*f&fYl@ z(dasj>q7v%tsxXzl<{X0+%pBvKObVF2eoq3OsW2zp1y5|F6rhwLjpG=vg!HDP(K-@ zK^uS7F38T-N6llh^XB9)Kt}5OZso+}EVCtr={_TN34SHSCB`jbGNz56ke*@A@b}m2 zvkR6K=H}%LM5>>WYB7$@n5iE#AuY`~K1DynIB9Igz<~p2`uk6qY??ILY?^{5(%pAQ z_Q@^Q&(SZ)$Zik9YP=M;~ic6$8)y(z!gR-~d8*sO&%tA1W?QBJnC zpy(-m&hp%1YjGQ9_QC>%THYL6e)htgdHQ18+%}$~?Zp^gzE!`ZU|tR?3JVL0tU$?~ zub-S08>5m)o3jApn4gJLF=O;giwEk*D8ihdH)nx9H=m?6$C^7gH!s(k zo72WXR{qnug`NQ|&B>ovPz3ta+*(kOmu+7-CpVwE%eCqk&MD5vLy3hXrhFhhm1BLt zz+&pxnzID_&A|w>3kuNzF=9+NVZ1rnHtU?Zc>paNRG=@01PA2IpAT`gF_Bq>!GkwY z$t$2=x%oiO&A01&Wtt|XCC#%fncE8;6fMckpOaUN`o%f=oF#Lzi%H^tnIg;<{swnZ z&XSzGr}XpZ6k9QwifRz%0HfYGCeu7&JWW$^VNQ1Ld}6eCA>{f%6Y}RQp~)?RjP0@D zXTbvSMU6A{nNTWI=3g6I=M*i-vFaac^_NCg!d8E*1-9&kdbL48K4vry{71+ZN-qawE(J@3${q_{*)(az<|*YwFDBhWnoTUp}#*fdSSlRI3jbz z&c;orHPZg~CI{yi49K37Uyz@hJtuEKVNuTf+~qlvZu81=!W}B{kiorWJonzgEk#n%+}W|KpyH^=dj) zO{c2qLN#5jrY|cg0-^7zfE{Yupr&Wl^tPJ*uBP56JRNmX(-<{1sp%XweNs(VtEr%- z8`X3dr5O-atqM4$rZi2td3iYt=H%%M3az=&(g6eXQQ0)BBibNEIZxVP&R|CK_0WFX z60%VqH0jvZ2+ca_=GNIk4@cPylKrDmtTtSl@KI#ooOw&<6y^>YJaArKp7hg4Q32z# zEEXm@-8l_zIA^JV zqmwgI1`LVuA5&2HR8j7Ng;srB!th7?<9EUk<@Zon$sGNp9Bg}5#WIs6$;!`Nnp0Gq zYki7r^_V$%xiEYAxpNq)@RQMj`YFaqlZ@jt&87^0Y40b4wGRRG6H@)9-#;1LS#QkB z7mwww8uJM<;eyT@)#HV4>)KA^M7+NZ}!zoh6_9p^Ta`JMl zIiB*T+n?5ru@x0zXz4`-WKqrYq~4!>=mm=@Re!cNIOC~eY)+Xd8jGn3O+onB5dUnUOzb$7 zoLZ_d>VryoIXQ*Wk2@yxDY;0so}ZdiNN?gR=Z9dK-!e?>P5dt%I@`731}5}74{9GZ z9j>MpHJzoVDn(|wT7Fec-&51=YI;yjFR1AaHNC5*fppTrPqz!uefo)30VCCPvYIYb z)2G#Rt(v~4rWI;>Mos^trrzHxWSL%SnyjYjYC20zpZ?zNL3}|4Y*f=7YI;CT'o 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/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; }