#! /usr/bin/env bash # Common cl.exe driver that expects the VC, INCLUDE, and 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 $(dirname $(realpath ${BASH_SOURCE[0]}))/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 , /AI # [/-]I | \ [/-]AI) args=("${args[@]}" "$1") shift args=("${args[@]}" "$(translate $1)") shift ;; # /I # [/-]I*) args=("${args[@]}" "$(split_translate 2 $1)") shift ;; # /AI # [/-]AI*) args=("${args[@]}" "$(split_translate 3 $1)") shift ;; # /F*: # [/-]F[adeimoprR]:) args=("${args[@]}" "$1") shift args=("${args[@]}" "$(translate $1)") shift ;; # /F*, /T{p,c}, /Yu. # [/-]F[adeimoprRUI]* | \ [/-]Tp* | \ [/-]Tc* | \ [/-]Yu*) args=("${args[@]}" "$(split_translate 3 $1)") shift ;; # /doc # [/-]doc*) args=("${args[@]}" "$(split_translate 4 $1)") shift ;; # @ # @*) 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 msvc_exec $diag "$VCBIN\\cl.exe" "${args[@]}"