aboutsummaryrefslogtreecommitdiff
path: root/msvc-common/msvc-cl-common
diff options
context:
space:
mode:
Diffstat (limited to 'msvc-common/msvc-cl-common')
-rwxr-xr-xmsvc-common/msvc-cl-common154
1 files changed, 154 insertions, 0 deletions
diff --git a/msvc-common/msvc-cl-common b/msvc-common/msvc-cl-common
new file mode 100755
index 0000000..57d389e
--- /dev/null
+++ b/msvc-common/msvc-cl-common
@@ -0,0 +1,154 @@
+#! /usr/bin/env bash
+
+# Note: shouldn't be executed directly, src_dir must be set.
+
+# Common cl.exe driver that expects the VCBIN, INCLUDE, and, if running as a
+# linker, SDKBIN, LIB variables to be set for the specific MSVC
+# version/configuration.
+
+trap "{ exit 1; }" ERR
+set -o errtrace # Trap in functions.
+
+function info () { echo "$*" 1>&2; }
+function error () { info "$*"; exit 1; }
+
+source "$src_dir/msvc-common/msvc-common"
+
+# File descriptor where the diagnostics will be sent. Unless STDOUT is used
+# for something else (e.g., /E), cl.exe sends the diagnostics there.
+# Otherwise it goes to STDERR.
+#
+diag=1
+
+# Translate absolute paths from POSIX to Windows. Use bash array to store
+# arguments in case they contain spaces.
+#
+# This needs to be done for both certain option values and arguments.
+# Arguments are tricky in that unless we recognize every option, and option
+# may look a lot like an absolute POSIX path (e.g., /nologo). The heuristics
+# that we are going to use here is that if the argument starts with / and
+# contains at least one more /, then we consider it an argument. Otherwise --
+# an options. We will also explicitly recognize certain options, like /D,
+# which may not fit this scheme well.
+#
+# Note that the order of the cases is important. Specifically, we want, e.g.,
+# /D before /D*.
+#
+# Note also that cl.exe options are case-sensitive.
+#
+args=()
+
+while [ $# -gt 0 ]; do
+ case $1 in
+
+ # /I <dir>, /AI <dir>
+ #
+ [/-]I | \
+ [/-]AI)
+ args=("${args[@]}" "$1")
+ shift
+ args=("${args[@]}" "$(translate $1)")
+ shift
+ ;;
+
+ # /I<dir>
+ #
+ [/-]I*)
+ args=("${args[@]}" "$(split_translate 2 $1)")
+ shift
+ ;;
+
+ # /AI<dir>
+ #
+ [/-]AI*)
+ args=("${args[@]}" "$(split_translate 3 $1)")
+ shift
+ ;;
+
+ # /F*: <file>
+ #
+ [/-]F[adeimoprR]:)
+ args=("${args[@]}" "$1")
+ shift
+ args=("${args[@]}" "$(translate $1)")
+ shift
+ ;;
+
+ # /F*<file>, /T{p,c}<file>, /Yu<file>.
+ #
+ [/-]F[adeimoprRUI]* | \
+ [/-]Tp* | \
+ [/-]Tc* | \
+ [/-]Yu*)
+ args=("${args[@]}" "$(split_translate 3 $1)")
+ shift
+ ;;
+
+ # /doc<file>
+ #
+ [/-]doc*)
+ args=("${args[@]}" "$(split_translate 4 $1)")
+ shift
+ ;;
+
+ # @<file>
+ #
+ @*)
+ args=("${args[@]}" "$(split_translate 1 $1)")
+ shift
+ ;;
+
+ # Handle other options with separate values. This makes sure we don't try
+ # to path-translate them.
+ #
+ [/-]D | \
+ [/-]U | \
+ [/-]link)
+ args=("${args[@]}" "$1")
+ shift
+ args=("${args[@]}" "$1")
+ shift
+ ;;
+
+ # Handle other options with combined values that could possibly be
+ # interpreted as paths, for example /DFOO=foo/bar.
+ #
+ [/-]D* | \
+ [/-]V* | \
+ [/-]Yl*)
+ args=("${args[@]}" "$1")
+ shift
+ ;;
+
+ # Detect /E and /EP -- they change where the diagnostics is sent.
+ #
+ [/-]E | \
+ [/-]EP)
+ diag=2
+ args=("${args[@]}" "$1")
+ shift
+ ;;
+
+ # Option or argument.
+ #
+ *)
+ # If contains at least two slashes, treat it as a path.
+ #
+ if [[ "$1" == /*/* ]]; then
+ args=("${args[@]}" "$(translate $1)")
+ else
+ args=("${args[@]}" "$1")
+ fi
+ shift
+ ;;
+ esac
+done
+
+export INCLUDE
+export LIB
+
+# The linker may need to run mt.exe which is in the SDK.
+#
+export WINEPATH="$VCBIN;$VCDLL;$SDKBIN"
+
+msvc_exec $diag "$VCBIN\\cl.exe" "${args[@]}"