summaryrefslogtreecommitdiff
path: root/compat/vcbuild
diff options
context:
space:
mode:
Diffstat (limited to 'compat/vcbuild')
-rw-r--r--compat/vcbuild/.gitignore3
-rw-r--r--compat/vcbuild/README62
-rw-r--r--compat/vcbuild/find_vs_env.bat168
-rwxr-xr-xcompat/vcbuild/scripts/clink.pl89
-rw-r--r--compat/vcbuild/vcpkg_copy_dlls.bat39
-rw-r--r--compat/vcbuild/vcpkg_install.bat80
6 files changed, 435 insertions, 6 deletions
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..1b6dabf5a2 100644
--- a/compat/vcbuild/README
+++ b/compat/vcbuild/README
@@ -1,3 +1,65 @@
+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
+
+================================================================
+
+Alternatively, run `make vcxproj` and then load the generated `git.sln` in
+Visual Studio. The initial build will install the vcpkg system and build the
+dependencies automatically. This will take a while.
+
+Instead of generating the `git.sln` file yourself (which requires a full Git
+for Windows SDK), you may want to consider fetching the `vs/master` branch of
+https://github.com/git-for-windows/git instead (which is updated automatically
+via CI running `make vcxproj`). The `vs/master` branch does not require a Git
+for Windows to build, but you can run the test scripts in a regular Git Bash.
+
+Note that `make vcxproj` will automatically add and commit the generated `.sln`
+and `.vcxproj` files to the repo. This is necessary to allow building a
+fully-testable Git in Visual Studio, where a regular Git Bash can be used to
+run the test scripts (as opposed to a full Git for Windows SDK): a number of
+build targets, such as Git commands implemented as Unix shell scripts (where
+`@@SHELL_PATH@@` and other placeholders are interpolated) require a full-blown
+Git for Windows SDK (which is about 10x the size of a regular Git for Windows
+installation).
+
+If your plan is to open a Pull Request with Git for Windows, it is a good idea
+to drop this commit before submitting.
+
+================================================================
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..b35d264c0e
--- /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" command 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..ec95a3b2d0 100755
--- a/compat/vcbuild/scripts/clink.pl
+++ b/compat/vcbuild/scripts/clink.pl
@@ -12,43 +12,120 @@
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);
- } elsif ("$arg" =~ /^-R/) {
+ push(@lflags, $arg);
+ } elsif ("$arg" =~ /^-[Rl]/) {
# eat
+ } elsif ("$arg" eq "-Werror") {
+ push(@cflags, "-WX");
+ } elsif ("$arg" eq "-Wall") {
+ # cl.exe understands -Wall, but it is really overzealous
+ push(@cflags, "-W4");
+ # disable the "signed/unsigned mismatch" warnings; our source code violates that
+ push(@cflags, "-wd4018");
+ push(@cflags, "-wd4245");
+ push(@cflags, "-wd4389");
+ # disable the "unreferenced formal parameter" warning; our source code violates that
+ push(@cflags, "-wd4100");
+ # disable the "conditional expression is constant" warning; our source code violates that
+ push(@cflags, "-wd4127");
+ # disable the "const object should be initialized" warning; these warnings affect only objects that are `static`
+ push(@cflags, "-wd4132");
+ # disable the "function/data pointer conversion in expression" warning; our source code violates that
+ push(@cflags, "-wd4152");
+ # disable the "non-constant aggregate initializer" warning; our source code violates that
+ push(@cflags, "-wd4204");
+ # disable the "cannot be initialized using address of automatic variable" warning; our source code violates that
+ push(@cflags, "-wd4221");
+ # disable the "possible loss of data" warnings; our source code violates that
+ push(@cflags, "-wd4244");
+ push(@cflags, "-wd4267");
+ # disable the "array is too small to include a terminating null character" warning; we ab-use strings to initialize OIDs
+ push(@cflags, "-wd4295");
+ # disable the "'<<': result of 32-bit shift implicitly converted to 64 bits" warning; our source code violates that
+ push(@cflags, "-wd4334");
+ # disable the "declaration hides previous local declaration" warning; our source code violates that
+ push(@cflags, "-wd4456");
+ # disable the "declaration hides function parameter" warning; our source code violates that
+ push(@cflags, "-wd4457");
+ # disable the "declaration hides global declaration" warning; our source code violates that
+ push(@cflags, "-wd4459");
+ # disable the "potentially uninitialized local variable '<name>' used" warning; our source code violates that
+ push(@cflags, "-wd4701");
+ # disable the "unreachable code" warning; our source code violates that
+ push(@cflags, "-wd4702");
+ # disable the "potentially uninitialized local pointer variable used" warning; our source code violates that
+ push(@cflags, "-wd4703");
+ # disable the "assignment within conditional expression" warning; our source code violates that
+ push(@cflags, "-wd4706");
+ # disable the "'inet_ntoa': Use inet_ntop() or InetNtop() instead" warning; our source code violates that
+ push(@cflags, "-wd4996");
+ } elsif ("$arg" =~ /^-W[a-z]/) {
+ # let's ignore those
} else {
push(@args, $arg);
}
}
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