From 3209a9fa6e87ad4d2f9d1087a1206347df4c6214 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 24 Nov 2016 11:38:44 +0200 Subject: Reorganize the script structure --- msvc-common | 50 ------------ msvc-common/msvc-cl-common | 154 +++++++++++++++++++++++++++++++++++ msvc-common/msvc-common | 56 +++++++++++++ msvc-common/msvc-lib-common | 100 +++++++++++++++++++++++ msvc-common/msvc-link-common | 188 +++++++++++++++++++++++++++++++++++++++++++ msvc-common/msvc-mt-common | 111 +++++++++++++++++++++++++ msvc-common/msvc-rc-common | 123 ++++++++++++++++++++++++++++ 7 files changed, 732 insertions(+), 50 deletions(-) delete mode 100755 msvc-common create mode 100755 msvc-common/msvc-cl-common create mode 100755 msvc-common/msvc-common create mode 100755 msvc-common/msvc-lib-common create mode 100755 msvc-common/msvc-link-common create mode 100755 msvc-common/msvc-mt-common create mode 100755 msvc-common/msvc-rc-common (limited to 'msvc-common') diff --git a/msvc-common b/msvc-common deleted file mode 100755 index 479ec3f..0000000 --- a/msvc-common +++ /dev/null @@ -1,50 +0,0 @@ -#! /usr/bin/env bash - -# Note: shouldn't be executed directly. - -# Translate absolute POSIX path to a Windows path with winepath. -# -function translate () # -{ - if [[ "$1" == /* ]]; then - winepath -w "$1" - else - echo "$1" - fi -} - -# Split the combined option and path value, translate the path component -# to a Windows path if absolute, then recombine the option and path. -# -function split_translate () # -{ - local o="${2:0:$1}" # First characters from $1. - local v="${2:$1}" # The rest. - - # If the path is absolute, map it with winepath. - # - if [[ "$v" == /* ]]; then - v="$(winepath -w "$v")" - fi - - echo "$o$v" -} - -# The argument should be 1 or 2. It indicates whether the diagnostics -# is sent to stdout (1) or stderr (2). -# -function msvc_exec () # ... -{ - local diag="$1" - shift - - # Suppress Wine noise. - # - export WINEDEBUG=fixme-all - - # Filter diagnostics output replacing absolute Windows paths with their - # POSIX mapping. If is 1 then both stdout and stderr output are read - # and filtered. - # - "$(dirname $(realpath ${BASH_SOURCE[0]}))/msvc-filter" "$diag" wine "$@" -} 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 , /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 + +# 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[@]}" diff --git a/msvc-common/msvc-common b/msvc-common/msvc-common new file mode 100755 index 0000000..d571f87 --- /dev/null +++ b/msvc-common/msvc-common @@ -0,0 +1,56 @@ +#! /usr/bin/env bash + +# Note: shouldn't be executed directly, src_dir must be set. + +# Translate absolute POSIX path to a Windows path with winepath. +# +function translate () # +{ + if [[ "$1" == /* ]]; then + winepath -w "$1" + else + echo "$1" + fi +} + +# Split the combined option and path value, translate the path component +# to a Windows path if absolute, then recombine the option and path. +# +function split_translate () # +{ + local o="${2:0:$1}" # First characters from $1. + local v="${2:$1}" # The rest. + + # If the path is absolute, map it with winepath. + # + if [[ "$v" == /* ]]; then + v="$(winepath -w "$v")" + fi + + echo "$o$v" +} + +# The argument should be 1 or 2. It indicates whether the diagnostics +# is sent to stdout (1) or stderr (2). +# +function msvc_exec () # ... +{ + local diag="$1" + shift + + # Suppress Wine noise. + # + export WINEDEBUG=fixme-all + + # Set an alternative .wine directory if requested. + # + if [ -n "$MSVC_WINEPREFIX" ]; then + export WINEPREFIX="$MSVC_WINEPREFIX" + fi + + # Filter diagnostics output replacing absolute Windows paths with their + # POSIX mapping. If is 1 then both stdout and stderr output are read + # and filtered. + # + "$src_dir/msvc-filter" "$diag" wine "$@" +} diff --git a/msvc-common/msvc-lib-common b/msvc-common/msvc-lib-common new file mode 100755 index 0000000..a38bcd3 --- /dev/null +++ b/msvc-common/msvc-lib-common @@ -0,0 +1,100 @@ +#! /usr/bin/env bash + +# Note: shouldn't be executed directly, src_dir must be set. + +# Common lib.exe driver that expects the VCBIN and LIB variables to be set for +# the specific MSVC version/configuration. +# +# It's not clear/documented why we need LIB or what the /LIBPATH option is +# for. Perhaps for link-time code generation (/LTCG). + +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" + +# 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 which may +# not fit this scheme well. +# +args=() + +while [ $# -gt 0 ]; do + case ${1^^} in # Uppercase for case-insensitive comparison. + + # /DEF[:filename] + # /OUT:filename + # + [/-]DEF:* | \ + [/-]OUT:*) + args=("${args[@]}" "$(split_translate 5 $1)") + shift + ;; + + # /LIST[:filename] + # /NAME:filename + # + [/-]LIST:* | \ + [/-]NAME:*) + args=("${args[@]}" "$(split_translate 6 $1)") + shift + ;; + + # /LIBPATH:dir + # + [/-]LIBPATH:*) + args=("${args[@]}" "$(split_translate 9 $1)") + shift + ;; + + # Handle other options with separate values. This makes sure we don't try + # to path-translate them. + # + + # Aren't any. + + # Handle other options with combined values that could possibly be + # interpreted as paths, for example /EXTRACT:foo/bar.obj. + # + [/-]EXPORT:* | \ + [/-]EXTRACT:* | \ + [/-]INCLUDE:* | \ + [/-]REMOVE:*) + 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 LIB + +# link.exe may need to run other tools (/LTCG). +# +export WINEPATH="$VCBIN;$VCDLL;$SDKBIN" + +# lib.exe always sends diagnostics to stdout. +# +msvc_exec 1 "$VCBIN\\lib.exe" "${args[@]}" diff --git a/msvc-common/msvc-link-common b/msvc-common/msvc-link-common new file mode 100755 index 0000000..931a251 --- /dev/null +++ b/msvc-common/msvc-link-common @@ -0,0 +1,188 @@ +#! /usr/bin/env bash + +# Note: shouldn't be executed directly, src_exe and src_dir must be set. + +# Common link.exe driver that expects the VCBIN, SDKBIN, 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 "$src_dir/msvc-common/msvc-common" + +# 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 which may +# not fit this scheme well. +# +# Note that link.exe /? is missing some options that are documented in MSDN. +# +args=() + +while [ $# -gt 0 ]; do + case ${1^^} in # Uppercase for case-insensitive comparison. + + # @@ TODO: handle the rest/obscure options. + # + # @file + # /ASSEMBLYLINKRESOURCE:filename + # /ASSEMBLYMODULE:filename + # /ASSEMBLYRESOURCE:filename[,[name][,PRIVATE]] + # /BASE:{address[,size]|@filename,key} + #+ /DEF:filename + #+ /DEFAULTLIB:library + #+ /DELAYLOAD:dll + # /FASTGENPROFILE:PGD=filename|... + # /GENPROFILE:PGD=filename|... + #+ /IDLOUT:filename + #+ /IMPLIB:filename + #+ /KEYFILE:filename + #+ /LIBPATH:dir + #+ /MANIFESTFILE:filename + #+ /MANIFESTINPUT:filename + #+ /MAP:filename + #+ /MIDL:@commandfile + #+ /NODEFAULTLIB:library + #+ /ORDER:@filename + #+ /OUT:filename + #+ /PDB:filename + #+ /PDBALTPATH:filename + #+ /PDBSTRIPPED:filename + #+ /PGD:filename + #+ /STUB:filename + #+ /TLBOUT:filename + # /USEPROFILE:PGD=filename + #+ /WHOLEARCHIVE:library + #+ /WINMDFILE:filename + # /WINMDKEYCONTAINER:name + #+ /WINMDKEYFILE:filename + + [/-]DEF:* | \ + [/-]MAP:* | \ + [/-]OUT:* | \ + [/-]PDB:* | \ + [/-]PGD:*) + args=("${args[@]}" "$(split_translate 5 $1)") + shift + ;; + + [/-]STUB:*) + args=("${args[@]}" "$(split_translate 6 $1)") + shift + ;; + + [/-]MIDL:@*) + args=("${args[@]}" "$(split_translate 7 $1)") + shift + ;; + + [/-]IMPLIB:* | \ + [/-]IDLOUT:* | \ + [/-]TLBOUT:* | \ + [/-]ORDER:@*) + args=("${args[@]}" "$(split_translate 8 $1)") + shift + ;; + + [/-]KEYFILE:* | \ + [/-]LIBPATH:*) + args=("${args[@]}" "$(split_translate 9 $1)") + shift + ;; + + [/-]DELAYLOAD:* | \ + [/-]WINMDFILE:*) + args=("${args[@]}" "$(split_translate 11 $1)") + shift + ;; + + [/-]DEFAULTLIB:* | \ + [/-]PDBALTPATH:*) + args=("${args[@]}" "$(split_translate 12 $1)") + shift + ;; + + [/-]PDBSTRIPPED:*) + args=("${args[@]}" "$(split_translate 13 $1)") + shift + ;; + + [/-]NODEFAULTLIB:* | \ + [/-]MANIFESTFILE:* | \ + [/-]WHOLEARCHIVE:* | \ + [/-]WINMDKEYFILE:*) + args=("${args[@]}" "$(split_translate 14 $1)") + shift + ;; + + [/-]MANIFESTINPUT:*) + args=("${args[@]}" "$(split_translate 15 $1)") + shift + ;; + + # Handle other options with separate values. This makes sure we don't try + # to path-translate them. + # + + # Aren't any. + + # Handle other options with combined values that could possibly be + # interpreted as paths. + # + # /ENTRY:symbol + # /EXPORT:symbol + # /INCLUDE:symbol + # /KEYCONTAINER:name + # /MANIFESTDEPENDENCY:manifest dependency + # /MANIFESTUAC[:{NO|UAC fragment}] + # /MAPINFO:{EXPORTS} + # /MERGE:from=to + # /SECTION:name,[[!]{DEKPRSW}][,ALIGN=#] + # + [/-]ENTRY:* | \ + [/-]EXPORT:* | \ + [/-]INCLUDE:* | \ + [/-]KEYCONTAINER:* | \ + [/-]MANIFESTDEPENDENCY:* | \ + [/-]MANIFESTUAC:* | \ + [/-]MAPINFO:* | \ + [/-]MERGE:* | \ + [/-]SECTION:* | \ + [/-]REMOVE:*) + 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 LIB + +# link.exe may need to run mt.exe which is in the SDK. +# +export WINEPATH="$VCBIN;$VCDLL;$SDKBIN" + +# link.exe always sends diagnostics to stdout. +# +msvc_exec 1 "$VCBIN\\link.exe" "${args[@]}" diff --git a/msvc-common/msvc-mt-common b/msvc-common/msvc-mt-common new file mode 100755 index 0000000..305d98e --- /dev/null +++ b/msvc-common/msvc-mt-common @@ -0,0 +1,111 @@ +#! /usr/bin/env bash + +# Note: shouldn't be executed directly, src_dir must be set. + +# Common mt.exe driver that expects the SDKBIN variable 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" + +# 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. +# +# Note that we assume mt.exe options start with '-' and are case-sensitive. +# +args=() + +while [ $# -gt 0 ]; do + case $1 in + + # @@ TODO: handle for [;[#]] + # + # -rgs: + # -tlb: + # -dll: + # -replacements: + # -managedassemblyname: + # -out: + # -inputresource:[;[#]] + # -outputresource:[;[#]] + # -updateresource:[;[#]] + # -hashupdate[:] + # -validate_file_hashes: + + -rgs:* | \ + -tlb:* | \ + -dll:* | \ + -out:*) + args=("${args[@]}" "$(split_translate 5 $1)") + shift + ;; + + -hashupdate:*) + args=("${args[@]}" "$(split_translate 12 $1)") + shift + ;; + + -replacements:*) + args=("${args[@]}" "$(split_translate 14 $1)") + shift + ;; + + -inputresource:*) + args=("${args[@]}" "$(split_translate 15 $1)") + shift + ;; + + -outputresource:* | \ + -updateresource:*) + args=("${args[@]}" "$(split_translate 16 $1)") + shift + ;; + + -managedassemblyname:*) + args=("${args[@]}" "$(split_translate 21 $1)") + shift + ;; + + -validate_file_hashes:*) + args=("${args[@]}" "$(split_translate 22 $1)") + shift + ;; + + # Handle other options with separate values. This makes sure we don't try + # to path-translate them. + # + + # None. + + # Handle other options with combined values that could possibly be + # interpreted as paths. + # + -identity:*) + args=("${args[@]}" "$1") + shift + ;; + + # Option or argument. + # + *) + # If starts with a slash, treat it as a path (options start with dash). + # + if [[ "$1" == /* ]]; then + args=("${args[@]}" "$(translate $1)") + else + args=("${args[@]}" "$1") + fi + shift + ;; + esac +done + +# mt.exe always sends diagnostics to stdout. +# +msvc_exec 1 "$SDKBIN\\mt.exe" "${args[@]}" diff --git a/msvc-common/msvc-rc-common b/msvc-common/msvc-rc-common new file mode 100755 index 0000000..ca986b4 --- /dev/null +++ b/msvc-common/msvc-rc-common @@ -0,0 +1,123 @@ +#! /usr/bin/env bash + +# Note: shouldn't be executed directly, src_dir must be set. + +# Common rc.exe driver that expects the SDKBIN and INCLUDE 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" + +# 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 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 that rc.exe /? is missing some options that are documented in MSDN. +# +args=() + +while [ $# -gt 0 ]; do + case ${1^^} in # Uppercase for case-insensitive comparison. + + # /I + # + [/-]I) + args=("${args[@]}" "$1") + shift + args=("${args[@]}" "$(translate $1)") + shift + ;; + + # /I + # + [/-]I*) + args=("${args[@]}" "$(split_translate 2 $1)") + shift + ;; + + # /f[om] + # + [/-]F[OM]) + args=("${args[@]}" "$1") + shift + args=("${args[@]}" "$(translate $1)") + shift + ;; + + # /f[om] + # + [/-]F[OM]*) + args=("${args[@]}" "$(split_translate 3 $1)") + shift + ;; + + # /q + # + [/-]Q) + args=("${args[@]}" "$1") + shift + args=("${args[@]}" "$(translate $1)") + shift + ;; + + # /q + # + [/-]Q*) + args=("${args[@]}" "$(split_translate 2 $1)") + shift + ;; + + # Handle other options with separate values. This makes sure we don't try + # to path-translate them. + # + [/-]D | \ + [/-]U) + 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*) + 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 + +# rc.exe always sends diagnostics to stdout. +# +msvc_exec 1 "$SDKBIN\\rc.exe" "${args[@]}" -- cgit v1.1