Update winpty to work with MSYS, MSYS2, and Cygwin.

* MSYS is 32-bit only.

 * MSYS2 and Cygwin are either 32-bit or 64-bit.  On 64-bit MSYS2/Cygwin,
   we use the same architecture for all generated binaries.

 * Prefer mingw-w64 to mingw.  mingw-w64 seems to be more up-to-date.
   It is the only option for 64-bit Windows, so stop looking for
   x86_64-pc-mingw32-g++.

 * Also pass -static when linking binaries.  Otherwise, a pthreads DLL
   is linked dynamically.
This commit is contained in:
Ryan Prichard 2015-09-30 03:34:16 -05:00
parent 9da12b25c5
commit 2ecc596f8b
5 changed files with 84 additions and 29 deletions

View File

@ -25,7 +25,7 @@ You need the following to build winpty:
* A Cygwin or MSYS installation * A Cygwin or MSYS installation
* GNU make * GNU make
* A MinGW 32-bit g++ toolchain, v4 or later, to build ``winpty.dll`` and * A MinGW g++ toolchain, v4 or later, to build ``winpty.dll`` and
``winpty-agent.exe`` ``winpty-agent.exe``
* A g++ toolchain targeting Cygwin or MSYS, v3 or later, to build * A g++ toolchain targeting Cygwin or MSYS, v3 or later, to build
``console.exe`` ``console.exe``
@ -38,8 +38,7 @@ compiled with the MSYS/Cygwin toolchain.
MinGW appears to be split into two distributions -- MinGW (creates 32-bit MinGW appears to be split into two distributions -- MinGW (creates 32-bit
binaries) and MinGW-w64 (creates both 32-bit and 64-bit binaries). Either binaries) and MinGW-w64 (creates both 32-bit and 64-bit binaries). Either
one is acceptable, but the compiler must be v4 or later and produce 32-bit one is acceptable, but the compiler must be v4 or later.
binaries.
Cygwin packages Cygwin packages
--------------- ---------------
@ -48,20 +47,29 @@ The default g++ compiler for Cygwin targets Cygwin itself, but Cygwin also
packages MinGW compilers from both the MinGW and MinGW-w64 projects. As of packages MinGW compilers from both the MinGW and MinGW-w64 projects. As of
this writing, the necessary packages are: this writing, the necessary packages are:
* Either ``mingw-gcc-g++`` or ``mingw64-i686-gcc-g++`` (but not * Either ``mingw-gcc-g++``, ``mingw64-i686-gcc-g++`` or
``mingw64-x86_64-gcc-g++``) ``mingw64-x86_64-gcc-g++``. Select the appropriate compiler for your
CPU architecture.
* ``gcc-g++`` * ``gcc-g++``
MinGW packages MSYS packages
-------------- -------------
The default g++ compiler for MinGW targets native Windows, but the MinGW For the original MSYS, use the ``mingw-get`` tool (MinGW Installation Manager),
project also packages compilers to target the MSYS environment itself. The and select at least these components:
required packages are: * ``mingw-developer-toolkit``
* ``mingw32-base``
* ``mingw32-gcc-g++``
* ``msys-base``
* ``msys-system-builder``
* ``mingw32-make`` When running ``./configure``, make sure that ``mingw32-g++`` is in your
* ``g++`` ``PATH``. It will be in the ``C:\MinGW\bin`` directory.
* ``msys-dvlpr``
For MSYS2, use ``pacman`` and install at least these packages:
* ``msys/gcc``
* ``mingw32/mingw-w64-i686-gcc`` or ``mingw64/mingw-w64-x86_64-gcc``. Select
the appropriate compiler for your CPU architecture.
Build Build

View File

@ -44,7 +44,7 @@ CXXFLAGS += \
-fno-exceptions \ -fno-exceptions \
-fno-rtti -fno-rtti
LDFLAGS += -static-libgcc -static-libstdc++ LDFLAGS += -static -static-libgcc -static-libstdc++
all : $(PROGRAM) all : $(PROGRAM)

70
configure vendored
View File

@ -47,6 +47,13 @@ function findTool {
IS_CYGWIN=0 IS_CYGWIN=0
IS_MSYS=0 IS_MSYS=0
# Link parts of the Cygwin binary statically to aid in redistribution? The
# binary still links dynamically against the main DLL. The MinGW binaries are
# also statically linked and therefore depend only on Windows DLLs. I started
# linking the Cygwin/MSYS binary statically, because G++ 4.7 changed the
# Windows C++ ABI.
UNIX_LDFLAGS_STATIC_LIBSTDCXX='-static -static-libgcc -static-libstdc++'
# Detect the environment -- Cygwin or MSYS. # Detect the environment -- Cygwin or MSYS.
case $(uname -s) in case $(uname -s) in
CYGWIN*) CYGWIN*)
@ -54,30 +61,67 @@ case $(uname -s) in
IS_CYGWIN=1 IS_CYGWIN=1
case $(uname -m) in case $(uname -m) in
i686) i686)
echo 'uname -m identifies a i686 environment.' echo 'uname -m identifies an i686 environment.'
UNIX_GPP=i686-pc-cygwin-g++ UNIX_GPP=i686-pc-cygwin-g++
MINGW_GPP="i686-pc-mingw32-g++ i686-w64-mingw32-g++" MINGW_GPP="i686-w64-mingw32-g++ i686-pc-mingw32-g++"
;; ;;
x86_64) x86_64)
echo 'uname -m identifies a x86_64 environment.' echo 'uname -m identifies an x86_64 environment.'
UNIX_GPP=x86_64-pc-cygwin-g++ UNIX_GPP=x86_64-pc-cygwin-g++
MINGW_GPP="x86_64-pc-mingw32-g++ x86_64-w64-mingw32-g++" MINGW_GPP=x86_64-w64-mingw32-g++
;; ;;
*) *)
echo 'Error: uname -m did not match either i686 or x86_64.' echo 'Error: uname -m did not match either i686 or x86_64.'
exit 1 exit 1
;; ;;
esac esac
UNIX_LDFLAGS_STATIC_LIBSTDCXX="-static-libgcc -static-libstdc++"
;; ;;
MINGW*) MSYS*|MINGW*)
echo 'uname -s identifies a MSYS environment.' # MSYS2 notes:
# - MSYS2 offers two shortcuts to open an environment:
# - MinGW-w64 Win32 Shell. This env reports a `uname -s` of
# MINGW32_NT-6.1 on 32-bit Win7. The MinGW-w64 compiler
# (i686-w64-mingw32-g++.exe) is in the PATH.
# - MSYS2 Shell. `uname -s` instead reports MSYS_NT-6.1.
# The i686-w64-mingw32-g++ compiler is not in the PATH.
# - MSYS2 appears to use MinGW-w64, not the older mingw.org.
# MSYS notes:
# - `uname -s` is always MINGW32_NT-6.1 on Win7.
echo 'uname -s identifies an MSYS/MSYS2 environment.'
IS_MSYS=1 IS_MSYS=1
UNIX_GPP=i686-pc-msys-g++ case $(uname -m) in
MINGW_GPP=mingw32-g++ i686)
# The MSYS compiler does not recognize -static-libstdc++. There is a echo 'uname -m identifies an i686 environment.'
# msys-1.0.dll, but no gcc or stdc++ DLL. UNIX_GPP=i686-pc-msys-g++
UNIX_LDFLAGS_STATIC_LIBSTDCXX= MINGW_GPP='i686-w64-mingw32-g++.exe mingw32-g++'
if echo "$(uname -r)" | grep '^1[.]' > /dev/null; then
# The MSYS-targeting compiler for the original 32-bit-only
# MSYS does not recognize the -static-libstdc++ flag, and
# it does not work with -static, because it tries to link
# statically with the core MSYS library and fails.
#
# Distinguish between the two using the major version
# number of `uname -r`:
#
# MSYS uname -r: 1.0.18(0.48/3/2)
# MSYS2 uname -r: 2.0.0(0.284/5/3)
#
# This is suboptimal because MSYS2 is not actually the
# second version of MSYS--it's a brand-new fork of Cygwin.
#
UNIX_LDFLAGS_STATIC_LIBSTDCXX=
fi
;;
x86_64)
echo 'uname -m identifies an x86_64 environment.'
UNIX_GPP=x86_64-pc-msys-g++
MINGW_GPP=x86_64-w64-mingw32-g++
;;
*)
echo 'Error: uname -m did not match either i686 or x86_64.'
exit 1
;;
esac
;; ;;
*) *)
echo 'Error: uname -s did not match either CYGWIN* or MINGW*.' echo 'Error: uname -s did not match either CYGWIN* or MINGW*.'
@ -88,7 +132,7 @@ esac
# Search the PATH and pick the first match. # Search the PATH and pick the first match.
findTool "Cygwin/MSYS G++ compiler" "$UNIX_GPP" findTool "Cygwin/MSYS G++ compiler" "$UNIX_GPP"
UNIX_GPP=$FINDTOOL_OUT UNIX_GPP=$FINDTOOL_OUT
findTool "32-bit MinGW G++ compiler" "$MINGW_GPP" findTool "MinGW G++ compiler" "$MINGW_GPP"
MINGW_GPP=$FINDTOOL_OUT MINGW_GPP=$FINDTOOL_OUT
# Write config files. # Write config files.

View File

@ -23,7 +23,7 @@ include ../config-mingw.mk
LIBRARY = ../build/winpty.dll LIBRARY = ../build/winpty.dll
OBJECTS = winpty.o DebugClient.o OBJECTS = winpty.o DebugClient.o
LDFLAGS += -shared -static-libgcc -static-libstdc++ LDFLAGS += -shared -static -static-libgcc -static-libstdc++
CXXFLAGS += \ CXXFLAGS += \
-I../include \ -I../include \

View File

@ -223,7 +223,10 @@ static void setFdNonBlock(int fd)
static std::string convertPosixPathToWin(const std::string &path) static std::string convertPosixPathToWin(const std::string &path)
{ {
char *tmp; char *tmp;
#if !defined(__MSYS__) && CYGWIN_VERSION_API_MINOR >= 181 #if defined(CYGWIN_VERSION_CYGWIN_CONV) && \
CYGWIN_VERSION_API_MINOR >= CYGWIN_VERSION_CYGWIN_CONV
// MSYS2 and versions of Cygwin released after 2009 or so use this API.
// The original MSYS still lacks this API.
ssize_t newSize = cygwin_conv_path(CCP_POSIX_TO_WIN_A | CCP_RELATIVE, ssize_t newSize = cygwin_conv_path(CCP_POSIX_TO_WIN_A | CCP_RELATIVE,
path.c_str(), NULL, 0); path.c_str(), NULL, 0);
assert(newSize >= 0); assert(newSize >= 0);