From 83a8686c06ddec119dc91342b4a9f7f8aa7c5cf5 Mon Sep 17 00:00:00 2001 From: Trung Nguyen <57174311+trungnt2910@users.noreply.github.com> Date: Tue, 23 Jan 2024 01:22:16 +0700 Subject: [PATCH] tool/cosmocc: Properly handle dependency output (#1091) a2753de contains some regressions, causing `fixupobj` to be inappropriately suppressed when `-MD` or `-MMD` is passed. This commit reverts most changes by a2753de, and: - Treats all invocations of the compiler with `-M` and `-MM` as with the `cpp` intent, since these flags imply `-E`. - Handle the dependency output path specified by `-MF`. + This is trivial for `cosmocross` since the script does not throw objects to and from temporary directories. + For `cosmocc`, the file names are calculated based on the `-MF` value provided by the user. If this flag is not specified, the script generates the file name based on the output file using GCC rules. Then, before calling the real compilers, an additional `-MF` flag is passed to override the dependency outputs with mangled file names. --- tool/cosmocc/bin/cosmocc | 79 +++++++++++++++++++++++++------------ tool/cosmocc/bin/cosmocross | 16 ++------ 2 files changed, 57 insertions(+), 38 deletions(-) diff --git a/tool/cosmocc/bin/cosmocc b/tool/cosmocc/bin/cosmocc index 49e0e9222..719d0b5d6 100755 --- a/tool/cosmocc/bin/cosmocc +++ b/tool/cosmocc/bin/cosmocc @@ -88,7 +88,9 @@ APELINKFLAGS= FLAGS_X86_64= FLAGS_AARCH64= INPUT_FILE_COUNT=0 -OUTPUT_IS_TEXT=0 +MDFLAG=0 +NEED_DEPENDENCY_OUTPUT= +DEPENDENCY_OUTPUT= for x; do if [ x"$x" != x"${x#* }" ]; then fatal_error "arguments containing spaces unsupported: $x" @@ -97,6 +99,10 @@ for x; do NEED_OUTPUT= OUTPUT=$x continue + elif [ -n "$NEED_DEPENDENCY_OUTPUT" ]; then + NEED_DEPENDENCY_OUTPUT= + DEPENDENCY_OUTPUT=$x + continue elif [ -n "$NEED_JOIN" ]; then x="${NEED_JOIN}${x}" NEED_JOIN= @@ -124,11 +130,19 @@ for x; do elif [ x"$x" != x"${x#-o}" ]; then # startswith(x, "-o") OUTPUT=${x#-o} continue + elif [ x"$x" = x"-MF" ]; then + NEED_DEPENDENCY_OUTPUT=1 + continue + elif [ x"$x" != x"${x#-MF}" ]; then # startswith(x, "-MF") + DEPENDENCY_OUTPUT=${x#-MF} + continue elif [ x"$x" != x"${x#-O}" ]; then # startswith(x, "-O") OPT=$x elif [ x"$x" = x"-c" ]; then INTENT=cc - elif [ x"$x" = x"-E" ]; then + elif [ x"$x" = x"-E" ] || + [ x"$x" = x"-M" ] || + [ x"$x" = x"-MM" ]; then INTENT=cpp elif [ x"$x" = x"-s" ]; then APELINKFLAGS="$APELINKFLAGS -s" @@ -205,12 +219,9 @@ for x; do elif [ x"$x" = x"--param" ]; then NEED_EQUAL=$x continue - elif [ x"$x" = x"-M" ] || - [ x"$x" = x"-MM" ] || - [ x"$x" = x"-MD" ] || - [ x"$x" = x"-MMD" ] || - [ x"$x" = x"-E" ]; then - OUTPUT_IS_TEXT=1 + elif [ x"$x" = x"-MD" ] || + [ x"$x" = x"-MMD" ]; then + MDFLAG=1 fi FLAGS="$FLAGS $x" ARGS="$ARGS $x" @@ -311,6 +322,21 @@ mangle_object_path() { mangled_path="${outdir}.$arch/$outbas" } +get_dependency_outputs() { + if [ $MDFLAG -eq 1 ]; then + if [ -n "$DEPENDENCY_OUTPUT" ]; then + DEPENDENCY_FLAGS_x86_64="-MF $DEPENDENCY_OUTPUT" + mangle_object_path "$DEPENDENCY_OUTPUT" aarch64 + DEPENDENCY_FLAGS_AARCH64="-MF $mangled_path" + else + base="$1.d" + DEPENDENCY_FLAGS_x86_64="-MF $base" + mangle_object_path "$base" aarch64 + DEPENDENCY_FLAGS_AARCH64="-MF $mangled_path" + fi + fi +} + mktemper() { "$BIN/mktemper" \ "$TMPDIR/fatcosmocc.XXXXXXXXXXXXX$1" @@ -328,19 +354,16 @@ build_object() { $CFLAGS_X86_64 \ $CPPFLAGS_X86_64 \ "$@" \ + $DEPENDENCY_FLAGS_x86_64 \ $FLAGS_X86_64 \ $PRECIOUS log_command "$@" "$@" || exit - if [ $OUTPUT_IS_TEXT -eq 0 ]; then - set -- \ - "$BIN/fixupobj" \ - "$OUTPUT_X86_64" - log_command "$@" - exec "$@" - else - exit - fi + set -- \ + "$BIN/fixupobj" \ + "$OUTPUT_X86_64" + log_command "$@" + exec "$@" ) & pid1=$! ( @@ -352,19 +375,16 @@ build_object() { $CFLAGS_AARCH64 \ $CPPFLAGS_AARCH64 \ "$@" \ + $DEPENDENCY_FLAGS_AARCH64 \ $FLAGS_AARCH64 \ $PRECIOUS log_command "$@" "$@" || exit - if [ $OUTPUT_IS_TEXT -eq 0 ]; then - set -- \ - "$BIN/fixupobj" \ - "$OUTPUT_AARCH64" - log_command "$@" - exec "$@" - else - exit - fi + set -- \ + "$BIN/fixupobj" \ + "$OUTPUT_AARCH64" + log_command "$@" + exec "$@" ) 2>"$out2" & pid2=$! if ! wait $pid1; then @@ -411,6 +431,7 @@ for x in $ARGS; do OUTPUT_X86_64=$OUTPUT mangle_object_path "$OUTPUT" aarch64 OUTPUT_AARCH64="$mangled_path" + get_dependency_outputs "$OUTPUT" build_object $FLAGS -c "$x" else # e.g. `cc -c dir/foo.c` builds foo.o @@ -418,6 +439,7 @@ for x in $ARGS; do OUTPUT_X86_64="${o%.*}.o" mangle_object_path "${o%.*}.o" aarch64 OUTPUT_AARCH64="$mangled_path" + get_dependency_outputs "${o%.*}" build_object $FLAGS -c "$x" fi else @@ -425,10 +447,15 @@ for x in $ARGS; do if [ -z "$OUTPUT" ]; then OUTPUT=a.out fi + if [ -z "$DEPENDENCY_OUTPUT" ]; then + o=${x##*/} + DEPENDENCY_OUTPUT="a-${o%.*}.d" + fi # e.g. `cc -o foo foo.c` should *not* build foo.o OUTPUT_X86_64=$(mktemper .o) || Exit OUTPUT_AARCH64=$(mktemper .o) || Exit TEMP_FILES="${TEMP_FILES} ${OUTPUT_X86_64} ${OUTPUT_AARCH64}" + get_dependency_outputs build_object $FLAGS -c "$x" LDARGS_X86_64="${LDARGS_X86_64} ${OUTPUT_X86_64}" LDARGS_AARCH64="${LDARGS_AARCH64} ${OUTPUT_AARCH64}" diff --git a/tool/cosmocc/bin/cosmocross b/tool/cosmocc/bin/cosmocross index 9d130c00b..e1f3afd04 100755 --- a/tool/cosmocc/bin/cosmocross +++ b/tool/cosmocc/bin/cosmocross @@ -100,7 +100,6 @@ INTENT=ld GOT_SOME=0 NEED_OUTPUT= RELOCATABLE=0 -OUTPUT_IS_TEXT=0 for x; do if [ $FIRST -eq 1 ]; then set -- @@ -128,7 +127,9 @@ for x; do continue elif [ x"$x" = x"-r" ]; then RELOCATABLE=1 - elif [ x"$x" = x"-E" ]; then + elif [ x"$x" = x"-E" ] || + [ x"$x" = x"-M" ] || + [ x"$x" = x"-MM" ]; then INTENT=cpp elif [ x"$x" = x"-o" ]; then NEED_OUTPUT=1 @@ -176,12 +177,6 @@ for x; do GOT_SOME=1 elif [ x"$x" = x"-dumpmachine" ]; then GOT_SOME=1 - elif [ x"$x" = x"-M" ] || - [ x"$x" = x"-MM" ] || - [ x"$x" = x"-MD" ] || - [ x"$x" = x"-MMD" ] || - [ x"$x" = x"-E" ]; then - OUTPUT_IS_TEXT=1 fi set -- "$@" "$x" done @@ -223,10 +218,7 @@ log_command "$@" if [ -n "$OUTPUT" ] && [ -f "$OUTPUT" ]; then if [ $INTENT = cc ] || [ $INTENT = ld ]; then - if [ $OUTPUT_IS_TEXT -eq 0 ]; then - "$BIN/fixupobj" "$OUTPUT" - fi - exit + "$BIN/fixupobj" "$OUTPUT" || exit fi if [ $INTENT = ld ]; then if [ x"$OUTPUT" != x"${OUTPUT%.com}" ] ||