From 06bd759e50339afecb59eef588afde2e35d9c797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 21 Apr 2024 00:13:51 +0300 Subject: [PATCH] wrappers: Add a wrapper for clang-scan-deps This picks the architecture by looking for a triple prefix in the nested command, and passes it as an explicit flag, to let clang-scan-deps find it. We also pass -stdlib=libc++, to let it find the libc++ headers as expected. --- install-wrappers.sh | 2 + wrappers/clang-scan-deps-wrapper.c | 106 ++++++++++++++++++++++++++++ wrappers/clang-scan-deps-wrapper.sh | 66 +++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100644 wrappers/clang-scan-deps-wrapper.c create mode 100755 wrappers/clang-scan-deps-wrapper.sh diff --git a/install-wrappers.sh b/install-wrappers.sh index 0df42ab..578d76f 100755 --- a/install-wrappers.sh +++ b/install-wrappers.sh @@ -126,6 +126,7 @@ if [ -n "$HOST" ] && [ -n "$EXEEXT" ]; then done fi $CC wrappers/clang-target-wrapper.c -o "$PREFIX/bin/clang-target-wrapper$EXEEXT" -O2 -Wl,-s $WRAPPER_FLAGS +$CC wrappers/clang-scan-deps-wrapper.c -o "$PREFIX/bin/clang-scan-deps-wrapper$EXEEXT" -O2 -Wl,-s $WRAPPER_FLAGS $CC wrappers/llvm-wrapper.c -o "$PREFIX/bin/llvm-wrapper$EXEEXT" -O2 -Wl,-s $WRAPPER_FLAGS if [ -n "$EXEEXT" ]; then # For Windows, we should prefer the executable wrapper, which also works @@ -141,6 +142,7 @@ for arch in $ARCHS; do for exec in clang clang++ gcc g++ c++ as; do ln -sf clang-target-wrapper$CTW_SUFFIX $arch-w64-$target_os-$exec$CTW_LINK_SUFFIX done + ln -sf clang-scan-deps-wrapper$CTW_SUFFIX $arch-w64-$target_os-clang-scan-deps$CTW_LINK_SUFFIX for exec in addr2line ar ranlib nm objcopy readelf size strings strip llvm-ar llvm-ranlib; do if [ -n "$EXEEXT" ]; then link_target=llvm-wrapper diff --git a/wrappers/clang-scan-deps-wrapper.c b/wrappers/clang-scan-deps-wrapper.c new file mode 100644 index 0000000..21f6b9f --- /dev/null +++ b/wrappers/clang-scan-deps-wrapper.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2024 Martin Storsjo + * + * This file is part of llvm-mingw. + * + * 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 "native-wrapper.h" + +#ifndef DEFAULT_TARGET +#define DEFAULT_TARGET "x86_64-w64-mingw32" +#endif + +int _tmain(int argc, TCHAR *argv[]) { + const TCHAR *dir; + split_argv(argv[0], &dir, NULL, NULL, NULL); + + int max_arg = argc + 3; + const TCHAR **exec_argv = malloc((max_arg + 1) * sizeof(*exec_argv)); + int arg = 0; + exec_argv[arg++] = concat(dir, _T("clang-scan-deps")); + + // If changing this wrapper, change clang-scan-deps-wrapper.sh accordingly. + int i = 1; + int got_flags = 0; + TCHAR *cmd_exe = NULL; + for (; i < argc; i++) { + if (got_flags) { + cmd_exe = _tcsdup(argv[i]); + exec_argv[arg++] = argv[i]; + i++; + break; + } else if (!_tcscmp(argv[i], _T("--"))) { + got_flags = 1; + exec_argv[arg++] = argv[i]; + } else { + exec_argv[arg++] = argv[i]; + } + } + + if (cmd_exe) { + // If cmd_exe is a - style command, prefer the + // target triple from there, rather than from what we might have + // had in our name. + TCHAR *sep = _tcsrchrs(cmd_exe, '/', '\\'); + if (sep) + cmd_exe = sep + 1; + sep = _tcsrchr(cmd_exe, '.'); + if (sep) + *sep = '\0'; + TCHAR *dash = _tcsrchr(cmd_exe, '-'); + const TCHAR *target = NULL; + if (dash) { + *dash = '\0'; + const TCHAR *cmd_exe_suffix = dash + 1; + if (!_tcscmp(cmd_exe_suffix, _T("clang")) || + !_tcscmp(cmd_exe_suffix, _T("clang++")) || + !_tcscmp(cmd_exe_suffix, _T("gcc")) || + !_tcscmp(cmd_exe_suffix, _T("g++")) || + !_tcscmp(cmd_exe_suffix, _T("c++")) || + !_tcscmp(cmd_exe_suffix, _T("as")) || + !_tcscmp(cmd_exe_suffix, _T("cc")) || + !_tcscmp(cmd_exe_suffix, _T("c99")) || + !_tcscmp(cmd_exe_suffix, _T("c11"))) { + target = cmd_exe; + } + } +#ifdef _WIN32 + // On Windows, we want to set our default target even if no target + // was found in cmd_exe, as we want to support running with a foreign + // clang-scan-deps-real.exe binary, that could have any default. + if (!target) + target = _T(DEFAULT_TARGET); +#endif + + if (target) { + // If we did find a cmd_exe and have figured out a target, add + // -target after cmd_exe. + exec_argv[arg++] = _T("-target"); + exec_argv[arg++] = target; + exec_argv[arg++] = _T("-stdlib=libc++"); + } + } + + for (; i < argc; i++) + exec_argv[arg++] = argv[i]; + + exec_argv[arg] = NULL; + if (arg > max_arg) { + fprintf(stderr, "Too many options added\n"); + abort(); + } + + return run_final(exec_argv[0], exec_argv); +} diff --git a/wrappers/clang-scan-deps-wrapper.sh b/wrappers/clang-scan-deps-wrapper.sh new file mode 100755 index 0000000..614e872 --- /dev/null +++ b/wrappers/clang-scan-deps-wrapper.sh @@ -0,0 +1,66 @@ +#!/bin/bash +# +# Copyright (c) 2024 Martin Storsjo +# +# 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. + +get_dir() { + target="$1" + while [ -L "$target" ]; do + cd "$(dirname "$target")" + target="$(readlink "$(basename "$target")")" + done + cd "$(dirname "$target")" + pwd +} + +DIR="$(get_dir "$0")" + +# If changing this wrapper, change clang-scan-deps-wrapper.c accordingly. +EXE="$DIR/clang-scan-deps" +FLAGS=() +while [ $# -gt 0 ]; do + if [ -n "$got_flags" ]; then + CMD_EXE="$1" + shift + break + elif [ "$1" = "--" ]; then + got_flags=1 + FLAGS+=("$1") + else + FLAGS+=("$1") + fi + shift +done + +if [ -n "$CMD_EXE" ]; then + # If CMD_EXE is a - style command, pick up the + # target triple from there. + CMD_BASENAME="$(basename "$CMD_EXE")" + CMD_BASENAME="${CMD_BASENAME%.*}" + CMD_TARGET="${CMD_BASENAME%-*}" + CMD_EXE_SUFFIX="${CMD_BASENAME##*-}" + if [ "$CMD_TARGET" != "$CMD_BASENAME" ]; then + case $CMD_EXE_SUFFIX in + clang|clang++|gcc|g++|c++|as|cc|c99|c11) + TARGET="$CMD_TARGET" + ;; + esac + fi +fi + +if [ -n "$TARGET" ]; then + "$EXE" "${FLAGS[@]}" "$CMD_EXE" -target $TARGET -stdlib=libc++ "$@" +else + "$EXE" "${FLAGS[@]}" "$@" +fi