diff options
Diffstat (limited to 'compat')
-rw-r--r-- | compat/mingw.c | 111 | ||||
-rw-r--r-- | compat/mingw.h | 24 | ||||
-rw-r--r-- | compat/msvc.h | 10 | ||||
-rw-r--r-- | compat/obstack.h | 2 | ||||
-rw-r--r-- | compat/poll/poll.c | 4 | ||||
-rw-r--r-- | compat/vcbuild/.gitignore | 3 | ||||
-rw-r--r-- | compat/vcbuild/README | 39 | ||||
-rw-r--r-- | compat/vcbuild/find_vs_env.bat | 168 | ||||
-rwxr-xr-x | compat/vcbuild/scripts/clink.pl | 41 | ||||
-rw-r--r-- | compat/vcbuild/vcpkg_copy_dlls.bat | 39 | ||||
-rw-r--r-- | compat/vcbuild/vcpkg_install.bat | 80 | ||||
-rw-r--r-- | compat/win32/git.manifest | 25 | ||||
-rw-r--r-- | compat/winansi.c | 37 |
13 files changed, 528 insertions, 55 deletions
diff --git a/compat/mingw.c b/compat/mingw.c index 9b6d2400e1..4891789771 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1407,7 +1407,7 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen do_unset_environment_variables(); /* Determine whether or not we are associated to a console */ - cons = CreateFile("CONOUT$", GENERIC_WRITE, + cons = CreateFileW(L"CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (cons == INVALID_HANDLE_VALUE) { @@ -1553,7 +1553,10 @@ static int try_shell_exec(const char *cmd, char *const *argv) if (prog) { int exec_id; int argc = 0; - const char **argv2; +#ifndef _MSC_VER + const +#endif + char **argv2; while (argv[argc]) argc++; ALLOC_ARRAY(argv2, argc + 1); argv2[0] = (char *)cmd; /* full path to the script file */ @@ -1946,13 +1949,19 @@ struct passwd *getpwuid(int uid) static unsigned initialized; static char user_name[100]; static struct passwd *p; + wchar_t buf[100]; DWORD len; if (initialized) return p; - len = sizeof(user_name); - if (!GetUserName(user_name, &len)) { + len = ARRAY_SIZE(buf); + if (!GetUserNameW(buf, &len)) { + initialized = 1; + return NULL; + } + + if (xwcstoutf(user_name, buf, sizeof(user_name)) < 0) { initialized = 1; return NULL; } @@ -2116,8 +2125,33 @@ int mingw_raise(int sig) sigint_fn(SIGINT); return 0; +#if defined(_MSC_VER) + case SIGILL: + case SIGFPE: + case SIGSEGV: + case SIGTERM: + case SIGBREAK: + case SIGABRT: + case SIGABRT_COMPAT: + /* + * The <signal.h> header in the MS C Runtime defines 8 signals + * as being supported on the platform. Anything else causes an + * "Invalid signal or error" (which in DEBUG builds causes the + * Abort/Retry/Ignore dialog). We by-pass the CRT for things we + * already know will fail. + */ + return raise(sig); + default: + errno = EINVAL; + return -1; + +#else + default: return raise(sig); + +#endif + } } @@ -2301,18 +2335,13 @@ static void setup_windows_environment(void) setenv("TERM", "cygwin", 1); } +#if !defined(_MSC_VER) /* * Disable MSVCRT command line wildcard expansion (__getmainargs called from * mingw startup code, see init.c in mingw runtime). */ int _CRT_glob = 0; - -typedef struct { - int newmode; -} _startupinfo; - -extern int __wgetmainargs(int *argc, wchar_t ***argv, wchar_t ***env, int glob, - _startupinfo *si); +#endif static NORETURN void die_startup(void) { @@ -2390,21 +2419,40 @@ static void maybe_redirect_std_handles(void) GENERIC_WRITE, FILE_FLAG_NO_BUFFERING); } -void mingw_startup(void) +#ifdef _MSC_VER +#ifdef _DEBUG +#include <crtdbg.h> +#endif +#endif + +/* + * We implement wmain() and compile with -municode, which would + * normally ignore main(), but we call the latter from the former + * so that we can handle non-ASCII command-line parameters + * appropriately. + * + * To be more compatible with the core git code, we convert + * argv into UTF8 and pass them directly to main(). + */ +int wmain(int argc, const wchar_t **wargv) { - int i, maxlen, argc; - char *buffer; - wchar_t **wenv, **wargv; - _startupinfo si; + int i, maxlen, exit_status; + char *buffer, **save; + const char **argv; trace2_initialize_clock(); - maybe_redirect_std_handles(); +#ifdef _MSC_VER +#ifdef _DEBUG + _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); +#endif - /* get wide char arguments and environment */ - si.newmode = 0; - if (__wgetmainargs(&argc, &wargv, &wenv, _CRT_glob, &si) < 0) - die_startup(); +#ifdef USE_MSVC_CRTDBG + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); +#endif +#endif + + maybe_redirect_std_handles(); /* determine size of argv and environ conversion buffer */ maxlen = wcslen(wargv[0]); @@ -2415,9 +2463,16 @@ void mingw_startup(void) maxlen = 3 * maxlen + 1; buffer = malloc_startup(maxlen); - /* convert command line arguments and environment to UTF-8 */ + /* + * Create a UTF-8 version of w_argv. Also create a "save" copy + * to remember all the string pointers because parse_options() + * will remove claimed items from the argv that we pass down. + */ + ALLOC_ARRAY(argv, argc + 1); + ALLOC_ARRAY(save, argc + 1); for (i = 0; i < argc; i++) - __argv[i] = wcstoutfdup_startup(buffer, wargv[i], maxlen); + argv[i] = save[i] = wcstoutfdup_startup(buffer, wargv[i], maxlen); + argv[i] = save[i] = NULL; free(buffer); /* fix Windows specific environment settings */ @@ -2436,6 +2491,16 @@ void mingw_startup(void) /* initialize Unicode console */ winansi_init(); + + /* invoke the real main() using our utf8 version of argv. */ + exit_status = main(argc, argv); + + for (i = 0; i < argc; i++) + free(save[i]); + free(save); + free(argv); + + return exit_status; } int uname(struct utsname *buf) diff --git a/compat/mingw.h b/compat/mingw.h index 593bdbffe6..a03e40e6e2 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -352,11 +352,13 @@ static inline int getrlimit(int resource, struct rlimit *rlp) #ifndef __MINGW64_VERSION_MAJOR #define off_t off64_t #define lseek _lseeki64 +#ifndef _MSC_VER struct timespec { time_t tv_sec; long tv_nsec; }; #endif +#endif struct mingw_stat { _dev_t st_dev; @@ -562,18 +564,18 @@ int xwcstoutf(char *utf, const wchar_t *wcs, size_t utflen); extern CRITICAL_SECTION pinfo_cs; /* - * A replacement of main() that adds win32 specific initialization. + * Git, like most portable C applications, implements a main() function. On + * Windows, this main() function would receive parameters encoded in the + * current locale, but Git for Windows would prefer UTF-8 encoded parameters. + * + * To make that happen, we still declare main() here, and then declare and + * implement wmain() (which is the Unicode variant of main()) and compile with + * -municode. This wmain() function reencodes the parameters from UTF-16 to + * UTF-8 format, sets up a couple of other things as required on Windows, and + * then hands off to the main() function. */ - -void mingw_startup(void); -#define main(c,v) dummy_decl_mingw_main(void); \ -static int mingw_main(c,v); \ -int main(int argc, const char **argv) \ -{ \ - mingw_startup(); \ - return mingw_main(__argc, (void *)__argv); \ -} \ -static int mingw_main(c,v) +int wmain(int argc, const wchar_t **w_argv); +int main(int argc, const char **argv); /* * Used by Pthread API implementation for Windows diff --git a/compat/msvc.h b/compat/msvc.h index 29a8ce8204..1d7a8c6145 100644 --- a/compat/msvc.h +++ b/compat/msvc.h @@ -6,6 +6,10 @@ #include <malloc.h> #include <io.h> +#pragma warning(disable: 4018) /* signed/unsigned comparison */ +#pragma warning(disable: 4244) /* type conversion, possible loss of data */ +#pragma warning(disable: 4090) /* 'function' : different 'const' qualifiers (ALLOC_GROW etc.)*/ + /* porting function */ #define inline __inline #define __inline__ __inline @@ -18,6 +22,12 @@ #undef ERROR +#define ftello _ftelli64 + +typedef int sigset_t; +/* open for reading, writing, or both (not in fcntl.h) */ +#define O_ACCMODE (_O_RDONLY | _O_WRONLY | _O_RDWR) + #include "compat/mingw.h" #endif diff --git a/compat/obstack.h b/compat/obstack.h index ced94d0118..ae36ed6a66 100644 --- a/compat/obstack.h +++ b/compat/obstack.h @@ -496,7 +496,7 @@ __extension__ \ ( (h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \ ((((h)->temp.tempint > 0 \ && (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \ - ? (int) ((h)->next_free = (h)->object_base \ + ? (ptrdiff_t) ((h)->next_free = (h)->object_base \ = (h)->temp.tempint + (char *) (h)->chunk) \ : (((obstack_free) ((h), (h)->temp.tempint + (char *) (h)->chunk), 0), 0))) diff --git a/compat/poll/poll.c b/compat/poll/poll.c index 4459408c7d..0e95dd493c 100644 --- a/compat/poll/poll.c +++ b/compat/poll/poll.c @@ -149,8 +149,8 @@ win32_compute_revents (HANDLE h, int *p_sought) case FILE_TYPE_PIPE: if (!once_only) { - NtQueryInformationFile = (PNtQueryInformationFile) - GetProcAddress (GetModuleHandle ("ntdll.dll"), + NtQueryInformationFile = (PNtQueryInformationFile)(void (*)(void)) + GetProcAddress (GetModuleHandleW (L"ntdll.dll"), "NtQueryInformationFile"); once_only = TRUE; } diff --git a/compat/vcbuild/.gitignore b/compat/vcbuild/.gitignore new file mode 100644 index 0000000000..8f8b794ef3 --- /dev/null +++ b/compat/vcbuild/.gitignore @@ -0,0 +1,3 @@ +/vcpkg/ +/MSVC-DEFS-GEN +/VCPKG-DEFS diff --git a/compat/vcbuild/README b/compat/vcbuild/README index 60fd873fe8..b633e7db98 100644 --- a/compat/vcbuild/README +++ b/compat/vcbuild/README @@ -1,3 +1,42 @@ +The Steps to Build Git with VS2015 or VS2017 from the command line. + +1. Install the "vcpkg" open source package manager and build essential + third-party libraries. The steps for this have been captured in a + set of convenience scripts. These can be run from a stock Command + Prompt or from an SDK bash window: + + $ cd <repo_root> + $ ./compat/vcbuild/vcpkg_install.bat + + The vcpkg tools and all of the third-party sources will be installed + in this folder: + <repo_root>/compat/vcbuild/vcpkg/ + + A file will be created with a set of Makefile macros pointing to a + unified "include", "lib", and "bin" directory (release and debug) for + all of the required packages. This file will be included by the main + Makefile: + <repo_root>/compat/vcbuild/MSVC-DEFS-GEN + +2. OPTIONALLY copy the third-party *.dll and *.pdb files into the repo + root to make it easier to run and debug git.exe without having to + manipulate your PATH. This is especially true for debug sessions in + Visual Studio. + + Use ONE of the following forms which should match how you want to + compile git.exe. + + $ ./compat/vcbuild/vcpkg_copy_packages.bat debug + $ ./compat/vcbuild/vcpkg_copy_packages.bat release + +3. Build git using MSVC from an SDK bash window using one of the + following commands: + + $ make MSVC=1 + $ make MSVC=1 DEBUG=1 + +================================================================ + The Steps of Build Git with VS2008 1. You need the build environment, which contains the Git dependencies diff --git a/compat/vcbuild/find_vs_env.bat b/compat/vcbuild/find_vs_env.bat new file mode 100644 index 0000000000..40194dd230 --- /dev/null +++ b/compat/vcbuild/find_vs_env.bat @@ -0,0 +1,168 @@ +@ECHO OFF +REM ================================================================ +REM You can use either GCC (the default) or MSVC to build git +REM using the GIT-SDK command line tools. +REM $ make +REM $ make MSVC=1 +REM +REM GIT-SDK BASH windows inherit environment variables with all of +REM the bin/lib/include paths for GCC. It DOES NOT inherit values +REM for the corresponding MSVC tools. +REM +REM During normal (non-git) Windows development, you launch one +REM of the provided "developer command prompts" to set environment +REM variables for the MSVC tools. +REM +REM Therefore, to allow MSVC command line builds of git from BASH +REM and MAKE, we must blend these two different worlds. This script +REM attempts to do that. +REM ================================================================ +REM This BAT file starts in a plain (non-developer) command prompt, +REM searches for the "best" commmand prompt setup script, installs +REM it into the current CMD process, and exports the various MSVC +REM environment variables for use by MAKE. +REM +REM The output of this script should be written to a make "include +REM file" and referenced by the top-level Makefile. +REM +REM See "config.mak.uname" (look for compat/vcbuild/MSVC-DEFS-GEN). +REM ================================================================ +REM The provided command prompts are custom to each VS release and +REM filled with lots of internal knowledge (such as Registry settings); +REM even their names vary by release, so it is not appropriate for us +REM to look inside them. Rather, just run them in a subordinate +REM process and extract the settings we need. +REM ================================================================ +REM +REM Current (VS2017 and beyond) +REM ------------------- +REM Visual Studio 2017 introduced a new installation layout and +REM support for side-by-side installation of multiple versions of +REM VS2017. Furthermore, these can all coexist with installations +REM of previous versions of VS (which have a completely different +REM layout on disk). +REM +REM VS2017 Update 2 introduced a "vswhere.exe" command: +REM https://github.com/Microsoft/vswhere +REM https://blogs.msdn.microsoft.com/heaths/2017/02/25/vswhere-available/ +REM https://blogs.msdn.microsoft.com/vcblog/2017/03/06/finding-the-visual-c-compiler-tools-in-visual-studio-2017/ +REM +REM VS2015 +REM ------ +REM Visual Studio 2015 uses the traditional VcVarsAll. +REM +REM Earlier Versions +REM ---------------- +REM Currently unsupported. +REM +REM ================================================================ +REM Note: Throughout this script we use "dir <path> && <cmd>" rather +REM than "if exist <path>" because of script problems with pathnames +REM containing spaces. +REM ================================================================ + +REM Sanitize PATH to prevent git-sdk paths from confusing "wmic.exe" +REM (called internally in some of the system BAT files). +SET PATH=%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem; + +REM ================================================================ + +:current + SET vs_where=C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe + dir "%vs_where%" >nul 2>nul && GOTO have_vs_where + GOTO not_2017 + +:have_vs_where + REM Try to use VsWhere to get the location of VsDevCmd. + + REM Keep VsDevCmd from cd'ing away. + SET VSCMD_START_DIR=. + + REM Get the root of the VS product installation. + FOR /F "usebackq tokens=*" %%i IN (`"%vs_where%" -latest -requires Microsoft.VisualStudio.Workload.NativeDesktop -property installationPath`) DO @SET vs_ip=%%i + + SET vs_devcmd=%vs_ip%\Common7\Tools\VsDevCmd.bat + dir "%vs_devcmd%" >nul 2>nul && GOTO have_vs_devcmd + GOTO not_2017 + +:have_vs_devcmd + REM Use VsDevCmd to setup the environment of this process. + REM Setup CL for building 64-bit apps using 64-bit tools. + @call "%vs_devcmd%" -no_logo -arch=x64 -host_arch=x64 + + SET tgt=%VSCMD_ARG_TGT_ARCH% + + SET mn=%VCToolsInstallDir% + SET msvc_includes=-I"%mn%INCLUDE" + SET msvc_libs=-L"%mn%lib\%tgt%" + SET msvc_bin_dir=%mn%bin\Host%VSCMD_ARG_HOST_ARCH%\%tgt% + + SET sdk_dir=%WindowsSdkDir% + SET sdk_ver=%WindowsSDKVersion% + SET si=%sdk_dir%Include\%sdk_ver% + SET sdk_includes=-I"%si%ucrt" -I"%si%um" -I"%si%shared" + SET sl=%sdk_dir%lib\%sdk_ver% + SET sdk_libs=-L"%sl%ucrt\%tgt%" -L"%sl%um\%tgt%" + + SET vs_ver=%VisualStudioVersion% + + GOTO print_vars + +REM ================================================================ + +:not_2017 + REM See if VS2015 is installed. + + SET vs_2015_bat=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat + dir "%vs_2015_bat%" >nul 2>nul && GOTO have_vs_2015 + GOTO not_2015 + +:have_vs_2015 + REM Use VcVarsAll like the "x64 Native" command prompt. + REM Setup CL for building 64-bit apps using 64-bit tools. + @call "%vs_2015_bat%" amd64 + + REM Note that in VS2015 they use "x64" in some contexts and "amd64" in others. + SET mn=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\ + SET msvc_includes=-I"%mn%INCLUDE" + SET msvc_libs=-L"%mn%lib\amd64" + SET msvc_bin_dir=%mn%bin\amd64 + + SET sdk_dir=%WindowsSdkDir% + SET sdk_ver=%WindowsSDKVersion% + SET si=%sdk_dir%Include\%sdk_ver% + SET sdk_includes=-I"%si%ucrt" -I"%si%um" -I"%si%shared" -I"%si%winrt" + SET sl=%sdk_dir%lib\%sdk_ver% + SET sdk_libs=-L"%sl%ucrt\x64" -L"%sl%um\x64" + + SET vs_ver=%VisualStudioVersion% + + GOTO print_vars + +REM ================================================================ + +:not_2015 + echo "ERROR: unsupported VS version (older than VS2015)" >&2 + EXIT /B 1 + +REM ================================================================ + +:print_vars + REM Dump the essential vars to stdout to allow the main + REM Makefile to include it. See config.mak.uname. + REM Include DOS-style and BASH-style path for bin dir. + + echo msvc_bin_dir=%msvc_bin_dir% + SET X1=%msvc_bin_dir:C:=/C% + SET X2=%X1:\=/% + echo msvc_bin_dir_msys=%X2% + + echo msvc_includes=%msvc_includes% + echo msvc_libs=%msvc_libs% + + echo sdk_includes=%sdk_includes% + echo sdk_libs=%sdk_libs% + + echo vs_ver=%vs_ver% + + EXIT /B 0 diff --git a/compat/vcbuild/scripts/clink.pl b/compat/vcbuild/scripts/clink.pl index a87d0da512..c7b021bfac 100755 --- a/compat/vcbuild/scripts/clink.pl +++ b/compat/vcbuild/scripts/clink.pl @@ -12,32 +12,62 @@ use strict; my @args = (); my @cflags = (); +my @lflags = (); my $is_linking = 0; +my $is_debug = 0; while (@ARGV) { my $arg = shift @ARGV; - if ("$arg" =~ /^-[DIMGO]/) { + if ("$arg" eq "-DDEBUG") { + # Some vcpkg-based libraries have different names for release + # and debug versions. This hack assumes that -DDEBUG comes + # before any "-l*" flags. + $is_debug = 1; + } + if ("$arg" =~ /^-[DIMGOZ]/) { push(@cflags, $arg); } elsif ("$arg" eq "-o") { my $file_out = shift @ARGV; if ("$file_out" =~ /exe$/) { $is_linking = 1; + # Create foo.exe and foo.pdb push(@args, "-OUT:$file_out"); } else { + # Create foo.o and foo.o.pdb push(@args, "-Fo$file_out"); + push(@args, "-Fd$file_out.pdb"); } } elsif ("$arg" eq "-lz") { + if ($is_debug) { + push(@args, "zlibd.lib"); + } else{ push(@args, "zlib.lib"); + } } elsif ("$arg" eq "-liconv") { - push(@args, "iconv.lib"); + push(@args, "libiconv.lib"); } elsif ("$arg" eq "-lcrypto") { push(@args, "libeay32.lib"); } elsif ("$arg" eq "-lssl") { push(@args, "ssleay32.lib"); } elsif ("$arg" eq "-lcurl") { - push(@args, "libcurl.lib"); + my $lib = ""; + # Newer vcpkg definitions call this libcurl_imp.lib; Do we + # need to use that instead? + foreach my $flag (@lflags) { + if ($flag =~ /^-LIBPATH:(.*)/) { + foreach my $l ("libcurl_imp.lib", "libcurl.lib") { + if (-f "$1/$l") { + $lib = $l; + last; + } + } + } + } + push(@args, $lib); + } elsif ("$arg" eq "-lexpat") { + push(@args, "expat.lib"); } elsif ("$arg" =~ /^-L/ && "$arg" ne "-LTCG") { $arg =~ s/^-L/-LIBPATH:/; - push(@args, $arg); + push(@lflags, $arg); } elsif ("$arg" =~ /^-R/) { # eat } else { @@ -45,10 +75,11 @@ while (@ARGV) { } } if ($is_linking) { + push(@args, @lflags); unshift(@args, "link.exe"); } else { unshift(@args, "cl.exe"); push(@args, @cflags); } -#printf("**** @args\n"); +printf(STDERR "**** @args\n\n\n") if (!defined($ENV{'QUIET_GEN'})); exit (system(@args) != 0); diff --git a/compat/vcbuild/vcpkg_copy_dlls.bat b/compat/vcbuild/vcpkg_copy_dlls.bat new file mode 100644 index 0000000000..13661c14f8 --- /dev/null +++ b/compat/vcbuild/vcpkg_copy_dlls.bat @@ -0,0 +1,39 @@ +@ECHO OFF +REM ================================================================ +REM This script is an optional step. It copies the *.dll and *.pdb +REM files (created by vcpkg_install.bat) into the top-level directory +REM of the repo so that you can type "./git.exe" and find them without +REM having to fixup your PATH. +REM +REM NOTE: Because the names of some DLL files change between DEBUG and +REM NOTE: RELEASE builds when built using "vcpkg.exe", you will need +REM NOTE: to copy up the corresponding version. +REM ================================================================ + + SETLOCAL EnableDelayedExpansion + + @FOR /F "delims=" %%D IN ("%~dp0") DO @SET cwd=%%~fD + cd %cwd% + + SET arch=x64-windows + SET inst=%cwd%vcpkg\installed\%arch% + + IF [%1]==[release] ( + echo Copying RELEASE mode DLLs to repo root... + ) ELSE IF [%1]==[debug] ( + SET inst=%inst%\debug + echo Copying DEBUG mode DLLs to repo root... + ) ELSE ( + echo ERROR: Invalid argument. + echo Usage: %~0 release + echo Usage: %~0 debug + EXIT /B 1 + ) + + xcopy /e/s/v/y %inst%\bin\*.dll ..\..\ + xcopy /e/s/v/y %inst%\bin\*.pdb ..\..\ + + xcopy /e/s/v/y %inst%\bin\*.dll ..\..\t\helper\ + xcopy /e/s/v/y %inst%\bin\*.pdb ..\..\t\helper\ + + EXIT /B 0 diff --git a/compat/vcbuild/vcpkg_install.bat b/compat/vcbuild/vcpkg_install.bat new file mode 100644 index 0000000000..ebd0bad242 --- /dev/null +++ b/compat/vcbuild/vcpkg_install.bat @@ -0,0 +1,80 @@ +@ECHO OFF +REM ================================================================ +REM This script installs the "vcpkg" source package manager and uses +REM it to build the third-party libraries that git requires when it +REM is built using MSVC. +REM +REM [1] Install VCPKG. +REM [a] Create <root>/compat/vcbuild/vcpkg/ +REM [b] Download "vcpkg". +REM [c] Compile using the currently installed version of VS. +REM [d] Create <root>/compat/vcbuild/vcpkg/vcpkg.exe +REM +REM [2] Install third-party libraries. +REM [a] Download each (which may also install CMAKE). +REM [b] Compile in RELEASE mode and install in: +REM vcpkg/installed/<arch>/{bin,lib} +REM [c] Compile in DEBUG mode and install in: +REM vcpkg/installed/<arch>/debug/{bin,lib} +REM [d] Install headers in: +REM vcpkg/installed/<arch>/include +REM +REM [3] Create a set of MAKE definitions for the top-level +REM Makefile to allow "make MSVC=1" to find the above +REM third-party libraries. +REM [a] Write vcpkg/VCPGK-DEFS +REM +REM https://blogs.msdn.microsoft.com/vcblog/2016/09/19/vcpkg-a-tool-to-acquire-and-build-c-open-source-libraries-on-windows/ +REM https://github.com/Microsoft/vcpkg +REM https://vcpkg.readthedocs.io/en/latest/ +REM ================================================================ + + SETLOCAL EnableDelayedExpansion + + @FOR /F "delims=" %%D IN ("%~dp0") DO @SET cwd=%%~fD + cd %cwd% + + dir vcpkg\vcpkg.exe >nul 2>nul && GOTO :install_libraries + + echo Fetching vcpkg in %cwd%vcpkg + git.exe clone https://github.com/Microsoft/vcpkg vcpkg + IF ERRORLEVEL 1 ( EXIT /B 1 ) + + cd vcpkg + echo Building vcpkg + powershell -exec bypass scripts\bootstrap.ps1 + IF ERRORLEVEL 1 ( EXIT /B 1 ) + + echo Successfully installed %cwd%vcpkg\vcpkg.exe + +:install_libraries + SET arch=x64-windows + + echo Installing third-party libraries... + FOR %%i IN (zlib expat libiconv openssl libssh2 curl) DO ( + cd %cwd%vcpkg + IF NOT EXIST "packages\%%i_%arch%" CALL :sub__install_one %%i + IF ERRORLEVEL 1 ( EXIT /B 1 ) + ) + +:install_defines + cd %cwd% + SET inst=%cwd%vcpkg\installed\%arch% + + echo vcpkg_inc=-I"%inst%\include">VCPKG-DEFS + echo vcpkg_rel_lib=-L"%inst%\lib">>VCPKG-DEFS + echo vcpkg_rel_bin="%inst%\bin">>VCPKG-DEFS + echo vcpkg_dbg_lib=-L"%inst%\debug\lib">>VCPKG-DEFS + echo vcpkg_dbg_bin="%inst%\debug\bin">>VCPKG-DEFS + + EXIT /B 0 + + +:sub__install_one + echo Installing package %1... + + .\vcpkg.exe install %1:%arch% + IF ERRORLEVEL 1 ( EXIT /B 1 ) + + echo Finished %1 + goto :EOF diff --git a/compat/win32/git.manifest b/compat/win32/git.manifest new file mode 100644 index 0000000000..771e3cce43 --- /dev/null +++ b/compat/win32/git.manifest @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <assemblyIdentity type="win32" name="Git" version="0.0.0.1" /> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level="asInvoker" uiAccess="false" /> + </requestedPrivileges> + </security> + </trustInfo> + <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> + <application> + <!-- Windows Vista --> + <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> + <!-- Windows 7 --> + <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> + <!-- Windows 8 --> + <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> + <!-- Windows 8.1 --> + <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> + <!-- Windows 10 --> + <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> + </application> + </compatibility> +</assembly> diff --git a/compat/winansi.c b/compat/winansi.c index f4f08237f9..cacd82c833 100644 --- a/compat/winansi.c +++ b/compat/winansi.c @@ -7,6 +7,7 @@ #include <wingdi.h> #include <winreg.h> #include "win32.h" +#include "win32/lazyload.h" static int fd_is_interactive[3] = { 0, 0, 0 }; #define FD_CONSOLE 0x1 @@ -41,26 +42,21 @@ typedef struct _CONSOLE_FONT_INFOEX { #endif #endif -typedef BOOL (WINAPI *PGETCURRENTCONSOLEFONTEX)(HANDLE, BOOL, - PCONSOLE_FONT_INFOEX); - static void warn_if_raster_font(void) { DWORD fontFamily = 0; - PGETCURRENTCONSOLEFONTEX pGetCurrentConsoleFontEx; + DECLARE_PROC_ADDR(kernel32.dll, BOOL, GetCurrentConsoleFontEx, + HANDLE, BOOL, PCONSOLE_FONT_INFOEX); /* don't bother if output was ascii only */ if (!non_ascii_used) return; /* GetCurrentConsoleFontEx is available since Vista */ - pGetCurrentConsoleFontEx = (PGETCURRENTCONSOLEFONTEX) GetProcAddress( - GetModuleHandle("kernel32.dll"), - "GetCurrentConsoleFontEx"); - if (pGetCurrentConsoleFontEx) { + if (INIT_PROC_ADDR(GetCurrentConsoleFontEx)) { CONSOLE_FONT_INFOEX cfi; cfi.cbSize = sizeof(cfi); - if (pGetCurrentConsoleFontEx(console, 0, &cfi)) + if (GetCurrentConsoleFontEx(console, 0, &cfi)) fontFamily = cfi.FontFamily; } else { /* pre-Vista: check default console font in registry */ @@ -544,7 +540,20 @@ static HANDLE swap_osfhnd(int fd, HANDLE new_handle) #ifdef DETECT_MSYS_TTY #include <winternl.h> + +#if defined(_MSC_VER) + +typedef struct _OBJECT_NAME_INFORMATION +{ + UNICODE_STRING Name; + WCHAR NameBuffer[0]; +} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; + +#define ObjectNameInformation 1 + +#else #include <ntstatus.h> +#endif static void detect_msys_tty(int fd) { @@ -599,7 +608,7 @@ int winansi_isatty(int fd) void winansi_init(void) { int con1, con2; - char name[32]; + wchar_t name[32]; /* check if either stdout or stderr is a console output screen buffer */ con1 = is_console(1); @@ -619,13 +628,15 @@ void winansi_init(void) } /* create a named pipe to communicate with the console thread */ - xsnprintf(name, sizeof(name), "\\\\.\\pipe\\winansi%lu", GetCurrentProcessId()); - hwrite = CreateNamedPipe(name, PIPE_ACCESS_OUTBOUND, + if (swprintf(name, ARRAY_SIZE(name) - 1, L"\\\\.\\pipe\\winansi%lu", + GetCurrentProcessId()) < 0) + die("Could not initialize winansi pipe name"); + hwrite = CreateNamedPipeW(name, PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE | PIPE_WAIT, 1, BUFFER_SIZE, 0, 0, NULL); if (hwrite == INVALID_HANDLE_VALUE) die_lasterr("CreateNamedPipe failed"); - hread = CreateFile(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + hread = CreateFileW(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (hread == INVALID_HANDLE_VALUE) die_lasterr("CreateFile for named pipe failed"); |