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)/, @
{$$build_structure{"$prefix${name}_LIBS"}}));
81 $libs_debug = $libs_release;
82 $libs_debug =~ s/zlib\.lib/zlibd\.lib/g;
83 $libs_debug =~ s/libcurl\.lib/libcurl-d\.lib/g;
87 $defines =~ s/</</g;
88 $defines =~ s/>/>/g;
91 die "Could not create the directory $target for $label project!\n" unless (-d
"$target" || mkdir "$target");
93 open F
, ">$vcxproj" or die "Could not open $vcxproj for writing!\n";
94 binmode F
, ":crlf :utf8";
97 <?xml version
="1.0" encoding
="utf-8"?
>
98 <Project DefaultTargets
="Build" ToolsVersion
="14.0" xmlns
="http://schemas.microsoft.com/developer/msbuild/2003">
99 <ItemGroup Label
="ProjectConfigurations">
100 <ProjectConfiguration Include
="Debug|Win32">
101 <Configuration
>Debug
</Configuration
>
102 <Platform
>Win32
</Platform
>
103 </ProjectConfiguration
>
104 <ProjectConfiguration Include
="Release|Win32">
105 <Configuration
>Release
</Configuration
>
106 <Platform
>Win32
</Platform
>
107 </ProjectConfiguration
>
108 <ProjectConfiguration Include
="Debug|x64">
109 <Configuration
>Debug
</Configuration
>
110 <Platform
>x64
</Platform
>
111 </ProjectConfiguration
>
112 <ProjectConfiguration Include
="Release|x64">
113 <Configuration
>Release
</Configuration
>
114 <Platform
>x64
</Platform
>
115 </ProjectConfiguration
>
117 <PropertyGroup Label
="Globals">
118 <ProjectGuid
>$uuid</ProjectGuid
>
119 <Keyword
>Win32Proj
</Keyword
>
120 <VCPKGArch Condition
="'\$(Platform)'=='Win32'">x86
-windows
</VCPKGArch
>
121 <VCPKGArch Condition
="'\$(Platform)'!='Win32'">x64
-windows
</VCPKGArch
>
122 <VCPKGArchDirectory
>$cdup\\compat
\\vcbuild
\\vcpkg
\\installed
\\\
$(VCPKGArch
)</VCPKGArchDirectory
>
123 <VCPKGBinDirectory Condition
="'\$(Configuration)'=='Debug'">\
$(VCPKGArchDirectory
)\\debug
\\bin
</VCPKGBinDirectory
>
124 <VCPKGLibDirectory Condition
="'\$(Configuration)'=='Debug'">\
$(VCPKGArchDirectory
)\\debug
\\lib
</VCPKGLibDirectory
>
125 <VCPKGBinDirectory Condition
="'\$(Configuration)'!='Debug'">\
$(VCPKGArchDirectory
)\\bin
</VCPKGBinDirectory
>
126 <VCPKGLibDirectory Condition
="'\$(Configuration)'!='Debug'">\
$(VCPKGArchDirectory
)\\lib
</VCPKGLibDirectory
>
127 <VCPKGIncludeDirectory
>\
$(VCPKGArchDirectory
)\\include
</VCPKGIncludeDirectory
>
128 <VCPKGLibs Condition
="'\$(Configuration)'=='Debug'">$libs_debug</VCPKGLibs
>
129 <VCPKGLibs Condition
="'\$(Configuration)'!='Debug'">$libs_release</VCPKGLibs
>
131 <Import Project
="\$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
132 <PropertyGroup Condition
="'\$(Configuration)'=='Debug'" Label
="Configuration">
133 <UseDebugLibraries
>true
</UseDebugLibraries
>
134 <LinkIncremental
>true
</LinkIncremental
>
136 <PropertyGroup Condition
="'\$(Configuration)'=='Release'" Label
="Configuration">
137 <UseDebugLibraries
>false
</UseDebugLibraries
>
138 <WholeProgramOptimization
>true
</WholeProgramOptimization
>
141 <ConfigurationType
>$config_type</ConfigurationType
>
142 <PlatformToolset
>v140
</PlatformToolset
>
143 <!-- <CharacterSet
>UTF
-8</CharacterSet
> -->
144 <OutDir
>..\\</OutDir
>
145 <!-- <IntDir
>\
$(ProjectDir
)\
$(Configuration
)\\</IntDir
> -->
147 <Import Project
="\$(VCTargetsPath)\\Microsoft.Cpp.props" />
148 <ImportGroup Label
="ExtensionSettings">
150 <ImportGroup Label
="Shared">
152 <ImportGroup Label
="PropertySheets">
153 <Import Project
="\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props" Condition
="exists('\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props')" Label
="LocalAppDataPlatform" />
155 <PropertyGroup Label
="UserMacros" />
157 <GenerateManifest
>false
</GenerateManifest
>
158 <EnableManagedIncrementalBuild
>true
</EnableManagedIncrementalBuild
>
160 <ItemDefinitionGroup
>
162 <AdditionalOptions
>$cflags %(AdditionalOptions
)</AdditionalOptions
>
163 <AdditionalIncludeDirectories
>$cdup;$cdup\\compat
;$cdup\\compat
\\regex
;$cdup\\compat
\\win32
;$cdup\\compat
\\poll
;$cdup\\compat
\\vcbuild
\\include
;\
$(VCPKGIncludeDirectory
);%(AdditionalIncludeDirectories
)</AdditionalIncludeDirectories
>
164 <EnableParallelCodeGeneration
/>
165 <InlineFunctionExpansion
>OnlyExplicitInline
</InlineFunctionExpansion
>
166 <PrecompiledHeader
/>
167 <DebugInformationFormat
>ProgramDatabase
</DebugInformationFormat
>
170 <SuppressStartupBanner
>true
</SuppressStartupBanner
>
173 <AdditionalLibraryDirectories
>\
$(VCPKGLibDirectory
);%(AdditionalLibraryDirectories
)</AdditionalLibraryDirectories
>
174 <AdditionalDependencies
>\
$(VCPKGLibs
);\
$(AdditionalDependencies
)</AdditionalDependencies
>
175 <AdditionalOptions
>invalidcontinue
.obj
%(AdditionalOptions
)</AdditionalOptions
>
176 <EntryPointSymbol
>wmainCRTStartup
</EntryPointSymbol
>
177 <ManifestFile
>$cdup\\compat
\\win32
\\git
.manifest
</ManifestFile
>
178 <SubSystem
>Console
</SubSystem
>
181 if ($target eq 'libgit') {
183 <PreBuildEvent Condition
="!Exists('$cdup\\compat\\vcbuild\\vcpkg\\installed\\\$(VCPKGArch)\\include\\openssl\\ssl.h')">
184 <Message
>Initialize VCPKG
</Message
>
185 <Command
>del
"$cdup\\compat\\vcbuild\\vcpkg"</Command
>
186 <Command
>call
"$cdup\\compat\\vcbuild\\vcpkg_install.bat"</Command
>
191 </ItemDefinitionGroup
>
192 <ItemDefinitionGroup Condition
="'\$(Platform)'=='Win32'">
194 <TargetMachine
>MachineX86
</TargetMachine
>
196 </ItemDefinitionGroup
>
197 <ItemDefinitionGroup Condition
="'\$(Configuration)'=='Debug'">
199 <Optimization
>Disabled
</Optimization
>
200 <PreprocessorDefinitions
>WIN32
;_DEBUG
;$defines;%(PreprocessorDefinitions
)</PreprocessorDefinitions
>
201 <RuntimeLibrary
>MultiThreadedDebugDLL
</RuntimeLibrary
>
204 <GenerateDebugInformation
>true
</GenerateDebugInformation
>
206 </ItemDefinitionGroup
>
207 <ItemDefinitionGroup Condition
="'\$(Configuration)'=='Release'">
209 <Optimization
>MaxSpeed
</Optimization
>
210 <IntrinsicFunctions
>true
</IntrinsicFunctions
>
211 <PreprocessorDefinitions
>WIN32
;NDEBUG
;$defines;%(PreprocessorDefinitions
)</PreprocessorDefinitions
>
212 <RuntimeLibrary
>MultiThreadedDLL
</RuntimeLibrary
>
213 <FunctionLevelLinking
>true
</FunctionLevelLinking
>
214 <FavorSizeOrSpeed
>Speed
</FavorSizeOrSpeed
>
217 <GenerateDebugInformation
>true
</GenerateDebugInformation
>
218 <EnableCOMDATFolding
>true
</EnableCOMDATFolding
>
219 <OptimizeReferences
>true
</OptimizeReferences
>
221 </ItemDefinitionGroup
>
226 <ClCompile Include
="$_" />
232 if (!$static_library || $target =~ 'vcs-svn' || $target =~ 'xdiff') {
233 my $uuid_libgit = $$build_structure{"LIBS_libgit_GUID"};
234 my $uuid_xdiff_lib = $$build_structure{"LIBS_xdiff/lib_GUID"};
238 <ProjectReference Include
="$cdup\\libgit\\libgit.vcxproj">
239 <Project
>$uuid_libgit</Project
>
240 <ReferenceOutputAssembly
>false
</ReferenceOutputAssembly
>
243 if (!($name =~ 'xdiff')) {
245 <ProjectReference Include
="$cdup\\xdiff\\lib\\xdiff_lib.vcxproj">
246 <Project
>$uuid_xdiff_lib</Project
>
247 <ReferenceOutputAssembly
>false
</ReferenceOutputAssembly
>
251 if ($name =~ /(test-(line-buffer|svn-fe)|^git-remote-testsvn)\.exe$/) {
252 my $uuid_vcs_svn_lib = $$build_structure{"LIBS_vcs-svn/lib_GUID"};
254 <ProjectReference Include
="$cdup\\vcs-svn\\lib\\vcs-svn_lib.vcxproj">
255 <Project
>$uuid_vcs_svn_lib</Project
>
256 <ReferenceOutputAssembly
>false
</ReferenceOutputAssembly
>
265 <Import Project
="\$(VCTargetsPath)\\Microsoft.Cpp.targets" />
267 if (!$static_library) {
269 <Target Name
="${target}_AfterBuild" AfterTargets
="AfterBuild">
271 <DLLsAndPDBs Include
="\$(VCPKGBinDirectory)\\*.dll;\$(VCPKGBinDirectory)\\*.pdb" />
273 <Copy SourceFiles
="@(DLLsAndPDBs)" DestinationFolder
="\$(OutDir)" SkipUnchangedFiles
="true" UseHardlinksIfPossible
="true" />
274 <MakeDir Directories
="..\\templates\\blt\\branches" />
278 if ($target eq 'git') {
279 print F
" <Import Project=\"LinkOrCopyBuiltins.targets\" />\n";
287 sub createGlueProject
{
288 my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
289 print "Generate solutions file\n";
290 $rel_dir = "..\\$rel_dir";
291 $rel_dir =~ s/\//\\/g
;
292 my $SLN_HEAD = "Microsoft Visual Studio Solution File, Format Version 11.00\n# Visual Studio 2010\n";
293 my $SLN_PRE = "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = ";
294 my $SLN_POST = "\nEndProject\n";
296 my @libs = @
{$build_structure{"LIBS"}};
304 my @apps = @
{$build_structure{"APPS"}};
316 open F
, ">git.sln" || die "Could not open git.sln for writing!\n";
317 binmode F
, ":crlf :utf8";
323 my $uuid = $build_structure{"APPS_${appname}_GUID"};
325 my $vcxproj = $build_structure{"APPS_${appname}_VCXPROJ"};
326 $vcxproj =~ s/\//\\/g
;
327 $appname =~ s/.*\///;
328 print F
"\"${appname}\", \"${vcxproj}\", \"${uuid}\"";
333 my $uuid = $build_structure{"LIBS_${libname}_GUID"};
335 my $vcxproj = $build_structure{"LIBS_${libname}_VCXPROJ"};
336 $vcxproj =~ s/\//\\/g
;
337 $libname =~ s/\//_
/g
;
338 print F
"\"${libname}\", \"${vcxproj}\", \"${uuid}\"";
344 GlobalSection
(SolutionConfigurationPlatforms
) = preSolution
345 Debug
|x64
= Debug
|x64
346 Debug
|x86
= Debug
|x86
347 Release
|x64
= Release
|x64
348 Release
|x86
= Release
|x86
352 GlobalSection
(ProjectConfigurationPlatforms
) = postSolution
356 my $uuid = $build_structure{"APPS_${appname}_GUID"};
357 print F
"\t\t${uuid}.Debug|x64.ActiveCfg = Debug|x64\n";
358 print F
"\t\t${uuid}.Debug|x64.Build.0 = Debug|x64\n";
359 print F
"\t\t${uuid}.Debug|x86.ActiveCfg = Debug|Win32\n";
360 print F
"\t\t${uuid}.Debug|x86.Build.0 = Debug|Win32\n";
361 print F
"\t\t${uuid}.Release|x64.ActiveCfg = Release|x64\n";
362 print F
"\t\t${uuid}.Release|x64.Build.0 = Release|x64\n";
363 print F
"\t\t${uuid}.Release|x86.ActiveCfg = Release|Win32\n";
364 print F
"\t\t${uuid}.Release|x86.Build.0 = Release|Win32\n";
368 my $uuid = $build_structure{"LIBS_${libname}_GUID"};
369 print F
"\t\t${uuid}.Debug|x64.ActiveCfg = Debug|x64\n";
370 print F
"\t\t${uuid}.Debug|x64.Build.0 = Debug|x64\n";
371 print F
"\t\t${uuid}.Debug|x86.ActiveCfg = Debug|Win32\n";
372 print F
"\t\t${uuid}.Debug|x86.Build.0 = Debug|Win32\n";
373 print F
"\t\t${uuid}.Release|x64.ActiveCfg = Release|x64\n";
374 print F
"\t\t${uuid}.Release|x64.Build.0 = Release|x64\n";
375 print F
"\t\t${uuid}.Release|x86.ActiveCfg = Release|Win32\n";
376 print F
"\t\t${uuid}.Release|x86.Build.0 = Release|Win32\n";
381 GlobalSection
(SolutionProperties
) = preSolution
382 HideSolutionNode
= FALSE