From b704b8292abecd52df48c9c0b38b6deb52e1e9a4 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 29 Jul 2019 13:08:01 -0700 Subject: [PATCH 01/23] Vcproj.pm: auto-generate GUIDs We ran out GUIDs. Again. But there is no need to: we can generate them semi-randomly from the target file name of the project. Note: the Vcproj generator is probably only interesting for historical reasons; nevertheless, the upcoming Vcxproj generator (to support modern Visual Studio versions) is based on the Vcproj generator and it is better to fix this here first. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- contrib/buildsystems/Generators/Vcproj.pm | 66 ++++------------------- 1 file changed, 9 insertions(+), 57 deletions(-) diff --git a/contrib/buildsystems/Generators/Vcproj.pm b/contrib/buildsystems/Generators/Vcproj.pm index cfa74adcc2..c79b706bc8 100644 --- a/contrib/buildsystems/Generators/Vcproj.pm +++ b/contrib/buildsystems/Generators/Vcproj.pm @@ -3,6 +3,7 @@ require Exporter; use strict; use vars qw($VERSION); +use Digest::SHA qw(sha256_hex); our $VERSION = '1.00'; our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE); @@ -12,59 +13,12 @@ BEGIN { push @EXPORT_OK, qw(generate); } -my $guid_index = 0; -my @GUIDS = ( - "{E07B9989-2BF7-4F21-8918-BE22BA467AC3}", - "{278FFB51-0296-4A44-A81A-22B87B7C3592}", - "{7346A2C4-F0FD-444F-9EBE-1AF23B2B5650}", - "{67F421AC-EB34-4D49-820B-3196807B423F}", - "{385DCFE1-CC8C-4211-A451-80FCFC31CA51}", - "{97CC46C5-D2CC-4D26-B634-E75792B79916}", - "{C7CE21FE-6EF8-4012-A5C7-A22BCEDFBA11}", - "{51575134-3FDF-42D1-BABD-3FB12669C6C9}", - "{0AE195E4-9823-4B87-8E6F-20C5614AF2FF}", - "{4B918255-67CA-43BB-A46C-26704B666E6B}", - "{18CCFEEF-C8EE-4CC1-A265-26F95C9F4649}", - "{5D5D90FA-01B7-4973-AFE5-CA88C53AC197}", - "{1F054320-036D-49E1-B384-FB5DF0BC8AC0}", - "{7CED65EE-F2D9-4171-825B-C7D561FE5786}", - "{8D341679-0F07-4664-9A56-3BA0DE88B9BC}", - "{C189FEDC-2957-4BD7-9FA4-7622241EA145}", - "{66844203-1B9F-4C53-9274-164FFF95B847}", - "{E4FEA145-DECC-440D-AEEA-598CF381FD43}", - "{73300A8E-C8AC-41B0-B555-4F596B681BA7}", - "{873FDEB1-D01D-40BF-A1BF-8BBC58EC0F51}", - "{7922C8BE-76C5-4AC6-8BF7-885C0F93B782}", - "{E245D370-308B-4A49-BFC1-1E527827975F}", - "{F6FA957B-66FC-4ED7-B260-E59BBE4FE813}", - "{E6055070-0198-431A-BC49-8DB6CEE770AE}", - "{54159234-C3EB-43DA-906B-CE5DA5C74654}", - "{594CFC35-0B60-46F6-B8EF-9983ACC1187D}", - "{D93FCAB7-1F01-48D2-B832-F761B83231A5}", - "{DBA5E6AC-E7BE-42D3-8703-4E787141526E}", - "{6171953F-DD26-44C7-A3BE-CC45F86FC11F}", - "{9E19DDBE-F5E4-4A26-A2FE-0616E04879B8}", - "{AE81A615-99E3-4885-9CE0-D9CAA193E867}", - "{FBF4067E-1855-4F6C-8BCD-4D62E801A04D}", - "{17007948-6593-4AEB-8106-F7884B4F2C19}", - "{199D4C8D-8639-4DA6-82EF-08668C35DEE0}", - "{E085E50E-C140-4CF3-BE4B-094B14F0DDD6}", - "{00785268-A9CC-4E40-AC29-BAC0019159CE}", - "{4C06F56A-DCDB-46A6-B67C-02339935CF12}", - "{3A62D3FD-519E-4EC9-8171-D2C1BFEA022F}", - "{3A62D3FD-519E-4EC9-8171-D2C1BFEA022F}", - "{9392EB58-D7BA-410B-B1F0-B2FAA6BC89A7}", - "{2ACAB2D5-E0CE-4027-BCA0-D78B2D7A6C66}", - "{86E216C3-43CE-481A-BCB2-BE5E62850635}", - "{FB631291-7923-4B91-9A57-7B18FDBB7A42}", - "{0A176EC9-E934-45B8-B87F-16C7F4C80039}", - "{DF55CA80-46E8-4C53-B65B-4990A23DD444}", - "{3A0F9895-55D2-4710-BE5E-AD7498B5BF44}", - "{294BDC5A-F448-48B6-8110-DD0A81820F8C}", - "{4B9F66E9-FAC9-47AB-B1EF-C16756FBFD06}", - "{72EA49C6-2806-48BD-B81B-D4905102E19C}", - "{5728EB7E-8929-486C-8CD5-3238D060E768}" -); +sub generate_guid ($) { + my $hex = sha256_hex($_[0]); + $hex =~ s/^(.{8})(.{4})(.{4})(.{4})(.{12}).*/{$1-$2-$3-$4-$5}/; + $hex =~ tr/a-z/A-Z/; + return $hex; +} sub generate { my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_; @@ -92,9 +46,8 @@ sub createLibProject { $target =~ s/\//_/g; $target =~ s/\.a//; - my $uuid = $GUIDS[$guid_index]; + my $uuid = generate_guid($libname); $$build_structure{"LIBS_${target}_GUID"} = $uuid; - $guid_index += 1; my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"LIBS_${libname}_SOURCES"}})); my @sources; @@ -311,9 +264,8 @@ sub createAppProject { $target =~ s/\//_/g; $target =~ s/\.exe//; - my $uuid = $GUIDS[$guid_index]; + my $uuid = generate_guid($appname); $$build_structure{"APPS_${target}_GUID"} = $uuid; - $guid_index += 1; my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"APPS_${appname}_SOURCES"}})); my @sources; From 92e2f6e0533df466425c92f6ce7ae10df6d37a2d Mon Sep 17 00:00:00 2001 From: Philip Oakley Date: Mon, 29 Jul 2019 13:08:01 -0700 Subject: [PATCH 02/23] Vcproj.pm: list git.exe first to be startup project MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Visual Studio takes the first listed application/library as the default startup project [1]. Detect the 'git' project and place it at the head of the project list, rather than at the tail. Export the apps list before libs list for both the projects and global structures of the .sln file. [1] http://stackoverflow.com/questions/1238553/ vs2008-where-is-the-startup-project-setting-stored-for-a-solution "In the solution file, there are a list of pseudo-XML "Project" entries. It turns out that whatever is the first one ends up as the Startup Project, unless it’s overridden in the suo file. Argh. I just rearranged the order in the file and it’s good." "just moving the pseudo-xml isn't enough. You also have to move the group of entries in the "GlobalSection(ProjectConfigurationPlatforms) = postSolution" group that has the GUID of the project you moved to the top. So there are two places to move lines." Signed-off-by: Philip Oakley Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- contrib/buildsystems/Generators/Vcproj.pm | 33 +++++++++++++---------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/contrib/buildsystems/Generators/Vcproj.pm b/contrib/buildsystems/Generators/Vcproj.pm index c79b706bc8..d862cae503 100644 --- a/contrib/buildsystems/Generators/Vcproj.pm +++ b/contrib/buildsystems/Generators/Vcproj.pm @@ -513,20 +513,18 @@ sub createGlueProject { foreach (@apps) { $_ =~ s/\//_/g; $_ =~ s/\.exe//; - push(@tmp, $_); + if ($_ eq "git" ) { + unshift(@tmp, $_); + } else { + push(@tmp, $_); + } } @apps = @tmp; open F, ">git.sln" || die "Could not open git.sln for writing!\n"; binmode F, ":crlf"; print F "$SLN_HEAD"; - foreach (@libs) { - my $libname = $_; - my $uuid = $build_structure{"LIBS_${libname}_GUID"}; - print F "$SLN_PRE"; - print F "\"${libname}\", \"${libname}\\${libname}.vcproj\", \"${uuid}\""; - print F "$SLN_POST"; - } + my $uuid_libgit = $build_structure{"LIBS_libgit_GUID"}; my $uuid_xdiff_lib = $build_structure{"LIBS_xdiff_lib_GUID"}; foreach (@apps) { @@ -540,6 +538,13 @@ sub createGlueProject { print F " EndProjectSection"; print F "$SLN_POST"; } + foreach (@libs) { + my $libname = $_; + my $uuid = $build_structure{"LIBS_${libname}_GUID"}; + print F "$SLN_PRE"; + print F "\"${libname}\", \"${libname}\\${libname}.vcproj\", \"${uuid}\""; + print F "$SLN_POST"; + } print F << "EOM"; Global @@ -551,17 +556,17 @@ EOM print F << "EOM"; GlobalSection(ProjectConfigurationPlatforms) = postSolution EOM - foreach (@libs) { - my $libname = $_; - my $uuid = $build_structure{"LIBS_${libname}_GUID"}; + foreach (@apps) { + my $appname = $_; + my $uuid = $build_structure{"APPS_${appname}_GUID"}; print F "\t\t${uuid}.Debug|Win32.ActiveCfg = Debug|Win32\n"; print F "\t\t${uuid}.Debug|Win32.Build.0 = Debug|Win32\n"; print F "\t\t${uuid}.Release|Win32.ActiveCfg = Release|Win32\n"; print F "\t\t${uuid}.Release|Win32.Build.0 = Release|Win32\n"; } - foreach (@apps) { - my $appname = $_; - my $uuid = $build_structure{"APPS_${appname}_GUID"}; + foreach (@libs) { + my $libname = $_; + my $uuid = $build_structure{"LIBS_${libname}_GUID"}; print F "\t\t${uuid}.Debug|Win32.ActiveCfg = Debug|Win32\n"; print F "\t\t${uuid}.Debug|Win32.Build.0 = Debug|Win32\n"; print F "\t\t${uuid}.Release|Win32.ActiveCfg = Release|Win32\n"; From 905fa99e7a2c7f3cb4c74ec7ebaad88db9a58f8e Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 29 Jul 2019 13:08:02 -0700 Subject: [PATCH 03/23] Vcproj.pm: do not configure VCWebServiceProxyGeneratorTool It is not necessary, and Visual Studio 2015 no longer supports it, anyway. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- contrib/buildsystems/Generators/Vcproj.pm | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/contrib/buildsystems/Generators/Vcproj.pm b/contrib/buildsystems/Generators/Vcproj.pm index d862cae503..b17800184c 100644 --- a/contrib/buildsystems/Generators/Vcproj.pm +++ b/contrib/buildsystems/Generators/Vcproj.pm @@ -115,9 +115,6 @@ sub createLibProject { - @@ -181,9 +178,6 @@ sub createLibProject { - @@ -339,9 +333,6 @@ sub createAppProject { - @@ -410,9 +401,6 @@ sub createAppProject { - From 158471d155827e295266e3eb128dac47fca3d1e7 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 29 Jul 2019 13:08:03 -0700 Subject: [PATCH 04/23] Vcproj.pm: urlencode '<' and '>' when generating VC projects Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- contrib/buildsystems/Generators/Vcproj.pm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/contrib/buildsystems/Generators/Vcproj.pm b/contrib/buildsystems/Generators/Vcproj.pm index b17800184c..737647e76a 100644 --- a/contrib/buildsystems/Generators/Vcproj.pm +++ b/contrib/buildsystems/Generators/Vcproj.pm @@ -59,6 +59,8 @@ sub createLibProject { my $includes= join(";", sort(map(""$rel_dir\\$_"", @{$$build_structure{"LIBS_${libname}_INCLUDES"}}))); my $cflags = join(" ", sort(@{$$build_structure{"LIBS_${libname}_CFLAGS"}})); $cflags =~ s/\"/"/g; + $cflags =~ s//>/g; my $cflags_debug = $cflags; $cflags_debug =~ s/-MT/-MTd/; @@ -80,6 +82,8 @@ sub createLibProject { $defines =~ s/-D//g; $defines =~ s/\"/\\"/g; + $defines =~ s//>/g; $defines =~ s/\'//g; $includes =~ s/-I//g; mkdir "$target" || die "Could not create the directory $target for lib project!\n"; @@ -271,6 +275,8 @@ sub createAppProject { my $includes= join(";", sort(map(""$rel_dir\\$_"", @{$$build_structure{"APPS_${appname}_INCLUDES"}}))); my $cflags = join(" ", sort(@{$$build_structure{"APPS_${appname}_CFLAGS"}})); $cflags =~ s/\"/"/g; + $cflags =~ s//>/g; my $cflags_debug = $cflags; $cflags_debug =~ s/-MT/-MTd/; @@ -297,6 +303,8 @@ sub createAppProject { $defines =~ s/-D//g; $defines =~ s/\"/\\"/g; + $defines =~ s//>/g; $defines =~ s/\'//g; $defines =~ s/\\\\/\\/g; $includes =~ s/-I//g; From 865406bc5426d5196935e37a3a5fde9c843c3e96 Mon Sep 17 00:00:00 2001 From: Philip Oakley Date: Mon, 29 Jul 2019 13:08:03 -0700 Subject: [PATCH 05/23] contrib/buildsystems: ignore invalidcontinue.obj Since 4b623d8 (MSVC: link in invalidcontinue.obj for better POSIX compatibility, 2014-03-29), invalidcontinue.obj is linked in the MSVC build, but it was not parsed correctly by the buildsystem. Ignore it, as it is known to Visual Studio and will be handled elsewhere. Also only substitute filenames ending with .o when generating the source .c filename, otherwise we would start to expect .cbj files to generate .obj files (which are not generated by our build)... In the future there may be source files that produce .obj files so keep the two issues (.obj files with & without source files) separate. Signed-off-by: Philip Oakley Signed-off-by: Duncan Smart Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- contrib/buildsystems/engine.pl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl index 23da787dc5..53e65d4db7 100755 --- a/contrib/buildsystems/engine.pl +++ b/contrib/buildsystems/engine.pl @@ -282,7 +282,7 @@ sub handleLibLine # exit(1); foreach (@objfiles) { my $sourcefile = $_; - $sourcefile =~ s/\.o/.c/; + $sourcefile =~ s/\.o$/.c/; push(@sources, $sourcefile); push(@cflags, @{$compile_options{"${sourcefile}_CFLAGS"}}); push(@defines, @{$compile_options{"${sourcefile}_DEFINES"}}); @@ -326,8 +326,12 @@ sub handleLinkLine } elsif ($part =~ /\.(a|lib)$/) { $part =~ s/\.a$/.lib/; push(@libs, $part); - } elsif ($part =~ /\.(o|obj)$/) { + } elsif ($part eq 'invalidcontinue.obj') { + # ignore - known to MSVC + } elsif ($part =~ /\.o$/) { push(@objfiles, $part); + } elsif ($part =~ /\.obj$/) { + # do nothing, 'make' should not be producing .obj, only .o files } else { die "Unhandled lib option @ line $lineno: $part"; } @@ -336,7 +340,7 @@ sub handleLinkLine # exit(1); foreach (@objfiles) { my $sourcefile = $_; - $sourcefile =~ s/\.o/.c/; + $sourcefile =~ s/\.o$/.c/; push(@sources, $sourcefile); push(@cflags, @{$compile_options{"${sourcefile}_CFLAGS"}}); push(@defines, @{$compile_options{"${sourcefile}_DEFINES"}}); From e88919bfe285965bf99e3302a90187ba6f117be6 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 29 Jul 2019 13:08:04 -0700 Subject: [PATCH 06/23] contrib/buildsystems: ignore irrelevant files in Generators/ The Generators/ directory can contain spurious files such as editors' backup files. Even worse, there could be .swp files which are not even valid Perl scripts. Let's just ignore anything but .pm files in said directory. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- contrib/buildsystems/Generators.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/buildsystems/Generators.pm b/contrib/buildsystems/Generators.pm index 408ef714b8..aa4cbaa2ad 100644 --- a/contrib/buildsystems/Generators.pm +++ b/contrib/buildsystems/Generators.pm @@ -17,7 +17,7 @@ BEGIN { $me = dirname($me); if (opendir(D,"$me/Generators")) { foreach my $gen (readdir(D)) { - next if ($gen =~ /^\.\.?$/); + next unless ($gen =~ /\.pm$/); require "${me}/Generators/$gen"; $gen =~ s,\.pm,,; push(@AVAILABLE, $gen); From 90d5170cac9627d2a0bdd9660acb0477434eef42 Mon Sep 17 00:00:00 2001 From: Philip Oakley Date: Mon, 29 Jul 2019 13:08:05 -0700 Subject: [PATCH 07/23] contrib/buildsystems: fix misleading error message The error message talked about a "lib option", but it clearly referred to a link option. Signed-off-by: Philip Oakley Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- contrib/buildsystems/engine.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl index 53e65d4db7..11f0e16dda 100755 --- a/contrib/buildsystems/engine.pl +++ b/contrib/buildsystems/engine.pl @@ -333,7 +333,7 @@ sub handleLinkLine } elsif ($part =~ /\.obj$/) { # do nothing, 'make' should not be producing .obj, only .o files } else { - die "Unhandled lib option @ line $lineno: $part"; + die "Unhandled link option @ line $lineno: $part"; } } # print "AppOut: '$appout'\nLFlags: @lflags\nLibs : @libs\nOfiles: @objfiles\n"; From d8c07013b93496fff8e16b75560a22aa44da1625 Mon Sep 17 00:00:00 2001 From: Philip Oakley Date: Mon, 29 Jul 2019 13:08:05 -0700 Subject: [PATCH 08/23] contrib/buildsystems: handle quoted spaces in filenames The engine.pl script expects file names not to contain spaces. However, paths with spaces are quite prevalent on Windows. Use shellwords() rather than split() to parse them correctly. Helped-by: Junio C Hamano Signed-off-by: Philip Oakley Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- contrib/buildsystems/engine.pl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl index 11f0e16dda..ad6a82c30c 100755 --- a/contrib/buildsystems/engine.pl +++ b/contrib/buildsystems/engine.pl @@ -12,6 +12,7 @@ use File::Basename; use File::Spec; use Cwd; use Generators; +use Text::ParseWords; my (%build_structure, %compile_options, @makedry); my $out_dir = getcwd(); @@ -231,7 +232,7 @@ sub removeDuplicates sub handleCompileLine { my ($line, $lineno) = @_; - my @parts = split(' ', $line); + my @parts = shellwords($line); my $sourcefile; shift(@parts); # ignore cmd while (my $part = shift @parts) { @@ -265,7 +266,7 @@ sub handleLibLine my (@objfiles, @lflags, $libout, $part); # kill cmd and rm 'prefix' $line =~ s/^rm -f .* && .* rcs //; - my @parts = split(' ', $line); + my @parts = shellwords($line); while ($part = shift @parts) { if ($part =~ /^-/) { push(@lflags, $part); @@ -306,7 +307,7 @@ sub handleLinkLine { my ($line, $lineno) = @_; my (@objfiles, @lflags, @libs, $appout, $part); - my @parts = split(' ', $line); + my @parts = shellwords($line); shift(@parts); # ignore cmd while ($part = shift @parts) { if ($part =~ /^-IGNORE/) { From aae1713f14a48092f7fa9c10fdd3d1e4ba4e8367 Mon Sep 17 00:00:00 2001 From: Philip Oakley Date: Mon, 29 Jul 2019 13:08:06 -0700 Subject: [PATCH 09/23] contrib/buildsystems: ignore gettext stuff Git's build contains steps to handle internationalization. This caused hiccups in the parser used to generate QMake/Visual Studio project files. As those steps are irrelevant in this context, let's just ignore them. Signed-off-by: Philip Oakley Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- contrib/buildsystems/engine.pl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl index ad6a82c30c..9db3d43a1e 100755 --- a/contrib/buildsystems/engine.pl +++ b/contrib/buildsystems/engine.pl @@ -141,6 +141,12 @@ sub parseMakeOutput next; } + if ($text =~ /^(mkdir|msgfmt) /) { + # options to the Portable Object translations + # the line "mkdir ... && msgfmt ..." contains no linker options + next; + } + if($text =~ / -c /) { # compilation handleCompileLine($text, $line); From 03aa7118c3a11e96ba04c839e7378cc321ed2fbf Mon Sep 17 00:00:00 2001 From: Philip Oakley Date: Mon, 29 Jul 2019 13:08:07 -0700 Subject: [PATCH 10/23] contrib/buildsystems: redirect errors of the dry run into a log file Rather than swallowing the errors, it is better to have them in a file. To make it obvious what this is about, use the file name 'msvc-build-makedryerrors.txt'. Further, if the output is empty, simply delete that file. As we target Git for Windows' SDK (which, unlike its predecessor msysGit, offers Perl versions newer than 5.8), we can use the quite readable syntax `if -f -z $ErrsFile` (available in Perl >=5.10). Note that the file will contain the new values of the GIT_VERSION and GITGUI_VERSION if they were generated by the make file. They are omitted if the release is tagged and indentically defined in their respective GIT_VERSION_GEN file DEF_VER variables. Signed-off-by: Philip Oakley Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- contrib/buildsystems/engine.pl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl index 9db3d43a1e..de5c0b6b25 100755 --- a/contrib/buildsystems/engine.pl +++ b/contrib/buildsystems/engine.pl @@ -73,7 +73,12 @@ Running GNU Make to figure out build structure... EOM # Pipe a make --dry-run into a variable, if not already loaded from file -@makedry = `cd $git_dir && make -n MSVC=1 V=1 2>/dev/null` if !@makedry; +# Capture the make dry stderr to file for review (will be empty for a release build). + +my $ErrsFile = "msvc-build-makedryerrors.txt"; +@makedry = `make -C $git_dir -n MSVC=1 V=1 2>$ErrsFile` if !@makedry; +# test for an empty Errors file and remove it +unlink $ErrsFile if -f -z $ErrsFile; # Parse the make output into usable info parseMakeOutput(); From a530a59a6f6298622460805e28dfb2b49dd1cf11 Mon Sep 17 00:00:00 2001 From: Philip Oakley Date: Mon, 29 Jul 2019 13:08:07 -0700 Subject: [PATCH 11/23] contrib/buildsystems: optionally capture the dry-run in a file Add an option for capturing the output of the make dry-run used in determining the msvc-build structure for easy debugging. You can use the output of `--make-out ` in subsequent runs via the `--in ` option. Signed-off-by: Philip Oakley Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- contrib/buildsystems/engine.pl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl index de5c0b6b25..732239d817 100755 --- a/contrib/buildsystems/engine.pl +++ b/contrib/buildsystems/engine.pl @@ -32,6 +32,7 @@ generate usage: -g --gen Specify the buildsystem generator (default: $gen) Available: $genlist -o --out Specify output directory generation (default: .) + --make-out Write the output of GNU Make into a file -i --in Specify input file, instead of running GNU Make -h,-? --help This help EOM @@ -39,6 +40,7 @@ EOM } # Parse command-line options +my $make_out; while (@ARGV) { my $arg = shift @ARGV; if ("$arg" eq "-h" || "$arg" eq "--help" || "$arg" eq "-?") { @@ -46,6 +48,8 @@ while (@ARGV) { exit(0); } elsif("$arg" eq "--out" || "$arg" eq "-o") { $out_dir = shift @ARGV; + } elsif("$arg" eq "--make-out") { + $make_out = shift @ARGV; } elsif("$arg" eq "--gen" || "$arg" eq "-g") { $gen = shift @ARGV; } elsif("$arg" eq "--in" || "$arg" eq "-i") { @@ -80,6 +84,12 @@ my $ErrsFile = "msvc-build-makedryerrors.txt"; # test for an empty Errors file and remove it unlink $ErrsFile if -f -z $ErrsFile; +if (defined $make_out) { + open OUT, ">" . $make_out; + print OUT @makedry; + close OUT; +} + # Parse the make output into usable info parseMakeOutput(); From 66697467f8256bbc45e413fd2c5022898b0b01c0 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 29 Jul 2019 13:08:08 -0700 Subject: [PATCH 12/23] contrib/buildsystems: error out on unknown option One time too many did this developer call the `generate` script passing a `--make-out=` option that was happily ignored (because there should be a space, not an equal sign, between `--make-out` and the path). And one time too many, this script not only ignored it but did not even complain. Let's fix that. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- contrib/buildsystems/engine.pl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl index 732239d817..1a12f4d556 100755 --- a/contrib/buildsystems/engine.pl +++ b/contrib/buildsystems/engine.pl @@ -57,6 +57,8 @@ while (@ARGV) { open(F, "<$infile") || die "Couldn't open file $infile"; @makedry = ; close(F); + } else { + die "Unknown option: " . $arg; } } From 9103a75c584dd6edddfcb3004974a1bb48d9214c Mon Sep 17 00:00:00 2001 From: Philip Oakley Date: Mon, 29 Jul 2019 13:08:09 -0700 Subject: [PATCH 13/23] contrib/buildsystems: handle the curl library option Upon seeing the '-lcurl' option, point to the libcurl.lib. While there, fix the elsif indentation. Signed-off-by: Philip Oakley Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- contrib/buildsystems/engine.pl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl index 1a12f4d556..d613277595 100755 --- a/contrib/buildsystems/engine.pl +++ b/contrib/buildsystems/engine.pl @@ -341,10 +341,12 @@ sub handleLinkLine $appout = shift @parts; } elsif ("$part" eq "-lz") { push(@libs, "zlib.lib"); - } elsif ("$part" eq "-lcrypto") { + } elsif ("$part" eq "-lcrypto") { push(@libs, "libeay32.lib"); } elsif ("$part" eq "-lssl") { push(@libs, "ssleay32.lib"); + } elsif ("$part" eq "-lcurl") { + push(@libs, "libcurl.lib"); } elsif ($part =~ /^-/) { push(@lflags, $part); } elsif ($part =~ /\.(a|lib)$/) { From 1a537ecfbb9640744b6e8e523e13abf4e2641a3d Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 29 Jul 2019 13:08:10 -0700 Subject: [PATCH 14/23] contrib/buildsystems: handle libiconv, too Git's test suite shows tons of breakages unless Git is compiled *without* NO_ICONV. That means, in turn, that we need to generate build definitions *with* libiconv, which in turn implies that we have to handle the -liconv option properly. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- contrib/buildsystems/engine.pl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl index d613277595..c35844a0c7 100755 --- a/contrib/buildsystems/engine.pl +++ b/contrib/buildsystems/engine.pl @@ -347,6 +347,8 @@ sub handleLinkLine push(@libs, "ssleay32.lib"); } elsif ("$part" eq "-lcurl") { push(@libs, "libcurl.lib"); + } elsif ("$part" eq "-liconv") { + push(@libs, "libiconv.lib"); } elsif ($part =~ /^-/) { push(@lflags, $part); } elsif ($part =~ /\.(a|lib)$/) { From 6e500217f99ee6c3a314cb15766aa5dce99f55ca Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 29 Jul 2019 13:08:10 -0700 Subject: [PATCH 15/23] contrib/buildsystems: also handle -lexpat This is a dependency required for the non-smart HTTP backend. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- contrib/buildsystems/engine.pl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl index c35844a0c7..9bde7ae15b 100755 --- a/contrib/buildsystems/engine.pl +++ b/contrib/buildsystems/engine.pl @@ -347,6 +347,8 @@ sub handleLinkLine push(@libs, "ssleay32.lib"); } elsif ("$part" eq "-lcurl") { push(@libs, "libcurl.lib"); + } elsif ("$part" eq "-lexpat") { + push(@libs, "expat.lib"); } elsif ("$part" eq "-liconv") { push(@libs, "libiconv.lib"); } elsif ($part =~ /^-/) { From 4553f9de23f8d451bf801b566247bf987570626a Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 29 Jul 2019 13:08:11 -0700 Subject: [PATCH 16/23] contrib/buildsystems: handle options starting with a slash With the recent changes to allow building with MSVC=1, we now pass the /OPT:REF option to the compiler. This confuses the parser that wants to turn the output of a dry run into project definitions for QMake and Visual Studio: Unhandled link option @ line 213: /OPT:REF at [...] Let's just extend the code that passes through options that start with a dash, so that it passes through options that start with a slash, too. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- contrib/buildsystems/engine.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl index 9bde7ae15b..8bb07e8e25 100755 --- a/contrib/buildsystems/engine.pl +++ b/contrib/buildsystems/engine.pl @@ -351,7 +351,7 @@ sub handleLinkLine push(@libs, "expat.lib"); } elsif ("$part" eq "-liconv") { push(@libs, "libiconv.lib"); - } elsif ($part =~ /^-/) { + } elsif ($part =~ /^[-\/]/) { push(@lflags, $part); } elsif ($part =~ /\.(a|lib)$/) { $part =~ s/\.a$/.lib/; From 384a61bc6a8e6dc241d685acf4fb7b5a15003dbb Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 29 Jul 2019 13:08:12 -0700 Subject: [PATCH 17/23] contrib/buildsystems: add a backend for modern Visual Studio versions Based on the previous patches in this patch series that fixed the generator for `.vcproj` files (which were used by Visual Studio prior to 2015 to define projects), this patch offers to generate project definitions for neweer versions of Visual Studio (which use `.vcxproj` files). To that end, this patch copy-edits the generator of the `.vcproj`. In addition, we now use the `vcpkg` system which allows us to build Git's dependencies (e.g. curl, libexpat) conveniently. The support scripts were introduced in the `jh/msvc` patch series, and with this patch we initialize the `vcpkg` conditionally, in the `libgit` project's `PreBuildEvent`. To allow for parallel building of the projects, we therefore put `libgit` at the bottom of the project hierarchy. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- contrib/buildsystems/Generators/Vcxproj.pm | 385 +++++++++++++++++++++ 1 file changed, 385 insertions(+) create mode 100644 contrib/buildsystems/Generators/Vcxproj.pm diff --git a/contrib/buildsystems/Generators/Vcxproj.pm b/contrib/buildsystems/Generators/Vcxproj.pm new file mode 100644 index 0000000000..e65d78e16d --- /dev/null +++ b/contrib/buildsystems/Generators/Vcxproj.pm @@ -0,0 +1,385 @@ +package Generators::Vcxproj; +require Exporter; + +use strict; +use vars qw($VERSION); +use Digest::SHA qw(sha256_hex); + +our $VERSION = '1.00'; +our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE); +@ISA = qw(Exporter); + +BEGIN { + push @EXPORT_OK, qw(generate); +} + +sub generate_guid ($) { + my $hex = sha256_hex($_[0]); + $hex =~ s/^(.{8})(.{4})(.{4})(.{4})(.{12}).*/{$1-$2-$3-$4-$5}/; + $hex =~ tr/a-z/A-Z/; + return $hex; +} + +sub generate { + my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_; + my @libs = @{$build_structure{"LIBS"}}; + foreach (@libs) { + createProject($_, $git_dir, $out_dir, $rel_dir, \%build_structure, 1); + } + + my @apps = @{$build_structure{"APPS"}}; + foreach (@apps) { + createProject($_, $git_dir, $out_dir, $rel_dir, \%build_structure, 0); + } + + createGlueProject($git_dir, $out_dir, $rel_dir, %build_structure); + return 0; +} + +sub createProject { + my ($name, $git_dir, $out_dir, $rel_dir, $build_structure, $static_library) = @_; + my $label = $static_library ? "lib" : "app"; + my $prefix = $static_library ? "LIBS_" : "APPS_"; + my $config_type = $static_library ? "StaticLibrary" : "Application"; + print "Generate $name vcxproj $label project\n"; + my $cdup = $name; + $cdup =~ s/[^\/]+/../g; + $cdup =~ s/\//\\/g; + $rel_dir = $rel_dir eq "." ? $cdup : "$cdup\\$rel_dir"; + $rel_dir =~ s/\//\\/g; + + my $target = $name; + if ($static_library) { + $target =~ s/\.a//; + } else { + $target =~ s/\.exe//; + } + + my $uuid = generate_guid($name); + $$build_structure{"$prefix${target}_GUID"} = $uuid; + my $vcxproj = $target; + $vcxproj =~ s/(.*\/)?(.*)/$&\/$2.vcxproj/; + $vcxproj =~ s/([^\/]*)(\/lib)\/(lib.vcxproj)/$1$2\/$1_$3/; + $$build_structure{"$prefix${target}_VCXPROJ"} = $vcxproj; + + my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"$prefix${name}_SOURCES"}})); + my @sources; + foreach (@srcs) { + $_ =~ s/\//\\/g; + push(@sources, $_); + } + my $defines = join(";", sort(@{$$build_structure{"$prefix${name}_DEFINES"}})); + my $includes= join(";", sort(map { s/^-I//; s/\//\\/g; File::Spec->file_name_is_absolute($_) ? $_ : "$rel_dir\\$_" } @{$$build_structure{"$prefix${name}_INCLUDES"}})); + my $cflags = join(" ", sort(map { s/^-[GLMOWZ].*//; s/.* .*/"$&"/; $_; } @{$$build_structure{"$prefix${name}_CFLAGS"}})); + $cflags =~ s//>/g; + + my $libs_release = "\n "; + my $libs_debug = "\n "; + if (!$static_library) { + $libs_release = join(";", sort(grep /^(?!libgit\.lib|xdiff\/lib\.lib|vcs-svn\/lib\.lib)/, @{$$build_structure{"$prefix${name}_LIBS"}})); + $libs_debug = $libs_release; + $libs_debug =~ s/zlib\.lib/zlibd\.lib/; + } + + $defines =~ s/-D//g; + $defines =~ s//>/g; + $defines =~ s/\'//g; + + die "Could not create the directory $target for $label project!\n" unless (-d "$target" || mkdir "$target"); + + open F, ">$vcxproj" or die "Could not open $vcxproj for writing!\n"; + binmode F, ":crlf :utf8"; + print F chr(0xFEFF); + print F << "EOM"; + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + $uuid + Win32Proj + x86-windows + x64-windows + $cdup\\compat\\vcbuild\\vcpkg\\installed\\\$(VCPKGArch) + \$(VCPKGArchDirectory)\\debug\\bin + \$(VCPKGArchDirectory)\\debug\\lib + \$(VCPKGArchDirectory)\\bin + \$(VCPKGArchDirectory)\\lib + \$(VCPKGArchDirectory)\\include + $libs_debug + $libs_release + + + + true + true + + + false + true + + + $config_type + v140 + + ..\\ + + + + + + + + + + + + + false + true + + + + $cflags %(AdditionalOptions) + $cdup;$cdup\\compat;$cdup\\compat\\regex;$cdup\\compat\\win32;$cdup\\compat\\poll;$cdup\\compat\\vcbuild\\include;\$(VCPKGIncludeDirectory);%(AdditionalIncludeDirectories) + + OnlyExplicitInline + + ProgramDatabase + + + true + + + \$(VCPKGLibDirectory);%(AdditionalLibraryDirectories) + \$(VCPKGLibs);\$(AdditionalDependencies) + invalidcontinue.obj %(AdditionalOptions) + wmainCRTStartup + $cdup\\compat\\win32\\git.manifest + Console + +EOM + if ($target eq 'libgit') { + print F << "EOM"; + + Initialize VCPKG + del "$cdup\\compat\\vcbuild\\vcpkg" + call "$cdup\\compat\\vcbuild\\vcpkg_install.bat" + +EOM + } + print F << "EOM"; + + + + MachineX86 + + + + + Disabled + WIN32;_DEBUG;$defines;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + + + true + + + + + MaxSpeed + true + WIN32;NDEBUG;$defines;%(PreprocessorDefinitions) + MultiThreadedDLL + true + Speed + + + true + true + true + + + +EOM + foreach(@sources) { + print F << "EOM"; + +EOM + } + print F << "EOM"; + +EOM + if (!$static_library || $target =~ 'vcs-svn' || $target =~ 'xdiff') { + my $uuid_libgit = $$build_structure{"LIBS_libgit_GUID"}; + my $uuid_xdiff_lib = $$build_structure{"LIBS_xdiff/lib_GUID"}; + + print F << "EOM"; + + + $uuid_libgit + false + +EOM + if (!($name =~ 'xdiff')) { + print F << "EOM"; + + $uuid_xdiff_lib + false + +EOM + } + if ($name =~ /(test-(line-buffer|svn-fe)|^git-remote-testsvn)\.exe$/) { + my $uuid_vcs_svn_lib = $$build_structure{"LIBS_vcs-svn/lib_GUID"}; + print F << "EOM"; + + $uuid_vcs_svn_lib + false + +EOM + } + print F << "EOM"; + +EOM + } + print F << "EOM"; + +EOM + if (!$static_library) { + print F << "EOM"; + + + + + + + +EOM + } + print F << "EOM"; + +EOM + close F; +} + +sub createGlueProject { + my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_; + print "Generate solutions file\n"; + $rel_dir = "..\\$rel_dir"; + $rel_dir =~ s/\//\\/g; + my $SLN_HEAD = "Microsoft Visual Studio Solution File, Format Version 11.00\n# Visual Studio 2010\n"; + my $SLN_PRE = "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = "; + my $SLN_POST = "\nEndProject\n"; + + my @libs = @{$build_structure{"LIBS"}}; + my @tmp; + foreach (@libs) { + $_ =~ s/\.a//; + push(@tmp, $_); + } + @libs = @tmp; + + my @apps = @{$build_structure{"APPS"}}; + @tmp = (); + foreach (@apps) { + $_ =~ s/\.exe//; + if ($_ eq "git" ) { + unshift(@tmp, $_); + } else { + push(@tmp, $_); + } + } + @apps = @tmp; + + open F, ">git.sln" || die "Could not open git.sln for writing!\n"; + binmode F, ":crlf :utf8"; + print F chr(0xFEFF); + print F "$SLN_HEAD"; + + foreach (@apps) { + my $appname = $_; + my $uuid = $build_structure{"APPS_${appname}_GUID"}; + print F "$SLN_PRE"; + my $vcxproj = $build_structure{"APPS_${appname}_VCXPROJ"}; + $vcxproj =~ s/\//\\/g; + $appname =~ s/.*\///; + print F "\"${appname}\", \"${vcxproj}\", \"${uuid}\""; + print F "$SLN_POST"; + } + foreach (@libs) { + my $libname = $_; + my $uuid = $build_structure{"LIBS_${libname}_GUID"}; + print F "$SLN_PRE"; + my $vcxproj = $build_structure{"LIBS_${libname}_VCXPROJ"}; + $vcxproj =~ s/\//\\/g; + $libname =~ s/\//_/g; + print F "\"${libname}\", \"${vcxproj}\", \"${uuid}\""; + print F "$SLN_POST"; + } + + print F << "EOM"; +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection +EOM + print F << "EOM"; + GlobalSection(ProjectConfigurationPlatforms) = postSolution +EOM + foreach (@apps) { + my $appname = $_; + my $uuid = $build_structure{"APPS_${appname}_GUID"}; + print F "\t\t${uuid}.Debug|x64.ActiveCfg = Debug|x64\n"; + print F "\t\t${uuid}.Debug|x64.Build.0 = Debug|x64\n"; + print F "\t\t${uuid}.Debug|x86.ActiveCfg = Debug|Win32\n"; + print F "\t\t${uuid}.Debug|x86.Build.0 = Debug|Win32\n"; + print F "\t\t${uuid}.Release|x64.ActiveCfg = Release|x64\n"; + print F "\t\t${uuid}.Release|x64.Build.0 = Release|x64\n"; + print F "\t\t${uuid}.Release|x86.ActiveCfg = Release|Win32\n"; + print F "\t\t${uuid}.Release|x86.Build.0 = Release|Win32\n"; + } + foreach (@libs) { + my $libname = $_; + my $uuid = $build_structure{"LIBS_${libname}_GUID"}; + print F "\t\t${uuid}.Debug|x64.ActiveCfg = Debug|x64\n"; + print F "\t\t${uuid}.Debug|x64.Build.0 = Debug|x64\n"; + print F "\t\t${uuid}.Debug|x86.ActiveCfg = Debug|Win32\n"; + print F "\t\t${uuid}.Debug|x86.Build.0 = Debug|Win32\n"; + print F "\t\t${uuid}.Release|x64.ActiveCfg = Release|x64\n"; + print F "\t\t${uuid}.Release|x64.Build.0 = Release|x64\n"; + print F "\t\t${uuid}.Release|x86.ActiveCfg = Release|Win32\n"; + print F "\t\t${uuid}.Release|x86.Build.0 = Release|Win32\n"; + } + + print F << "EOM"; + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal +EOM + close F; +} + +1; From 976aaedca0c6f64b37f4241bf06fa7ab06095986 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 29 Jul 2019 13:08:12 -0700 Subject: [PATCH 18/23] msvc: add a Makefile target to pre-generate the Visual Studio solution The entire idea of generating the VS solution makes only sense if we generate it via Continuous Integration; otherwise potential users would still have to download the entire Git for Windows SDK. If we pre-generate the Visual Studio solution, Git can be built entirely within Visual Studio, and the test scripts can be run in a regular Git for Windows (e.g. the Portable Git flavor, which does not include a full GCC toolchain and therefore weighs only about a tenth of Git for Windows' SDK). So let's just add a target in the Makefile that can be used to generate said solution; The generated files will then be committed so that they can be pushed to a branch ready to check out by Visual Studio users. To make things even more useful, we also generate and commit other files that are required to run the test suite, such as templates and bin-wrappers: with this, developers can run the test suite in a regular Git Bash after building the solution in Visual Studio. Note: for this build target, we do not actually need to initialize the `vcpkg` system, so we don't. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- compat/vcbuild/README | 23 +++++++++++++ config.mak.uname | 61 ++++++++++++++++++++++++++++++++++ contrib/buildsystems/engine.pl | 3 +- 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/compat/vcbuild/README b/compat/vcbuild/README index b633e7db98..1b6dabf5a2 100644 --- a/compat/vcbuild/README +++ b/compat/vcbuild/README @@ -37,6 +37,29 @@ The Steps to Build Git with VS2015 or VS2017 from the command line. ================================================================ +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/config.mak.uname b/config.mak.uname index 48a6723222..6d0ed923b8 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -25,10 +25,12 @@ include compat/vcbuild/MSVC-DEFS-GEN # See if vcpkg and the vcpkg-build versions of the third-party # libraries that we use are installed. We include the result # to get $(vcpkg_*) variables defined for the Makefile. +ifeq (,$(SKIP_VCPKG)) compat/vcbuild/VCPKG-DEFS: compat/vcbuild/vcpkg_install.bat @"$<" include compat/vcbuild/VCPKG-DEFS endif +endif # We choose to avoid "if .. else if .. else .. endif endif" # because maintaining the nesting to match is a pain. If @@ -689,3 +691,62 @@ ifeq ($(uname_S),QNX) NO_STRCASESTR = YesPlease NO_STRLCPY = YesPlease endif + +vcxproj: + # Require clean work tree + git update-index -q --refresh && \ + git diff-files --quiet && \ + git diff-index --cached --quiet HEAD -- + + # Make .vcxproj files and add them + unset QUIET_GEN QUIET_BUILT_IN; \ + perl contrib/buildsystems/generate -g Vcxproj + git add -f git.sln {*,*/lib,t/helper/*}/*.vcxproj + + # Add command-list.h + $(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 command-list.h + git add -f command-list.h + + # Add scripts + rm -f perl/perl.mak + $(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 \ + $(SCRIPT_LIB) $(SCRIPT_SH_GEN) $(SCRIPT_PERL_GEN) + # Strip out the sane tool path, needed only for building + sed -i '/^git_broken_path_fix ".*/d' git-sh-setup + git add -f $(SCRIPT_LIB) $(SCRIPT_SH_GEN) $(SCRIPT_PERL_GEN) + + # Add Perl module + $(MAKE) $(LIB_PERL_GEN) + git add -f perl/build + + # Add bin-wrappers, for testing + rm -rf bin-wrappers/ + $(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 $(test_bindir_programs) + # Ensure that the GIT_EXEC_PATH is a Unix-y one, and that the absolute + # path of the repository is not hard-coded (GIT_EXEC_PATH will be set + # by test-lib.sh according to the current setup) + sed -i -e 's/^\(GIT_EXEC_PATH\)=.*/test -n "$${\1##*:*}" ||\ + \1="$$(cygpath -u "$$\1")"/' \ + -e "s|'$$(pwd)|\"\$$GIT_EXEC_PATH\"'|g" bin-wrappers/* + # Ensure that test-* helpers find the .dll files copied to top-level + sed -i 's|^PATH=.*|&:"$$GIT_EXEC_PATH"|' bin-wrappers/test-* + # We do not want to force hard-linking builtins + sed -i 's|\(git\)-\([-a-z]*\)\.exe"|\1.exe" \2|g' \ + bin-wrappers/git-{receive-pack,upload-archive} + git add -f $(test_bindir_programs) + # remote-ext is a builtin, but invoked as if it were external + sed 's|receive-pack|remote-ext|g' \ + bin-wrappers/git-remote-ext + git add -f bin-wrappers/git-remote-ext + + # Add templates + $(MAKE) -C templates + git add -f templates/boilerplates.made templates/blt/ + + # Add build options + $(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 GIT-BUILD-OPTIONS + git add -f GIT-BUILD-OPTIONS + + # Commit the whole shebang + git commit -m "Generate Visual Studio solution" \ + -m "Auto-generated by \`$(MAKE)$(MAKEFLAGS) $@\`" diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl index 8bb07e8e25..fba8a3f056 100755 --- a/contrib/buildsystems/engine.pl +++ b/contrib/buildsystems/engine.pl @@ -82,7 +82,8 @@ EOM # Capture the make dry stderr to file for review (will be empty for a release build). my $ErrsFile = "msvc-build-makedryerrors.txt"; -@makedry = `make -C $git_dir -n MSVC=1 V=1 2>$ErrsFile` if !@makedry; +@makedry = `make -C $git_dir -n MSVC=1 SKIP_VCPKG=1 V=1 2>$ErrsFile` +if !@makedry; # test for an empty Errors file and remove it unlink $ErrsFile if -f -z $ErrsFile; From b18ae14a8f6da9a04d0a6e4698d8ccea4afb546d Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 29 Jul 2019 13:08:13 -0700 Subject: [PATCH 19/23] vcxproj: also link-or-copy builtins The default location for `.exe` files linked by Visual Studio depends on the mode (debug vs release) and the architecture. Meaning: after a full build, there is a `git.exe` in the top-level directory, but none of the built-ins are linked.. When running a test script in Git Bash, it therefore would pick up the wrong, say, `git-receive-pack.exe`: the one installed at the same time as the Git Bash. Absolutely not what we want. We want to have confidence that our test covers the MSVC-built Git executables, and not some random stuff. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- config.mak.uname | 15 +++++++++++++++ contrib/buildsystems/Generators/Vcxproj.pm | 3 +++ 2 files changed, 18 insertions(+) diff --git a/config.mak.uname b/config.mak.uname index 6d0ed923b8..db7f06b95f 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -703,6 +703,21 @@ vcxproj: perl contrib/buildsystems/generate -g Vcxproj git add -f git.sln {*,*/lib,t/helper/*}/*.vcxproj + # Generate the LinkOrCopyBuiltins.targets file + (echo '' && \ + echo ' ' && \ + for name in $(BUILT_INS);\ + do \ + echo ' '; \ + done && \ + for name in $(REMOTE_CURL_ALIASES); \ + do \ + echo ' '; \ + done && \ + echo ' ' && \ + echo '') >git/LinkOrCopyBuiltins.targets + git add -f git/LinkOrCopyBuiltins.targets + # Add command-list.h $(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 command-list.h git add -f command-list.h diff --git a/contrib/buildsystems/Generators/Vcxproj.pm b/contrib/buildsystems/Generators/Vcxproj.pm index e65d78e16d..576ccabe1d 100644 --- a/contrib/buildsystems/Generators/Vcxproj.pm +++ b/contrib/buildsystems/Generators/Vcxproj.pm @@ -274,6 +274,9 @@ EOM EOM } + if ($target eq 'git') { + print F " \n"; + } print F << "EOM"; EOM From 516dfb84163ba5317eba0ad3103267986c9e4ae2 Mon Sep 17 00:00:00 2001 From: Philip Oakley Date: Mon, 29 Jul 2019 13:08:14 -0700 Subject: [PATCH 20/23] .gitignore: touch up the entries regarding Visual Studio Add the Microsoft .manifest pattern, and do not anchor the 'Debug' and 'Release' entries at the top-level directory, to allow for multiple projects (one per target). Signed-off-by: Philip Oakley Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- .gitignore | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index e096e0a51c..e7bb15d301 100644 --- a/.gitignore +++ b/.gitignore @@ -230,6 +230,7 @@ *.ipdb *.dll .vs/ -/Debug/ -/Release/ +*.manifest +Debug/ +Release/ *.dSYM From 2ceed19a9b6589450043659ffbcce46a990269e4 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 29 Jul 2019 13:08:15 -0700 Subject: [PATCH 21/23] .gitignore: ignore Visual Studio's temporary/generated files Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index e7bb15d301..fcfb708b9e 100644 --- a/.gitignore +++ b/.gitignore @@ -233,4 +233,7 @@ *.manifest Debug/ Release/ +/UpgradeLog*.htm +/git.VC.VC.opendb +/git.VC.db *.dSYM From 3a94cb31d52f061c315b00bfc005f1b1c42ac92d Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 29 Jul 2019 13:08:16 -0700 Subject: [PATCH 22/23] bin-wrappers: append `.exe` to target paths if necessary When compiling with Visual Studio, the projects' names are identical to the executables modulo the extensions. Read: there will exist both a directory called `git` as well as an executable called `git.exe` in the end. Which means that the bin-wrappers *need* to target the `.exe` files lest they try to execute directories. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 98a0588416..3716dadc08 100644 --- a/Makefile +++ b/Makefile @@ -2717,7 +2717,7 @@ bin-wrappers/%: wrap-for-bin.sh @mkdir -p bin-wrappers $(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ -e 's|@@BUILD_DIR@@|$(shell pwd)|' \ - -e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%,$(@F))|' < $< > $@ && \ + -e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%$(X),$(@F))$(patsubst git%,$(X),$(filter $(@F),$(BINDIR_PROGRAMS_NEED_X)))|' < $< > $@ && \ chmod +x $@ # GNU make supports exporting all variables by "export" without parameters. From b91408400757d021b10876c36280ef891b502420 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 29 Jul 2019 13:08:16 -0700 Subject: [PATCH 23/23] git: avoid calling aliased builtins via their dashed form This is one of the few places where Git violates its own deprecation of the dashed form. It is not necessary, either. As of 595d59e2b53 (git.c: ignore pager.* when launching builtin as dashed external, 2017-08-02), Git wants to ignore the pager.* config setting when expanding aliases. So let's strip out the check_pager_config() call from the copy-edited code. This code actually made it into upstream git.git already, but it was disabled in `#if 0 ... #endif` guards so far. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- git.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/git.c b/git.c index f4c0478f32..3049dae85b 100644 --- a/git.c +++ b/git.c @@ -743,8 +743,6 @@ static int run_argv(int *argcp, const char ***argv) */ if (!done_alias) handle_builtin(*argcp, *argv); - -#if 0 // TODO In GFW, need to amend a7924b655e940b06cb547c235d6bed9767929673 to include trace2_ and _tr2 lines. else if (get_builtin(**argv)) { struct argv_array args = ARGV_ARRAY_INIT; int i; @@ -779,7 +777,6 @@ static int run_argv(int *argcp, const char ***argv) exit(i); die("could not execute builtin %s", **argv); } -#endif // a7924b655e940b06cb547c235d6bed9767929673 /* .. then try the external ones */ execv_dashed_external(*argv);