Skip to content

Commit c62bc49

Browse files
committed
Merge branch 'js/visual-studio'
Support building Git with Visual Studio The bits about .git/branches/* have been dropped from the series. We may want to drop the support for it, but until that happens, the tests should rely on the existence of the support to pass. * js/visual-studio: (23 commits) git: avoid calling aliased builtins via their dashed form bin-wrappers: append `.exe` to target paths if necessary .gitignore: ignore Visual Studio's temporary/generated files .gitignore: touch up the entries regarding Visual Studio vcxproj: also link-or-copy builtins msvc: add a Makefile target to pre-generate the Visual Studio solution contrib/buildsystems: add a backend for modern Visual Studio versions contrib/buildsystems: handle options starting with a slash contrib/buildsystems: also handle -lexpat contrib/buildsystems: handle libiconv, too contrib/buildsystems: handle the curl library option contrib/buildsystems: error out on unknown option contrib/buildsystems: optionally capture the dry-run in a file contrib/buildsystems: redirect errors of the dry run into a log file contrib/buildsystems: ignore gettext stuff contrib/buildsystems: handle quoted spaces in filenames contrib/buildsystems: fix misleading error message contrib/buildsystems: ignore irrelevant files in Generators/ contrib/buildsystems: ignore invalidcontinue.obj Vcproj.pm: urlencode '<' and '>' when generating VC projects ...
2 parents 9b274e2 + b914084 commit c62bc49

File tree

9 files changed

+576
-100
lines changed

9 files changed

+576
-100
lines changed

.gitignore

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@
231231
*.ipdb
232232
*.dll
233233
.vs/
234-
/Debug/
235-
/Release/
234+
*.manifest
235+
Debug/
236+
Release/
237+
/UpgradeLog*.htm
238+
/git.VC.VC.opendb
239+
/git.VC.db
236240
*.dSYM

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2720,7 +2720,7 @@ bin-wrappers/%: wrap-for-bin.sh
27202720
@mkdir -p bin-wrappers
27212721
$(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
27222722
-e 's|@@BUILD_DIR@@|$(shell pwd)|' \
2723-
-e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%,$(@F))|' < $< > $@ && \
2723+
-e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%$(X),$(@F))$(patsubst git%,$(X),$(filter $(@F),$(BINDIR_PROGRAMS_NEED_X)))|' < $< > $@ && \
27242724
chmod +x $@
27252725

27262726
# GNU make supports exporting all variables by "export" without parameters.

compat/vcbuild/README

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,29 @@ The Steps to Build Git with VS2015 or VS2017 from the command line.
3737

3838
================================================================
3939

40+
Alternatively, run `make vcxproj` and then load the generated `git.sln` in
41+
Visual Studio. The initial build will install the vcpkg system and build the
42+
dependencies automatically. This will take a while.
43+
44+
Instead of generating the `git.sln` file yourself (which requires a full Git
45+
for Windows SDK), you may want to consider fetching the `vs/master` branch of
46+
https://github.com/git-for-windows/git instead (which is updated automatically
47+
via CI running `make vcxproj`). The `vs/master` branch does not require a Git
48+
for Windows to build, but you can run the test scripts in a regular Git Bash.
49+
50+
Note that `make vcxproj` will automatically add and commit the generated `.sln`
51+
and `.vcxproj` files to the repo. This is necessary to allow building a
52+
fully-testable Git in Visual Studio, where a regular Git Bash can be used to
53+
run the test scripts (as opposed to a full Git for Windows SDK): a number of
54+
build targets, such as Git commands implemented as Unix shell scripts (where
55+
`@@SHELL_PATH@@` and other placeholders are interpolated) require a full-blown
56+
Git for Windows SDK (which is about 10x the size of a regular Git for Windows
57+
installation).
58+
59+
If your plan is to open a Pull Request with Git for Windows, it is a good idea
60+
to drop this commit before submitting.
61+
62+
================================================================
4063
The Steps of Build Git with VS2008
4164

4265
1. You need the build environment, which contains the Git dependencies

config.mak.uname

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@ include compat/vcbuild/MSVC-DEFS-GEN
2525
# See if vcpkg and the vcpkg-build versions of the third-party
2626
# libraries that we use are installed. We include the result
2727
# to get $(vcpkg_*) variables defined for the Makefile.
28+
ifeq (,$(SKIP_VCPKG))
2829
compat/vcbuild/VCPKG-DEFS: compat/vcbuild/vcpkg_install.bat
2930
@"$<"
3031
include compat/vcbuild/VCPKG-DEFS
3132
endif
33+
endif
3234

3335
# We choose to avoid "if .. else if .. else .. endif endif"
3436
# because maintaining the nesting to match is a pain. If
@@ -689,3 +691,77 @@ ifeq ($(uname_S),QNX)
689691
NO_STRCASESTR = YesPlease
690692
NO_STRLCPY = YesPlease
691693
endif
694+
695+
vcxproj:
696+
# Require clean work tree
697+
git update-index -q --refresh && \
698+
git diff-files --quiet && \
699+
git diff-index --cached --quiet HEAD --
700+
701+
# Make .vcxproj files and add them
702+
unset QUIET_GEN QUIET_BUILT_IN; \
703+
perl contrib/buildsystems/generate -g Vcxproj
704+
git add -f git.sln {*,*/lib,t/helper/*}/*.vcxproj
705+
706+
# Generate the LinkOrCopyBuiltins.targets file
707+
(echo '<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">' && \
708+
echo ' <Target Name="CopyBuiltins_AfterBuild" AfterTargets="AfterBuild">' && \
709+
for name in $(BUILT_INS);\
710+
do \
711+
echo ' <Copy SourceFiles="$$(OutDir)\git.exe" DestinationFiles="$$(OutDir)\'"$$name"'" SkipUnchangedFiles="true" UseHardlinksIfPossible="true" />'; \
712+
done && \
713+
for name in $(REMOTE_CURL_ALIASES); \
714+
do \
715+
echo ' <Copy SourceFiles="$$(OutDir)\'"$(REMOTE_CURL_PRIMARY)"'" DestinationFiles="$$(OutDir)\'"$$name"'" SkipUnchangedFiles="true" UseHardlinksIfPossible="true" />'; \
716+
done && \
717+
echo ' </Target>' && \
718+
echo '</Project>') >git/LinkOrCopyBuiltins.targets
719+
git add -f git/LinkOrCopyBuiltins.targets
720+
721+
# Add command-list.h
722+
$(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 command-list.h
723+
git add -f command-list.h
724+
725+
# Add scripts
726+
rm -f perl/perl.mak
727+
$(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 \
728+
$(SCRIPT_LIB) $(SCRIPT_SH_GEN) $(SCRIPT_PERL_GEN)
729+
# Strip out the sane tool path, needed only for building
730+
sed -i '/^git_broken_path_fix ".*/d' git-sh-setup
731+
git add -f $(SCRIPT_LIB) $(SCRIPT_SH_GEN) $(SCRIPT_PERL_GEN)
732+
733+
# Add Perl module
734+
$(MAKE) $(LIB_PERL_GEN)
735+
git add -f perl/build
736+
737+
# Add bin-wrappers, for testing
738+
rm -rf bin-wrappers/
739+
$(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 $(test_bindir_programs)
740+
# Ensure that the GIT_EXEC_PATH is a Unix-y one, and that the absolute
741+
# path of the repository is not hard-coded (GIT_EXEC_PATH will be set
742+
# by test-lib.sh according to the current setup)
743+
sed -i -e 's/^\(GIT_EXEC_PATH\)=.*/test -n "$${\1##*:*}" ||\
744+
\1="$$(cygpath -u "$$\1")"/' \
745+
-e "s|'$$(pwd)|\"\$$GIT_EXEC_PATH\"'|g" bin-wrappers/*
746+
# Ensure that test-* helpers find the .dll files copied to top-level
747+
sed -i 's|^PATH=.*|&:"$$GIT_EXEC_PATH"|' bin-wrappers/test-*
748+
# We do not want to force hard-linking builtins
749+
sed -i 's|\(git\)-\([-a-z]*\)\.exe"|\1.exe" \2|g' \
750+
bin-wrappers/git-{receive-pack,upload-archive}
751+
git add -f $(test_bindir_programs)
752+
# remote-ext is a builtin, but invoked as if it were external
753+
sed 's|receive-pack|remote-ext|g' \
754+
<bin-wrappers/git-receive-pack >bin-wrappers/git-remote-ext
755+
git add -f bin-wrappers/git-remote-ext
756+
757+
# Add templates
758+
$(MAKE) -C templates
759+
git add -f templates/boilerplates.made templates/blt/
760+
761+
# Add build options
762+
$(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 GIT-BUILD-OPTIONS
763+
git add -f GIT-BUILD-OPTIONS
764+
765+
# Commit the whole shebang
766+
git commit -m "Generate Visual Studio solution" \
767+
-m "Auto-generated by \`$(MAKE)$(MAKEFLAGS) $@\`"

contrib/buildsystems/Generators.pm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ BEGIN {
1717
$me = dirname($me);
1818
if (opendir(D,"$me/Generators")) {
1919
foreach my $gen (readdir(D)) {
20-
next if ($gen =~ /^\.\.?$/);
20+
next unless ($gen =~ /\.pm$/);
2121
require "${me}/Generators/$gen";
2222
$gen =~ s,\.pm,,;
2323
push(@AVAILABLE, $gen);

contrib/buildsystems/Generators/Vcproj.pm

Lines changed: 36 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ require Exporter;
33

44
use strict;
55
use vars qw($VERSION);
6+
use Digest::SHA qw(sha256_hex);
67

78
our $VERSION = '1.00';
89
our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE);
@@ -12,59 +13,12 @@ BEGIN {
1213
push @EXPORT_OK, qw(generate);
1314
}
1415

15-
my $guid_index = 0;
16-
my @GUIDS = (
17-
"{E07B9989-2BF7-4F21-8918-BE22BA467AC3}",
18-
"{278FFB51-0296-4A44-A81A-22B87B7C3592}",
19-
"{7346A2C4-F0FD-444F-9EBE-1AF23B2B5650}",
20-
"{67F421AC-EB34-4D49-820B-3196807B423F}",
21-
"{385DCFE1-CC8C-4211-A451-80FCFC31CA51}",
22-
"{97CC46C5-D2CC-4D26-B634-E75792B79916}",
23-
"{C7CE21FE-6EF8-4012-A5C7-A22BCEDFBA11}",
24-
"{51575134-3FDF-42D1-BABD-3FB12669C6C9}",
25-
"{0AE195E4-9823-4B87-8E6F-20C5614AF2FF}",
26-
"{4B918255-67CA-43BB-A46C-26704B666E6B}",
27-
"{18CCFEEF-C8EE-4CC1-A265-26F95C9F4649}",
28-
"{5D5D90FA-01B7-4973-AFE5-CA88C53AC197}",
29-
"{1F054320-036D-49E1-B384-FB5DF0BC8AC0}",
30-
"{7CED65EE-F2D9-4171-825B-C7D561FE5786}",
31-
"{8D341679-0F07-4664-9A56-3BA0DE88B9BC}",
32-
"{C189FEDC-2957-4BD7-9FA4-7622241EA145}",
33-
"{66844203-1B9F-4C53-9274-164FFF95B847}",
34-
"{E4FEA145-DECC-440D-AEEA-598CF381FD43}",
35-
"{73300A8E-C8AC-41B0-B555-4F596B681BA7}",
36-
"{873FDEB1-D01D-40BF-A1BF-8BBC58EC0F51}",
37-
"{7922C8BE-76C5-4AC6-8BF7-885C0F93B782}",
38-
"{E245D370-308B-4A49-BFC1-1E527827975F}",
39-
"{F6FA957B-66FC-4ED7-B260-E59BBE4FE813}",
40-
"{E6055070-0198-431A-BC49-8DB6CEE770AE}",
41-
"{54159234-C3EB-43DA-906B-CE5DA5C74654}",
42-
"{594CFC35-0B60-46F6-B8EF-9983ACC1187D}",
43-
"{D93FCAB7-1F01-48D2-B832-F761B83231A5}",
44-
"{DBA5E6AC-E7BE-42D3-8703-4E787141526E}",
45-
"{6171953F-DD26-44C7-A3BE-CC45F86FC11F}",
46-
"{9E19DDBE-F5E4-4A26-A2FE-0616E04879B8}",
47-
"{AE81A615-99E3-4885-9CE0-D9CAA193E867}",
48-
"{FBF4067E-1855-4F6C-8BCD-4D62E801A04D}",
49-
"{17007948-6593-4AEB-8106-F7884B4F2C19}",
50-
"{199D4C8D-8639-4DA6-82EF-08668C35DEE0}",
51-
"{E085E50E-C140-4CF3-BE4B-094B14F0DDD6}",
52-
"{00785268-A9CC-4E40-AC29-BAC0019159CE}",
53-
"{4C06F56A-DCDB-46A6-B67C-02339935CF12}",
54-
"{3A62D3FD-519E-4EC9-8171-D2C1BFEA022F}",
55-
"{3A62D3FD-519E-4EC9-8171-D2C1BFEA022F}",
56-
"{9392EB58-D7BA-410B-B1F0-B2FAA6BC89A7}",
57-
"{2ACAB2D5-E0CE-4027-BCA0-D78B2D7A6C66}",
58-
"{86E216C3-43CE-481A-BCB2-BE5E62850635}",
59-
"{FB631291-7923-4B91-9A57-7B18FDBB7A42}",
60-
"{0A176EC9-E934-45B8-B87F-16C7F4C80039}",
61-
"{DF55CA80-46E8-4C53-B65B-4990A23DD444}",
62-
"{3A0F9895-55D2-4710-BE5E-AD7498B5BF44}",
63-
"{294BDC5A-F448-48B6-8110-DD0A81820F8C}",
64-
"{4B9F66E9-FAC9-47AB-B1EF-C16756FBFD06}",
65-
"{72EA49C6-2806-48BD-B81B-D4905102E19C}",
66-
"{5728EB7E-8929-486C-8CD5-3238D060E768}"
67-
);
16+
sub generate_guid ($) {
17+
my $hex = sha256_hex($_[0]);
18+
$hex =~ s/^(.{8})(.{4})(.{4})(.{4})(.{12}).*/{$1-$2-$3-$4-$5}/;
19+
$hex =~ tr/a-z/A-Z/;
20+
return $hex;
21+
}
6822

6923
sub generate {
7024
my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
@@ -92,9 +46,8 @@ sub createLibProject {
9246
$target =~ s/\//_/g;
9347
$target =~ s/\.a//;
9448

95-
my $uuid = $GUIDS[$guid_index];
49+
my $uuid = generate_guid($libname);
9650
$$build_structure{"LIBS_${target}_GUID"} = $uuid;
97-
$guid_index += 1;
9851

9952
my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"LIBS_${libname}_SOURCES"}}));
10053
my @sources;
@@ -106,6 +59,8 @@ sub createLibProject {
10659
my $includes= join(";", sort(map("&quot;$rel_dir\\$_&quot;", @{$$build_structure{"LIBS_${libname}_INCLUDES"}})));
10760
my $cflags = join(" ", sort(@{$$build_structure{"LIBS_${libname}_CFLAGS"}}));
10861
$cflags =~ s/\"/&quot;/g;
62+
$cflags =~ s/</&lt;/g;
63+
$cflags =~ s/>/&gt;/g;
10964

11065
my $cflags_debug = $cflags;
11166
$cflags_debug =~ s/-MT/-MTd/;
@@ -127,6 +82,8 @@ sub createLibProject {
12782

12883
$defines =~ s/-D//g;
12984
$defines =~ s/\"/\\&quot;/g;
85+
$defines =~ s/</&lt;/g;
86+
$defines =~ s/>/&gt;/g;
13087
$defines =~ s/\'//g;
13188
$includes =~ s/-I//g;
13289
mkdir "$target" || die "Could not create the directory $target for lib project!\n";
@@ -162,9 +119,6 @@ sub createLibProject {
162119
<Tool
163120
Name="VCXMLDataGeneratorTool"
164121
/>
165-
<Tool
166-
Name="VCWebServiceProxyGeneratorTool"
167-
/>
168122
<Tool
169123
Name="VCMIDLTool"
170124
/>
@@ -228,9 +182,6 @@ sub createLibProject {
228182
<Tool
229183
Name="VCXMLDataGeneratorTool"
230184
/>
231-
<Tool
232-
Name="VCWebServiceProxyGeneratorTool"
233-
/>
234185
<Tool
235186
Name="VCMIDLTool"
236187
/>
@@ -311,9 +262,8 @@ sub createAppProject {
311262
$target =~ s/\//_/g;
312263
$target =~ s/\.exe//;
313264

314-
my $uuid = $GUIDS[$guid_index];
265+
my $uuid = generate_guid($appname);
315266
$$build_structure{"APPS_${target}_GUID"} = $uuid;
316-
$guid_index += 1;
317267

318268
my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"APPS_${appname}_SOURCES"}}));
319269
my @sources;
@@ -325,6 +275,8 @@ sub createAppProject {
325275
my $includes= join(";", sort(map("&quot;$rel_dir\\$_&quot;", @{$$build_structure{"APPS_${appname}_INCLUDES"}})));
326276
my $cflags = join(" ", sort(@{$$build_structure{"APPS_${appname}_CFLAGS"}}));
327277
$cflags =~ s/\"/&quot;/g;
278+
$cflags =~ s/</&lt;/g;
279+
$cflags =~ s/>/&gt;/g;
328280

329281
my $cflags_debug = $cflags;
330282
$cflags_debug =~ s/-MT/-MTd/;
@@ -351,6 +303,8 @@ sub createAppProject {
351303

352304
$defines =~ s/-D//g;
353305
$defines =~ s/\"/\\&quot;/g;
306+
$defines =~ s/</&lt;/g;
307+
$defines =~ s/>/&gt;/g;
354308
$defines =~ s/\'//g;
355309
$defines =~ s/\\\\/\\/g;
356310
$includes =~ s/-I//g;
@@ -387,9 +341,6 @@ sub createAppProject {
387341
<Tool
388342
Name="VCXMLDataGeneratorTool"
389343
/>
390-
<Tool
391-
Name="VCWebServiceProxyGeneratorTool"
392-
/>
393344
<Tool
394345
Name="VCMIDLTool"
395346
/>
@@ -458,9 +409,6 @@ sub createAppProject {
458409
<Tool
459410
Name="VCXMLDataGeneratorTool"
460411
/>
461-
<Tool
462-
Name="VCWebServiceProxyGeneratorTool"
463-
/>
464412
<Tool
465413
Name="VCMIDLTool"
466414
/>
@@ -561,20 +509,18 @@ sub createGlueProject {
561509
foreach (@apps) {
562510
$_ =~ s/\//_/g;
563511
$_ =~ s/\.exe//;
564-
push(@tmp, $_);
512+
if ($_ eq "git" ) {
513+
unshift(@tmp, $_);
514+
} else {
515+
push(@tmp, $_);
516+
}
565517
}
566518
@apps = @tmp;
567519

568520
open F, ">git.sln" || die "Could not open git.sln for writing!\n";
569521
binmode F, ":crlf";
570522
print F "$SLN_HEAD";
571-
foreach (@libs) {
572-
my $libname = $_;
573-
my $uuid = $build_structure{"LIBS_${libname}_GUID"};
574-
print F "$SLN_PRE";
575-
print F "\"${libname}\", \"${libname}\\${libname}.vcproj\", \"${uuid}\"";
576-
print F "$SLN_POST";
577-
}
523+
578524
my $uuid_libgit = $build_structure{"LIBS_libgit_GUID"};
579525
my $uuid_xdiff_lib = $build_structure{"LIBS_xdiff_lib_GUID"};
580526
foreach (@apps) {
@@ -588,6 +534,13 @@ sub createGlueProject {
588534
print F " EndProjectSection";
589535
print F "$SLN_POST";
590536
}
537+
foreach (@libs) {
538+
my $libname = $_;
539+
my $uuid = $build_structure{"LIBS_${libname}_GUID"};
540+
print F "$SLN_PRE";
541+
print F "\"${libname}\", \"${libname}\\${libname}.vcproj\", \"${uuid}\"";
542+
print F "$SLN_POST";
543+
}
591544

592545
print F << "EOM";
593546
Global
@@ -599,17 +552,17 @@ EOM
599552
print F << "EOM";
600553
GlobalSection(ProjectConfigurationPlatforms) = postSolution
601554
EOM
602-
foreach (@libs) {
603-
my $libname = $_;
604-
my $uuid = $build_structure{"LIBS_${libname}_GUID"};
555+
foreach (@apps) {
556+
my $appname = $_;
557+
my $uuid = $build_structure{"APPS_${appname}_GUID"};
605558
print F "\t\t${uuid}.Debug|Win32.ActiveCfg = Debug|Win32\n";
606559
print F "\t\t${uuid}.Debug|Win32.Build.0 = Debug|Win32\n";
607560
print F "\t\t${uuid}.Release|Win32.ActiveCfg = Release|Win32\n";
608561
print F "\t\t${uuid}.Release|Win32.Build.0 = Release|Win32\n";
609562
}
610-
foreach (@apps) {
611-
my $appname = $_;
612-
my $uuid = $build_structure{"APPS_${appname}_GUID"};
563+
foreach (@libs) {
564+
my $libname = $_;
565+
my $uuid = $build_structure{"LIBS_${libname}_GUID"};
613566
print F "\t\t${uuid}.Debug|Win32.ActiveCfg = Debug|Win32\n";
614567
print F "\t\t${uuid}.Debug|Win32.Build.0 = Debug|Win32\n";
615568
print F "\t\t${uuid}.Release|Win32.ActiveCfg = Release|Win32\n";

0 commit comments

Comments
 (0)