aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-06-06 18:17:33 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-06-06 18:17:33 +0200
commit18d2d38ba4c03d48a772174f3de856d81ff39a4f (patch)
treeea6a461953cae17b5006bac96171949f6e707489
parent34985ea6f26f6f0a383532ad804e44527715c3fe (diff)
Major redesign of wrappers
-rw-r--r--TODO13
-rwxr-xr-xcl-1120
-rwxr-xr-xcl-1220
-rwxr-xr-xcl-1432
-rwxr-xr-xlib-116
-rwxr-xr-xlib-126
-rwxr-xr-xlib-146
-rwxr-xr-xlink-116
-rwxr-xr-xlink-126
-rwxr-xr-xlink-146
-rwxr-xr-xmsvc-1118
-rwxr-xr-xmsvc-1218
-rwxr-xr-xmsvc-1426
-rwxr-xr-xmsvc-cl-common145
-rwxr-xr-xmsvc-common121
-rwxr-xr-xmsvc-lib-common95
-rwxr-xr-xmsvc-link-common80
17 files changed, 562 insertions, 62 deletions
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..83d5769
--- /dev/null
+++ b/TODO
@@ -0,0 +1,13 @@
+@@ link.exe option translation.
+
+@@ Requires GNU sed 4.2.2 or later (-z), realpath dirpath
+
+@@ Still need wineserver for /EP, etc. otherwise long pause.
+
+@@ Redirection of /EP to /dev/null is slow, to file is much faster.
+
+@@ What about 64-bit? cl-64 or some such?
+
+@@ I think options are not case-sensitive.
+
+@@ There is link command. link.exe? cl-14.exe?
diff --git a/cl-11 b/cl-11
index 5dc651e..7f6b85e 100755
--- a/cl-11
+++ b/cl-11
@@ -1,20 +1,6 @@
#! /usr/bin/env bash
-trap 'exit 1' ERR
+src="$(dirname $(realpath ${BASH_SOURCE[0]}))"
-SDK="C:\Program Files (x86)\Windows Kits\8.0"
-
-INCLUDE="$SDK\include\shared;$SDK\include\um;$SDK\include\winrt"
-LIB="$SDK\lib\win8\um\x86"
-
-VC="C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC"
-
-INCLUDE="$VC\include;$INCLUDE"
-LIB="$VC\lib;$LIB"
-
-export INCLUDE
-export LIB
-
-export WINEDEBUG=fixme-all
-
-wine "$VC\bin\cl.exe" $*
+source "$src/msvc-11"
+source "$src/msvc-cl-common"
diff --git a/cl-12 b/cl-12
index 8bda7ff..29490fc 100755
--- a/cl-12
+++ b/cl-12
@@ -1,20 +1,6 @@
#! /usr/bin/env bash
-trap 'exit 1' ERR
+src="$(dirname $(realpath ${BASH_SOURCE[0]}))"
-SDK="C:\Program Files (x86)\Windows Kits\8.1"
-
-INCLUDE="$SDK\include\shared;$SDK\include\um;$SDK\include\winrt"
-LIB="$SDK\lib\winv6.3\um\x86"
-
-VC="C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC"
-
-INCLUDE="$VC\include;$INCLUDE"
-LIB="$VC\lib;$LIB"
-
-export INCLUDE
-export LIB
-
-export WINEDEBUG=fixme-all
-
-wine "$VC\bin\cl.exe" $*
+source "$src/msvc-12"
+source "$src/msvc-cl-common"
diff --git a/cl-14 b/cl-14
index 43175d1..9190b9a 100755
--- a/cl-14
+++ b/cl-14
@@ -1,30 +1,6 @@
-#!/bin/sh
+#! /usr/bin/env bash
-# SDK
-#
-SDK="C:\Program Files (x86)\Windows Kits\8.1"
+src="$(dirname $(realpath ${BASH_SOURCE[0]}))"
-INCLUDE="$SDK\include\shared;$SDK\include\um;$SDK\include\winrt"
-LIB="$SDK\lib\winv6.3\um\x86"
-
-# CRT
-#
-CRT="C:\Program Files (x86)\Windows Kits\10"
-VER="10.0.10150.0"
-
-INCLUDE="$CRT\include\\$VER\ucrt;$INCLUDE"
-LIB="$CRT\lib\\$VER\ucrt\x86;$LIB"
-
-# VC
-#
-VC="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC"
-
-INCLUDE="$VC\include;$INCLUDE"
-LIB="$VC\lib;$LIB"
-
-export INCLUDE
-export LIB
-
-export WINEDEBUG=fixme-all
-
-exec wine "$VC\bin\cl.exe" $*
+source "$src/msvc-14"
+source "$src/msvc-cl-common"
diff --git a/lib-11 b/lib-11
new file mode 100755
index 0000000..87d3625
--- /dev/null
+++ b/lib-11
@@ -0,0 +1,6 @@
+#! /usr/bin/env bash
+
+src="$(dirname $(realpath ${BASH_SOURCE[0]}))"
+
+source "$src/msvc-11"
+source "$src/msvc-lib-common"
diff --git a/lib-12 b/lib-12
new file mode 100755
index 0000000..f047635
--- /dev/null
+++ b/lib-12
@@ -0,0 +1,6 @@
+#! /usr/bin/env bash
+
+src="$(dirname $(realpath ${BASH_SOURCE[0]}))"
+
+source "$src/msvc-12"
+source "$src/msvc-lib-common"
diff --git a/lib-14 b/lib-14
new file mode 100755
index 0000000..050a9bc
--- /dev/null
+++ b/lib-14
@@ -0,0 +1,6 @@
+#! /usr/bin/env bash
+
+src="$(dirname $(realpath ${BASH_SOURCE[0]}))"
+
+source "$src/msvc-14"
+source "$src/msvc-lib-common"
diff --git a/link-11 b/link-11
new file mode 100755
index 0000000..14267fc
--- /dev/null
+++ b/link-11
@@ -0,0 +1,6 @@
+#! /usr/bin/env bash
+
+src="$(dirname $(realpath ${BASH_SOURCE[0]}))"
+
+source "$src/msvc-11"
+source "$src/msvc-link-common"
diff --git a/link-12 b/link-12
new file mode 100755
index 0000000..d901cd3
--- /dev/null
+++ b/link-12
@@ -0,0 +1,6 @@
+#! /usr/bin/env bash
+
+src="$(dirname $(realpath ${BASH_SOURCE[0]}))"
+
+source "$src/msvc-12"
+source "$src/msvc-link-common"
diff --git a/link-14 b/link-14
new file mode 100755
index 0000000..07e24db
--- /dev/null
+++ b/link-14
@@ -0,0 +1,6 @@
+#! /usr/bin/env bash
+
+src="$(dirname $(realpath ${BASH_SOURCE[0]}))"
+
+source "$src/msvc-14"
+source "$src/msvc-link-common"
diff --git a/msvc-11 b/msvc-11
new file mode 100755
index 0000000..d1ccc99
--- /dev/null
+++ b/msvc-11
@@ -0,0 +1,18 @@
+#! /usr/bin/env bash
+
+# MSVC 11 setup/configuration. Should set VC, INCLUDE, and LIB variables.
+#
+
+# SDK
+#
+SDK="C:\\Program Files (x86)\\Windows Kits\\8.0"
+
+INCLUDE="$SDK\\include\\shared;$SDK\\include\\um;$SDK\\include\\winrt"
+LIB="$SDK\\lib\\win8\\um\\x86"
+
+# VC
+#
+VC="C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\VC"
+
+INCLUDE="$VC\\include;$INCLUDE"
+LIB="$VC\\lib;$LIB"
diff --git a/msvc-12 b/msvc-12
new file mode 100755
index 0000000..2674215
--- /dev/null
+++ b/msvc-12
@@ -0,0 +1,18 @@
+#! /usr/bin/env bash
+
+# MSVC 12 setup/configuration. Should set VC, INCLUDE, and LIB variables.
+#
+
+# SDK
+#
+SDK="C:\\Program Files (x86)\\Windows Kits\\8.1"
+
+INCLUDE="$SDK\\include\\shared;$SDK\\include\\um;$SDK\\include\\winrt"
+LIB="$SDK\\lib\\winv6.3\\um\\x86"
+
+# VC
+#
+VC="C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC"
+
+INCLUDE="$VC\\include;$INCLUDE"
+LIB="$VC\\lib;$LIB"
diff --git a/msvc-14 b/msvc-14
new file mode 100755
index 0000000..31242c6
--- /dev/null
+++ b/msvc-14
@@ -0,0 +1,26 @@
+#! /usr/bin/env bash
+
+# MSVC 14 setup/configuration. Should set VC, INCLUDE, and LIB variables.
+#
+
+# SDK
+#
+SDK="C:\\Program Files (x86)\\Windows Kits\\8.1"
+
+INCLUDE="$SDK\\include\\shared;$SDK\\include\\um;$SDK\\include\\winrt"
+LIB="$SDK\\lib\\winv6.3\\um\\x86"
+
+# CRT
+#
+CRT="C:\\Program Files (x86)\\Windows Kits\\10"
+VER="10.0.10150.0"
+
+INCLUDE="$CRT\\include\\$VER\\ucrt;$INCLUDE"
+LIB="$CRT\\lib\\$VER\\ucrt\\x86;$LIB"
+
+# VC
+#
+VC="C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC"
+
+INCLUDE="$VC\\include;$INCLUDE"
+LIB="$VC\\lib;$LIB"
diff --git a/msvc-cl-common b/msvc-cl-common
new file mode 100755
index 0000000..ce76fc8
--- /dev/null
+++ b/msvc-cl-common
@@ -0,0 +1,145 @@
+#! /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 set.
+
+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*.
+#
+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
+
+msvc_exec $diag "$VC\\bin\\cl.exe" "${args[@]}"
diff --git a/msvc-common b/msvc-common
new file mode 100755
index 0000000..b3969e8
--- /dev/null
+++ b/msvc-common
@@ -0,0 +1,121 @@
+#! /usr/bin/env bash
+
+# Note: shouldn't be executed directly.
+
+# Translate absolute POSIX path to a Windows path with winepath.
+#
+function translate () # <path>
+{
+ 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 () # <length> <option-path>
+{
+ local o="${2:0:$1}" # First <length> 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 <diag> argument should be 1 or 2. It indicates whether the diagnostics
+# is sent to stdout (1) or stderr (2).
+#
+# Note that if <exe> returns non-zero exit status, then this function calls
+# exit, not return. It also clears the ERR trap and overrides the EXIT trap.
+# All this pretty much means it should be the last statement in a call.
+#
+function msvc_exec () # <diag> <exe> <arg>...
+{
+ local diag=$1
+ shift
+
+ local exe="$1"
+ shift
+
+ # Assemble the arguments in an array to store in case they contain spaces.
+ #
+ local args=()
+
+ while [ $# -gt 0 ]; do
+ args=("${args[@]}" "$1")
+ shift
+ done
+
+ # Translate absolute Windows paths back to POSIX. The hard part here is to
+ # determing the end of the path. For example, the error location has the
+ # 'X:\...\foo(10):' form. However, we cannot assume that '(' ends the path;
+ # remember 'Program Files (x86)'.
+ #
+ # To sidestep this whole mess we are going to use this trick: instead of
+ # translating the whole path we will only translate its directory part, that
+ # is the longest part that still ends with the directory separator. We will
+ # also still recognize ':' and ''' as path terminators as well as space if
+ # it is the first character in the component.
+ #
+ # We also pass the path through realpath in order to get the actual path
+ # rather than Wine's dosdevices links.
+ #
+
+ # First delimit paths that we need to translate with NUL characters.
+ #
+ local s1="s#[A-Z]:[\\/]([^ ':][^':]*[\\/])*#\x00&\x00#g"
+
+ # Next translate the paths (note the -z sed option). The last xargs call
+ # does two things: it removes the newline added by realpath and adds the
+ # trailing slash removed by realpath.
+ #
+ # Substitution useful for debugging: #/bin/echo -n '&'#
+ #
+ local s2="s#^[A-Z]:[\\/]([^ ':][^':]*[\\/])*#winepath -u0 '&' | \
+xargs -0 realpath -z | xargs -0 -I{} /bin/echo -n {}/#e"
+
+ # Finally, get rid of the NUL characters. While at it, also kill Windows
+ # CR (0x0d).
+ #
+ local s3="s#\x00##g;s#\x0d##g"
+
+ # For testing/debugging:
+ #
+ #cat input | sed -re "$s1" | sed -z -re "$s2" | sed -re "$s3"
+
+ # Suppress Wine noise.
+ #
+ export WINEDEBUG=fixme-all
+
+ # Create a temporary named pipe.
+ #
+ local pipe="$(mktemp -u)"
+ mkfifo $pipe
+ trap "{ rm $pipe; }" EXIT
+
+ if [ $diag -eq 1 ]; then
+ wine "$exe" "${args[@]}" 2>&1 1>$pipe &
+ sed -re "$s1" $pipe | sed -z -re "$s2" | sed -re "$s3"
+ else
+ wine "$exe" "${args[@]}" 2>$pipe &
+ sed -re "$s1" $pipe | sed -z -re "$s2" | sed -re "$s3" 1>&2
+ fi
+
+ # Wait for the wine process and exit with its exit status if it's not
+ # zero. Don't you just hate bash sometimes? I sure do.
+ #
+ trap - ERR
+ wait $!
+ local r=$?
+ if [ $r -ne 0 ]; then
+ exit $r
+ fi
+}
diff --git a/msvc-lib-common b/msvc-lib-common
new file mode 100755
index 0000000..5d11ba1
--- /dev/null
+++ b/msvc-lib-common
@@ -0,0 +1,95 @@
+#! /usr/bin/env bash
+
+# @@ Do we really need LIB? What's /LIBPATH for?
+#
+# Common lib.exe driver that expects the VC and LIB variables to be set for
+# the specific MSVC version/configuration set.
+
+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
+
+# 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
+
+ # /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
+
+# @@ Do we need this?
+#
+export LIB
+
+# Lib.exe always sends diagnostics to stdout.
+#
+msvc_exec 1 "$VC\\bin\\lib.exe" "${args[@]}"
diff --git a/msvc-link-common b/msvc-link-common
new file mode 100755
index 0000000..64c8a0c
--- /dev/null
+++ b/msvc-link-common
@@ -0,0 +1,80 @@
+#! /usr/bin/env bash
+
+# Common link.exe driver that expects the VC and LIB variables to be set for
+# the specific MSVC version/configuration set.
+
+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
+
+# 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
+
+ # /DEF[:filename]
+ # /OUT:filename
+ #
+ [/-]DEF:* | \
+ [/-]OUT:*)
+ args=("${args[@]}" "$(split_translate 5 $1)")
+ shift
+ ;;
+
+ # @@ TODO
+ #
+
+ # /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.
+ #
+
+ # @@ TODO
+
+ # Handle other options with combined values that could possibly be
+ # interpreted as paths, for example /EXTRACT:foo/bar.obj.
+ #
+
+ # @@ TODO
+
+ # 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 always sends diagnostics to stdout.
+#
+msvc_exec 1 "$VC\\bin\\link.exe" "${args[@]}"