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
  ...
This commit is contained in:
Junio C Hamano 2019-08-02 13:12:02 -07:00
commit c62bc49139
9 changed files with 576 additions and 100 deletions

8
.gitignore vendored
View File

@ -231,6 +231,10 @@
*.ipdb
*.dll
.vs/
/Debug/
/Release/
*.manifest
Debug/
Release/
/UpgradeLog*.htm
/git.VC.VC.opendb
/git.VC.db
*.dSYM

View File

@ -2720,7 +2720,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.

View File

@ -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

View File

@ -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,77 @@ 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
# Generate the LinkOrCopyBuiltins.targets file
(echo '<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">' && \
echo ' <Target Name="CopyBuiltins_AfterBuild" AfterTargets="AfterBuild">' && \
for name in $(BUILT_INS);\
do \
echo ' <Copy SourceFiles="$$(OutDir)\git.exe" DestinationFiles="$$(OutDir)\'"$$name"'" SkipUnchangedFiles="true" UseHardlinksIfPossible="true" />'; \
done && \
for name in $(REMOTE_CURL_ALIASES); \
do \
echo ' <Copy SourceFiles="$$(OutDir)\'"$(REMOTE_CURL_PRIMARY)"'" DestinationFiles="$$(OutDir)\'"$$name"'" SkipUnchangedFiles="true" UseHardlinksIfPossible="true" />'; \
done && \
echo ' </Target>' && \
echo '</Project>') >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
# 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-receive-pack >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) $@\`"

View File

@ -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);

View File

@ -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;
@ -106,6 +59,8 @@ sub createLibProject {
my $includes= join(";", sort(map("&quot;$rel_dir\\$_&quot;", @{$$build_structure{"LIBS_${libname}_INCLUDES"}})));
my $cflags = join(" ", sort(@{$$build_structure{"LIBS_${libname}_CFLAGS"}}));
$cflags =~ s/\"/&quot;/g;
$cflags =~ s/</&lt;/g;
$cflags =~ s/>/&gt;/g;
my $cflags_debug = $cflags;
$cflags_debug =~ s/-MT/-MTd/;
@ -127,6 +82,8 @@ sub createLibProject {
$defines =~ s/-D//g;
$defines =~ s/\"/\\&quot;/g;
$defines =~ s/</&lt;/g;
$defines =~ s/>/&gt;/g;
$defines =~ s/\'//g;
$includes =~ s/-I//g;
mkdir "$target" || die "Could not create the directory $target for lib project!\n";
@ -162,9 +119,6 @@ sub createLibProject {
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
@ -228,9 +182,6 @@ sub createLibProject {
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
@ -311,9 +262,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;
@ -325,6 +275,8 @@ sub createAppProject {
my $includes= join(";", sort(map("&quot;$rel_dir\\$_&quot;", @{$$build_structure{"APPS_${appname}_INCLUDES"}})));
my $cflags = join(" ", sort(@{$$build_structure{"APPS_${appname}_CFLAGS"}}));
$cflags =~ s/\"/&quot;/g;
$cflags =~ s/</&lt;/g;
$cflags =~ s/>/&gt;/g;
my $cflags_debug = $cflags;
$cflags_debug =~ s/-MT/-MTd/;
@ -351,6 +303,8 @@ sub createAppProject {
$defines =~ s/-D//g;
$defines =~ s/\"/\\&quot;/g;
$defines =~ s/</&lt;/g;
$defines =~ s/>/&gt;/g;
$defines =~ s/\'//g;
$defines =~ s/\\\\/\\/g;
$includes =~ s/-I//g;
@ -387,9 +341,6 @@ sub createAppProject {
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
@ -458,9 +409,6 @@ sub createAppProject {
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
@ -561,20 +509,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) {
@ -588,6 +534,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
@ -599,17 +552,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";

View File

@ -0,0 +1,388 @@
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/</&lt;/g;
$cflags =~ s/>/&gt;/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/</&lt;/g;
$defines =~ s/>/&gt;/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";
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>$uuid</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<VCPKGArch Condition="'\$(Platform)'=='Win32'">x86-windows</VCPKGArch>
<VCPKGArch Condition="'\$(Platform)'!='Win32'">x64-windows</VCPKGArch>
<VCPKGArchDirectory>$cdup\\compat\\vcbuild\\vcpkg\\installed\\\$(VCPKGArch)</VCPKGArchDirectory>
<VCPKGBinDirectory Condition="'\(Configuration)'=='Debug'">\$(VCPKGArchDirectory)\\debug\\bin</VCPKGBinDirectory>
<VCPKGLibDirectory Condition="'\(Configuration)'=='Debug'">\$(VCPKGArchDirectory)\\debug\\lib</VCPKGLibDirectory>
<VCPKGBinDirectory Condition="'\(Configuration)'!='Debug'">\$(VCPKGArchDirectory)\\bin</VCPKGBinDirectory>
<VCPKGLibDirectory Condition="'\(Configuration)'!='Debug'">\$(VCPKGArchDirectory)\\lib</VCPKGLibDirectory>
<VCPKGIncludeDirectory>\$(VCPKGArchDirectory)\\include</VCPKGIncludeDirectory>
<VCPKGLibs Condition="'\(Configuration)'=='Debug'">$libs_debug</VCPKGLibs>
<VCPKGLibs Condition="'\(Configuration)'!='Debug'">$libs_release</VCPKGLibs>
</PropertyGroup>
<Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'\$(Configuration)'=='Debug'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'\$(Configuration)'=='Release'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup>
<ConfigurationType>$config_type</ConfigurationType>
<PlatformToolset>v140</PlatformToolset>
<!-- <CharacterSet>UTF-8</CharacterSet> -->
<OutDir>..\\</OutDir>
<!-- <IntDir>\$(ProjectDir)\$(Configuration)\\</IntDir> -->
</PropertyGroup>
<Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props" Condition="exists('\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<GenerateManifest>false</GenerateManifest>
<EnableManagedIncrementalBuild>true</EnableManagedIncrementalBuild>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalOptions>$cflags %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$cdup;$cdup\\compat;$cdup\\compat\\regex;$cdup\\compat\\win32;$cdup\\compat\\poll;$cdup\\compat\\vcbuild\\include;\$(VCPKGIncludeDirectory);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<EnableParallelCodeGeneration />
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<PrecompiledHeader />
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Lib>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Lib>
<Link>
<AdditionalLibraryDirectories>\$(VCPKGLibDirectory);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>\$(VCPKGLibs);\$(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>invalidcontinue.obj %(AdditionalOptions)</AdditionalOptions>
<EntryPointSymbol>wmainCRTStartup</EntryPointSymbol>
<ManifestFile>$cdup\\compat\\win32\\git.manifest</ManifestFile>
<SubSystem>Console</SubSystem>
</Link>
EOM
if ($target eq 'libgit') {
print F << "EOM";
<PreBuildEvent Condition="!Exists('$cdup\\compat\\vcbuild\\vcpkg\\installed\\\$(VCPKGArch)\\include\\openssl\\ssl.h')">
<Message>Initialize VCPKG</Message>
<Command>del "$cdup\\compat\\vcbuild\\vcpkg"</Command>
<Command>call "$cdup\\compat\\vcbuild\\vcpkg_install.bat"</Command>
</PreBuildEvent>
EOM
}
print F << "EOM";
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'\$(Platform)'=='Win32'">
<Link>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'\$(Configuration)'=='Debug'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;$defines;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'\$(Configuration)'=='Release'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;$defines;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
EOM
foreach(@sources) {
print F << "EOM";
<ClCompile Include="$_" />
EOM
}
print F << "EOM";
</ItemGroup>
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";
<ItemGroup>
<ProjectReference Include="$cdup\\libgit\\libgit.vcxproj">
<Project>$uuid_libgit</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
EOM
if (!($name =~ 'xdiff')) {
print F << "EOM";
<ProjectReference Include="$cdup\\xdiff\\lib\\xdiff_lib.vcxproj">
<Project>$uuid_xdiff_lib</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
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";
<ProjectReference Include="$cdup\\vcs-svn\\lib\\vcs-svn_lib.vcxproj">
<Project>$uuid_vcs_svn_lib</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
EOM
}
print F << "EOM";
</ItemGroup>
EOM
}
print F << "EOM";
<Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.targets" />
EOM
if (!$static_library) {
print F << "EOM";
<Target Name="${target}_AfterBuild" AfterTargets="AfterBuild">
<ItemGroup>
<DLLsAndPDBs Include="\$(VCPKGBinDirectory)\\*.dll;\$(VCPKGBinDirectory)\\*.pdb" />
</ItemGroup>
<Copy SourceFiles="@(DLLsAndPDBs)" DestinationFolder="\$(OutDir)" SkipUnchangedFiles="true" UseHardlinksIfPossible="true" />
<MakeDir Directories="..\\templates\\blt\\branches" />
</Target>
EOM
}
if ($target eq 'git') {
print F " <Import Project=\"LinkOrCopyBuiltins.targets\" />\n";
}
print F << "EOM";
</Project>
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;

View File

@ -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();
@ -31,6 +32,7 @@ generate usage:
-g <GENERATOR> --gen <GENERATOR> Specify the buildsystem generator (default: $gen)
Available: $genlist
-o <PATH> --out <PATH> Specify output directory generation (default: .)
--make-out <PATH> Write the output of GNU Make into a file
-i <FILE> --in <FILE> Specify input file, instead of running GNU Make
-h,-? --help This help
EOM
@ -38,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 "-?") {
@ -45,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") {
@ -52,6 +57,8 @@ while (@ARGV) {
open(F, "<$infile") || die "Couldn't open file $infile";
@makedry = <F>;
close(F);
} else {
die "Unknown option: " . $arg;
}
}
@ -72,7 +79,19 @@ 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 SKIP_VCPKG=1 V=1 2>$ErrsFile`
if !@makedry;
# 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();
@ -140,6 +159,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);
@ -231,7 +256,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 +290,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);
@ -282,7 +307,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"}});
@ -306,7 +331,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/) {
@ -317,26 +342,36 @@ 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 =~ /^-/) {
} 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 =~ /^[-\/]/) {
push(@lflags, $part);
} 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";
die "Unhandled link option @ line $lineno: $part";
}
}
# print "AppOut: '$appout'\nLFlags: @lflags\nLibs : @libs\nOfiles: @objfiles\n";
# 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"}});

3
git.c
View File

@ -739,8 +739,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;
@ -775,7 +773,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);