1 package Generators
::Vcxproj
;
6 use Digest::SHA qw(sha256_hex);
9 our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE);
13 push @EXPORT_OK, qw(generate);
16 sub generate_guid
($) {
17 my $hex = sha256_hex
($_[0]);
18 $hex =~ s/^(.{8})(.{4})(.{4})(.{4})(.{12}).*/{$1-$2-$3-$4-$5}/;
24 my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
25 my @libs = @
{$build_structure{"LIBS"}};
27 createProject
($_, $git_dir, $out_dir, $rel_dir, \
%build_structure, 1);
30 my @apps = @
{$build_structure{"APPS"}};
32 createProject
($_, $git_dir, $out_dir, $rel_dir, \
%build_structure, 0);
35 createGlueProject
($git_dir, $out_dir, $rel_dir, %build_structure);
40 my ($name, $git_dir, $out_dir, $rel_dir, $build_structure, $static_library) = @_;
41 my $label = $static_library ?
"lib" : "app";
42 my $prefix = $static_library ?
"LIBS_" : "APPS_";
43 my $config_type = $static_library ?
"StaticLibrary" : "Application";
44 print "Generate $name vcxproj $label project\n";
46 $cdup =~ s/[^\/]+/../g
;
48 $rel_dir = $rel_dir eq "." ?
$cdup : "$cdup\\$rel_dir";
49 $rel_dir =~ s/\//\\/g
;
52 if ($static_library) {
58 my $uuid = generate_guid
($name);
59 $$build_structure{"$prefix${target}_GUID"} = $uuid;
60 my $vcxproj = $target;
61 $vcxproj =~ s/(.*\/)?(.*)/$&\
/$2.vcxproj/;
62 $vcxproj =~ s/([^\/]*)(\/lib
)\
/(lib.vcxproj)/$1$2\
/$1_$3/;
63 $$build_structure{"$prefix${target}_VCXPROJ"} = $vcxproj;
65 my @srcs = sort(map("$rel_dir\\$_", @
{$$build_structure{"$prefix${name}_SOURCES"}}));
71 my $defines = join(";", sort(@
{$$build_structure{"$prefix${name}_DEFINES"}}));
72 my $includes= join(";", sort(map { s/^-I//; s/\//\\/g
; File
::Spec
->file_name_is_absolute($_) ?
$_ : "$rel_dir\\$_" } @
{$$build_structure{"$prefix${name}_INCLUDES"}}));
73 my $cflags = join(" ", sort(map { s/^-[GLMOWZ].*//; s/.* .*/"$&"/; $_; } @
{$$build_structure{"$prefix${name}_CFLAGS"}}));
74 $cflags =~ s/</</g;
75 $cflags =~ s/>/>/g;
77 my $libs_release = "\n ";
78 my $libs_debug = "\n ";
79 if (!$static_library) {
80 $libs_release = join(";", sort(grep /^(?!libgit\.lib|xdiff\/lib\
.lib
|vcs
-svn\
/lib\.lib|reftable\/libreftable\
.lib
)/, @
{$$build_structure{"$prefix${name}_LIBS"}}));
81 $libs_debug = $libs_release;
82 $libs_debug =~ s/zlib\.lib/zlibd\.lib/g;
83 $libs_debug =~ s/libexpat\.lib/libexpatd\.lib/g;
84 $libs_debug =~ s/libcurl\.lib/libcurl-d\.lib/g;
88 $defines =~ s/</</g;
89 $defines =~ s/>/>/g;
92 die "Could not create the directory $target for $label project!\n" unless (-d
"$target" || mkdir "$target");
94 open F
, ">$vcxproj" or die "Could not open $vcxproj for writing!\n";
95 binmode F
, ":crlf :utf8";
98 <?xml version
="1.0" encoding
="utf-8"?
>
99 <Project DefaultTargets
="Build" ToolsVersion
="14.0" xmlns
="http://schemas.microsoft.com/developer/msbuild/2003">
100 <ItemGroup Label
="ProjectConfigurations">
101 <ProjectConfiguration Include
="Debug|Win32">
102 <Configuration
>Debug
</Configuration
>
103 <Platform
>Win32
</Platform
>
104 </ProjectConfiguration
>
105 <ProjectConfiguration Include
="Release|Win32">
106 <Configuration
>Release
</Configuration
>
107 <Platform
>Win32
</Platform
>
108 </ProjectConfiguration
>
109 <ProjectConfiguration Include
="Debug|x64">
110 <Configuration
>Debug
</Configuration
>
111 <Platform
>x64
</Platform
>
112 </ProjectConfiguration
>
113 <ProjectConfiguration Include
="Release|x64">
114 <Configuration
>Release
</Configuration
>
115 <Platform
>x64
</Platform
>
116 </ProjectConfiguration
>
118 <PropertyGroup Label
="Globals">
119 <ProjectGuid
>$uuid</ProjectGuid
>
120 <Keyword
>Win32Proj
</Keyword
>
121 <VCPKGArch Condition
="'\$(Platform)'=='Win32'">x86
-windows
</VCPKGArch
>
122 <VCPKGArch Condition
="'\$(Platform)'!='Win32'">x64
-windows
</VCPKGArch
>
123 <VCPKGArchDirectory
>$cdup\\compat
\\vcbuild
\\vcpkg
\\installed
\\\
$(VCPKGArch
)</VCPKGArchDirectory
>
124 <VCPKGBinDirectory Condition
="'\$(Configuration)'=='Debug'">\
$(VCPKGArchDirectory
)\\debug
\\bin
</VCPKGBinDirectory
>
125 <VCPKGLibDirectory Condition
="'\$(Configuration)'=='Debug'">\
$(VCPKGArchDirectory
)\\debug
\\lib
</VCPKGLibDirectory
>
126 <VCPKGBinDirectory Condition
="'\$(Configuration)'!='Debug'">\
$(VCPKGArchDirectory
)\\bin
</VCPKGBinDirectory
>
127 <VCPKGLibDirectory Condition
="'\$(Configuration)'!='Debug'">\
$(VCPKGArchDirectory
)\\lib
</VCPKGLibDirectory
>
128 <VCPKGIncludeDirectory
>\
$(VCPKGArchDirectory
)\\include
</VCPKGIncludeDirectory
>
129 <VCPKGLibs Condition
="'\$(Configuration)'=='Debug'">$libs_debug</VCPKGLibs
>
130 <VCPKGLibs Condition
="'\$(Configuration)'!='Debug'">$libs_release</VCPKGLibs
>
132 <Import Project
="\$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
133 <PropertyGroup Condition
="'\$(Configuration)'=='Debug'" Label
="Configuration">
134 <UseDebugLibraries
>true
</UseDebugLibraries
>
135 <LinkIncremental
>true
</LinkIncremental
>
137 <PropertyGroup Condition
="'\$(Configuration)'=='Release'" Label
="Configuration">
138 <UseDebugLibraries
>false
</UseDebugLibraries
>
139 <WholeProgramOptimization
>true
</WholeProgramOptimization
>
142 <ConfigurationType
>$config_type</ConfigurationType
>
143 <PlatformToolset
>v140
</PlatformToolset
>
144 <!-- <CharacterSet
>UTF
-8</CharacterSet
> -->
145 <OutDir
>..\\</OutDir
>
146 <!-- <IntDir
>\
$(ProjectDir
)\
$(Configuration
)\\</IntDir
> -->
148 <Import Project
="\$(VCTargetsPath)\\Microsoft.Cpp.props" />
149 <ImportGroup Label
="ExtensionSettings">
151 <ImportGroup Label
="Shared">
153 <ImportGroup Label
="PropertySheets">
154 <Import Project
="\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props" Condition
="exists('\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props')" Label
="LocalAppDataPlatform" />
156 <PropertyGroup Label
="UserMacros" />
158 <GenerateManifest
>false
</GenerateManifest
>
159 <EnableManagedIncrementalBuild
>true
</EnableManagedIncrementalBuild
>
161 <ItemDefinitionGroup
>
163 <AdditionalOptions
>$cflags %(AdditionalOptions
)</AdditionalOptions
>
164 <AdditionalIncludeDirectories
>$cdup;$cdup\\compat
;$cdup\\compat
\\regex
;$cdup\\compat
\\win32
;$cdup\\compat
\\poll
;$cdup\\compat
\\vcbuild
\\include
;\
$(VCPKGIncludeDirectory
);%(AdditionalIncludeDirectories
)</AdditionalIncludeDirectories
>
165 <EnableParallelCodeGeneration
/>
166 <InlineFunctionExpansion
>OnlyExplicitInline
</InlineFunctionExpansion
>
167 <PrecompiledHeader
/>
168 <DebugInformationFormat
>ProgramDatabase
</DebugInformationFormat
>
171 <SuppressStartupBanner
>true
</SuppressStartupBanner
>
174 <AdditionalLibraryDirectories
>\
$(VCPKGLibDirectory
);%(AdditionalLibraryDirectories
)</AdditionalLibraryDirectories
>
175 <AdditionalDependencies
>\
$(VCPKGLibs
);\
$(AdditionalDependencies
)</AdditionalDependencies
>
176 <AdditionalOptions
>invalidcontinue
.obj
%(AdditionalOptions
)</AdditionalOptions
>
177 <EntryPointSymbol
>wmainCRTStartup
</EntryPointSymbol
>
178 <ManifestFile
>$cdup\\compat
\\win32
\\git
.manifest
</ManifestFile
>
179 <SubSystem
>Console
</SubSystem
>
182 if ($target eq 'libgit') {
184 <PreBuildEvent Condition
="!Exists('$cdup\\compat\\vcbuild\\vcpkg\\installed\\\$(VCPKGArch)\\include\\openssl\\ssl.h')">
185 <Message
>Initialize VCPKG
</Message
>
186 <Command
>del
"$cdup\\compat\\vcbuild\\vcpkg"</Command
>
187 <Command
>call
"$cdup\\compat\\vcbuild\\vcpkg_install.bat"</Command
>
192 </ItemDefinitionGroup
>
193 <ItemDefinitionGroup Condition
="'\$(Platform)'=='Win32'">
195 <TargetMachine
>MachineX86
</TargetMachine
>
197 </ItemDefinitionGroup
>
198 <ItemDefinitionGroup Condition
="'\$(Configuration)'=='Debug'">
200 <Optimization
>Disabled
</Optimization
>
201 <PreprocessorDefinitions
>WIN32
;_DEBUG
;$defines;%(PreprocessorDefinitions
)</PreprocessorDefinitions
>
202 <RuntimeLibrary
>MultiThreadedDebugDLL
</RuntimeLibrary
>
205 <GenerateDebugInformation
>true
</GenerateDebugInformation
>
207 </ItemDefinitionGroup
>
208 <ItemDefinitionGroup Condition
="'\$(Configuration)'=='Release'">
210 <Optimization
>MaxSpeed
</Optimization
>
211 <IntrinsicFunctions
>true
</IntrinsicFunctions
>
212 <PreprocessorDefinitions
>WIN32
;NDEBUG
;$defines;%(PreprocessorDefinitions
)</PreprocessorDefinitions
>
213 <RuntimeLibrary
>MultiThreadedDLL
</RuntimeLibrary
>
214 <FunctionLevelLinking
>true
</FunctionLevelLinking
>
215 <FavorSizeOrSpeed
>Speed
</FavorSizeOrSpeed
>
218 <GenerateDebugInformation
>true
</GenerateDebugInformation
>
219 <EnableCOMDATFolding
>true
</EnableCOMDATFolding
>
220 <OptimizeReferences
>true
</OptimizeReferences
>
222 </ItemDefinitionGroup
>
227 <ClCompile Include
="$_" />
233 if (!$static_library || $target =~ 'vcs-svn' || $target =~ 'xdiff') {
234 my $uuid_libgit = $$build_structure{"LIBS_libgit_GUID"};
235 my $uuid_libreftable = $$build_structure{"LIBS_reftable/libreftable_GUID"};
236 my $uuid_xdiff_lib = $$build_structure{"LIBS_xdiff/lib_GUID"};
240 <ProjectReference Include
="$cdup\\libgit\\libgit.vcxproj">
241 <Project
>$uuid_libgit</Project
>
242 <ReferenceOutputAssembly
>false
</ReferenceOutputAssembly
>
245 if (!($name =~ /xdiff|libreftable/)) {
247 <ProjectReference Include
="$cdup\\reftable\\libreftable\\libreftable.vcxproj">
248 <Project
>$uuid_libreftable</Project
>
249 <ReferenceOutputAssembly
>false
</ReferenceOutputAssembly
>
253 if (!($name =~ 'xdiff')) {
255 <ProjectReference Include
="$cdup\\xdiff\\lib\\xdiff_lib.vcxproj">
256 <Project
>$uuid_xdiff_lib</Project
>
257 <ReferenceOutputAssembly
>false
</ReferenceOutputAssembly
>
261 if ($name =~ /(test-(line-buffer|svn-fe)|^git-remote-testsvn)\.exe$/) {
262 my $uuid_vcs_svn_lib = $$build_structure{"LIBS_vcs-svn/lib_GUID"};
264 <ProjectReference Include
="$cdup\\vcs-svn\\lib\\vcs-svn_lib.vcxproj">
265 <Project
>$uuid_vcs_svn_lib</Project
>
266 <ReferenceOutputAssembly
>false
</ReferenceOutputAssembly
>
275 <Import Project
="\$(VCTargetsPath)\\Microsoft.Cpp.targets" />
277 if (!$static_library) {
279 <Target Name
="${target}_AfterBuild" AfterTargets
="AfterBuild">
281 <DLLsAndPDBs Include
="\$(VCPKGBinDirectory)\\*.dll;\$(VCPKGBinDirectory)\\*.pdb" />
283 <Copy SourceFiles
="@(DLLsAndPDBs)" DestinationFolder
="\$(OutDir)" SkipUnchangedFiles
="true" UseHardlinksIfPossible
="true" />
284 <MakeDir Directories
="..\\templates\\blt\\branches" />
288 if ($target eq 'git') {
289 print F
" <Import Project=\"LinkOrCopyBuiltins.targets\" />\n";
291 if ($target eq 'git-remote-http') {
292 print F
" <Import Project=\"LinkOrCopyRemoteHttp.targets\" />\n";
300 sub createGlueProject
{
301 my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
302 print "Generate solutions file\n";
303 $rel_dir = "..\\$rel_dir";
304 $rel_dir =~ s/\//\\/g
;
305 my $SLN_HEAD = "Microsoft Visual Studio Solution File, Format Version 11.00\n# Visual Studio 2010\n";
306 my $SLN_PRE = "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = ";
307 my $SLN_POST = "\nEndProject\n";
309 my @libs = @
{$build_structure{"LIBS"}};
317 my @apps = @
{$build_structure{"APPS"}};
329 open F
, ">git.sln" || die "Could not open git.sln for writing!\n";
330 binmode F
, ":crlf :utf8";
336 my $uuid = $build_structure{"APPS_${appname}_GUID"};
338 my $vcxproj = $build_structure{"APPS_${appname}_VCXPROJ"};
339 $vcxproj =~ s/\//\\/g
;
340 $appname =~ s/.*\///;
341 print F
"\"${appname}\", \"${vcxproj}\", \"${uuid}\"";
346 my $uuid = $build_structure{"LIBS_${libname}_GUID"};
348 my $vcxproj = $build_structure{"LIBS_${libname}_VCXPROJ"};
349 $vcxproj =~ s/\//\\/g
;
350 $libname =~ s/\//_
/g
;
351 print F
"\"${libname}\", \"${vcxproj}\", \"${uuid}\"";
357 GlobalSection
(SolutionConfigurationPlatforms
) = preSolution
358 Debug
|x64
= Debug
|x64
359 Debug
|x86
= Debug
|x86
360 Release
|x64
= Release
|x64
361 Release
|x86
= Release
|x86
365 GlobalSection
(ProjectConfigurationPlatforms
) = postSolution
369 my $uuid = $build_structure{"APPS_${appname}_GUID"};
370 print F
"\t\t${uuid}.Debug|x64.ActiveCfg = Debug|x64\n";
371 print F
"\t\t${uuid}.Debug|x64.Build.0 = Debug|x64\n";
372 print F
"\t\t${uuid}.Debug|x86.ActiveCfg = Debug|Win32\n";
373 print F
"\t\t${uuid}.Debug|x86.Build.0 = Debug|Win32\n";
374 print F
"\t\t${uuid}.Release|x64.ActiveCfg = Release|x64\n";
375 print F
"\t\t${uuid}.Release|x64.Build.0 = Release|x64\n";
376 print F
"\t\t${uuid}.Release|x86.ActiveCfg = Release|Win32\n";
377 print F
"\t\t${uuid}.Release|x86.Build.0 = Release|Win32\n";
381 my $uuid = $build_structure{"LIBS_${libname}_GUID"};
382 print F
"\t\t${uuid}.Debug|x64.ActiveCfg = Debug|x64\n";
383 print F
"\t\t${uuid}.Debug|x64.Build.0 = Debug|x64\n";
384 print F
"\t\t${uuid}.Debug|x86.ActiveCfg = Debug|Win32\n";
385 print F
"\t\t${uuid}.Debug|x86.Build.0 = Debug|Win32\n";
386 print F
"\t\t${uuid}.Release|x64.ActiveCfg = Release|x64\n";
387 print F
"\t\t${uuid}.Release|x64.Build.0 = Release|x64\n";
388 print F
"\t\t${uuid}.Release|x86.ActiveCfg = Release|Win32\n";
389 print F
"\t\t${uuid}.Release|x86.Build.0 = Release|Win32\n";
394 GlobalSection
(SolutionProperties
) = preSolution
395 HideSolutionNode
= FALSE