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/;
86 $defines =~ s/</</g;
87 $defines =~ s/>/>/g;
90 die "Could not create the directory $target for $label project!\n" unless (-d
"$target" || mkdir "$target");
92 open F
, ">$vcxproj" or die "Could not open $vcxproj for writing!\n";
93 binmode F
, ":crlf :utf8";
96 <?xml version
="1.0" encoding
="utf-8"?
>
97 <Project DefaultTargets
="Build" ToolsVersion
="14.0" xmlns
="http://schemas.microsoft.com/developer/msbuild/2003">
98 <ItemGroup Label
="ProjectConfigurations">
99 <ProjectConfiguration Include
="Debug|Win32">
100 <Configuration
>Debug
</Configuration
>
101 <Platform
>Win32
</Platform
>
102 </ProjectConfiguration
>
103 <ProjectConfiguration Include
="Release|Win32">
104 <Configuration
>Release
</Configuration
>
105 <Platform
>Win32
</Platform
>
106 </ProjectConfiguration
>
107 <ProjectConfiguration Include
="Debug|x64">
108 <Configuration
>Debug
</Configuration
>
109 <Platform
>x64
</Platform
>
110 </ProjectConfiguration
>
111 <ProjectConfiguration Include
="Release|x64">
112 <Configuration
>Release
</Configuration
>
113 <Platform
>x64
</Platform
>
114 </ProjectConfiguration
>
116 <PropertyGroup Label
="Globals">
117 <ProjectGuid
>$uuid</ProjectGuid
>
118 <Keyword
>Win32Proj
</Keyword
>
119 <VCPKGArch Condition
="'\$(Platform)'=='Win32'">x86
-windows
</VCPKGArch
>
120 <VCPKGArch Condition
="'\$(Platform)'!='Win32'">x64
-windows
</VCPKGArch
>
121 <VCPKGArchDirectory
>$cdup\\compat
\\vcbuild
\\vcpkg
\\installed
\\\
$(VCPKGArch
)</VCPKGArchDirectory
>
122 <VCPKGBinDirectory Condition
="'\(Configuration)'=='Debug'">\
$(VCPKGArchDirectory
)\\debug
\\bin
</VCPKGBinDirectory
>
123 <VCPKGLibDirectory Condition
="'\(Configuration)'=='Debug'">\
$(VCPKGArchDirectory
)\\debug
\\lib
</VCPKGLibDirectory
>
124 <VCPKGBinDirectory Condition
="'\(Configuration)'!='Debug'">\
$(VCPKGArchDirectory
)\\bin
</VCPKGBinDirectory
>
125 <VCPKGLibDirectory Condition
="'\(Configuration)'!='Debug'">\
$(VCPKGArchDirectory
)\\lib
</VCPKGLibDirectory
>
126 <VCPKGIncludeDirectory
>\
$(VCPKGArchDirectory
)\\include
</VCPKGIncludeDirectory
>
127 <VCPKGLibs Condition
="'\(Configuration)'=='Debug'">$libs_debug</VCPKGLibs
>
128 <VCPKGLibs Condition
="'\(Configuration)'!='Debug'">$libs_release</VCPKGLibs
>
130 <Import Project
="\$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
131 <PropertyGroup Condition
="'\$(Configuration)'=='Debug'" Label
="Configuration">
132 <UseDebugLibraries
>true
</UseDebugLibraries
>
133 <LinkIncremental
>true
</LinkIncremental
>
135 <PropertyGroup Condition
="'\$(Configuration)'=='Release'" Label
="Configuration">
136 <UseDebugLibraries
>false
</UseDebugLibraries
>
137 <WholeProgramOptimization
>true
</WholeProgramOptimization
>
140 <ConfigurationType
>$config_type</ConfigurationType
>
141 <PlatformToolset
>v140
</PlatformToolset
>
142 <!-- <CharacterSet
>UTF
-8</CharacterSet
> -->
143 <OutDir
>..\\</OutDir
>
144 <!-- <IntDir
>\
$(ProjectDir
)\
$(Configuration
)\\</IntDir
> -->
146 <Import Project
="\$(VCTargetsPath)\\Microsoft.Cpp.props" />
147 <ImportGroup Label
="ExtensionSettings">
149 <ImportGroup Label
="Shared">
151 <ImportGroup Label
="PropertySheets">
152 <Import Project
="\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props" Condition
="exists('\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props')" Label
="LocalAppDataPlatform" />
154 <PropertyGroup Label
="UserMacros" />
156 <GenerateManifest
>false
</GenerateManifest
>
157 <EnableManagedIncrementalBuild
>true
</EnableManagedIncrementalBuild
>
159 <ItemDefinitionGroup
>
161 <AdditionalOptions
>$cflags %(AdditionalOptions
)</AdditionalOptions
>
162 <AdditionalIncludeDirectories
>$cdup;$cdup\\compat
;$cdup\\compat
\\regex
;$cdup\\compat
\\win32
;$cdup\\compat
\\poll
;$cdup\\compat
\\vcbuild
\\include
;\
$(VCPKGIncludeDirectory
);%(AdditionalIncludeDirectories
)</AdditionalIncludeDirectories
>
163 <EnableParallelCodeGeneration
/>
164 <InlineFunctionExpansion
>OnlyExplicitInline
</InlineFunctionExpansion
>
165 <PrecompiledHeader
/>
166 <DebugInformationFormat
>ProgramDatabase
</DebugInformationFormat
>
169 <SuppressStartupBanner
>true
</SuppressStartupBanner
>
172 <AdditionalLibraryDirectories
>\
$(VCPKGLibDirectory
);%(AdditionalLibraryDirectories
)</AdditionalLibraryDirectories
>
173 <AdditionalDependencies
>\
$(VCPKGLibs
);\
$(AdditionalDependencies
)</AdditionalDependencies
>
174 <AdditionalOptions
>invalidcontinue
.obj
%(AdditionalOptions
)</AdditionalOptions
>
175 <EntryPointSymbol
>wmainCRTStartup
</EntryPointSymbol
>
176 <ManifestFile
>$cdup\\compat
\\win32
\\git
.manifest
</ManifestFile
>
177 <SubSystem
>Console
</SubSystem
>
180 if ($target eq 'libgit') {
182 <PreBuildEvent Condition
="!Exists('$cdup\\compat\\vcbuild\\vcpkg\\installed\\\$(VCPKGArch)\\include\\openssl\\ssl.h')">
183 <Message
>Initialize VCPKG
</Message
>
184 <Command
>del
"$cdup\\compat\\vcbuild\\vcpkg"</Command
>
185 <Command
>call
"$cdup\\compat\\vcbuild\\vcpkg_install.bat"</Command
>
190 </ItemDefinitionGroup
>
191 <ItemDefinitionGroup Condition
="'\$(Platform)'=='Win32'">
193 <TargetMachine
>MachineX86
</TargetMachine
>
195 </ItemDefinitionGroup
>
196 <ItemDefinitionGroup Condition
="'\$(Configuration)'=='Debug'">
198 <Optimization
>Disabled
</Optimization
>
199 <PreprocessorDefinitions
>WIN32
;_DEBUG
;$defines;%(PreprocessorDefinitions
)</PreprocessorDefinitions
>
200 <RuntimeLibrary
>MultiThreadedDebugDLL
</RuntimeLibrary
>
203 <GenerateDebugInformation
>true
</GenerateDebugInformation
>
205 </ItemDefinitionGroup
>
206 <ItemDefinitionGroup Condition
="'\$(Configuration)'=='Release'">
208 <Optimization
>MaxSpeed
</Optimization
>
209 <IntrinsicFunctions
>true
</IntrinsicFunctions
>
210 <PreprocessorDefinitions
>WIN32
;NDEBUG
;$defines;%(PreprocessorDefinitions
)</PreprocessorDefinitions
>
211 <RuntimeLibrary
>MultiThreadedDLL
</RuntimeLibrary
>
212 <FunctionLevelLinking
>true
</FunctionLevelLinking
>
213 <FavorSizeOrSpeed
>Speed
</FavorSizeOrSpeed
>
216 <GenerateDebugInformation
>true
</GenerateDebugInformation
>
217 <EnableCOMDATFolding
>true
</EnableCOMDATFolding
>
218 <OptimizeReferences
>true
</OptimizeReferences
>
220 </ItemDefinitionGroup
>
225 <ClCompile Include
="$_" />
231 if (!$static_library || $target =~ 'vcs-svn' || $target =~ 'xdiff') {
232 my $uuid_libgit = $$build_structure{"LIBS_libgit_GUID"};
233 my $uuid_xdiff_lib = $$build_structure{"LIBS_xdiff/lib_GUID"};
237 <ProjectReference Include
="$cdup\\libgit\\libgit.vcxproj">
238 <Project
>$uuid_libgit</Project
>
239 <ReferenceOutputAssembly
>false
</ReferenceOutputAssembly
>
242 if (!($name =~ 'xdiff')) {
244 <ProjectReference Include
="$cdup\\xdiff\\lib\\xdiff_lib.vcxproj">
245 <Project
>$uuid_xdiff_lib</Project
>
246 <ReferenceOutputAssembly
>false
</ReferenceOutputAssembly
>
250 if ($name =~ /(test-(line-buffer|svn-fe)|^git-remote-testsvn)\.exe$/) {
251 my $uuid_vcs_svn_lib = $$build_structure{"LIBS_vcs-svn/lib_GUID"};
253 <ProjectReference Include
="$cdup\\vcs-svn\\lib\\vcs-svn_lib.vcxproj">
254 <Project
>$uuid_vcs_svn_lib</Project
>
255 <ReferenceOutputAssembly
>false
</ReferenceOutputAssembly
>
264 <Import Project
="\$(VCTargetsPath)\\Microsoft.Cpp.targets" />
266 if (!$static_library) {
268 <Target Name
="${target}_AfterBuild" AfterTargets
="AfterBuild">
270 <DLLsAndPDBs Include
="\$(VCPKGBinDirectory)\\*.dll;\$(VCPKGBinDirectory)\\*.pdb" />
272 <Copy SourceFiles
="@(DLLsAndPDBs)" DestinationFolder
="\$(OutDir)" SkipUnchangedFiles
="true" UseHardlinksIfPossible
="true" />
273 <MakeDir Directories
="..\\templates\\blt\\branches" />
277 if ($target eq 'git') {
278 print F
" <Import Project=\"LinkOrCopyBuiltins.targets\" />\n";
286 sub createGlueProject
{
287 my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
288 print "Generate solutions file\n";
289 $rel_dir = "..\\$rel_dir";
290 $rel_dir =~ s/\//\\/g
;
291 my $SLN_HEAD = "Microsoft Visual Studio Solution File, Format Version 11.00\n# Visual Studio 2010\n";
292 my $SLN_PRE = "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = ";
293 my $SLN_POST = "\nEndProject\n";
295 my @libs = @
{$build_structure{"LIBS"}};
303 my @apps = @
{$build_structure{"APPS"}};
315 open F
, ">git.sln" || die "Could not open git.sln for writing!\n";
316 binmode F
, ":crlf :utf8";
322 my $uuid = $build_structure{"APPS_${appname}_GUID"};
324 my $vcxproj = $build_structure{"APPS_${appname}_VCXPROJ"};
325 $vcxproj =~ s/\//\\/g
;
326 $appname =~ s/.*\///;
327 print F
"\"${appname}\", \"${vcxproj}\", \"${uuid}\"";
332 my $uuid = $build_structure{"LIBS_${libname}_GUID"};
334 my $vcxproj = $build_structure{"LIBS_${libname}_VCXPROJ"};
335 $vcxproj =~ s/\//\\/g
;
336 $libname =~ s/\//_
/g
;
337 print F
"\"${libname}\", \"${vcxproj}\", \"${uuid}\"";
343 GlobalSection
(SolutionConfigurationPlatforms
) = preSolution
344 Debug
|x64
= Debug
|x64
345 Debug
|x86
= Debug
|x86
346 Release
|x64
= Release
|x64
347 Release
|x86
= Release
|x86
351 GlobalSection
(ProjectConfigurationPlatforms
) = postSolution
355 my $uuid = $build_structure{"APPS_${appname}_GUID"};
356 print F
"\t\t${uuid}.Debug|x64.ActiveCfg = Debug|x64\n";
357 print F
"\t\t${uuid}.Debug|x64.Build.0 = Debug|x64\n";
358 print F
"\t\t${uuid}.Debug|x86.ActiveCfg = Debug|Win32\n";
359 print F
"\t\t${uuid}.Debug|x86.Build.0 = Debug|Win32\n";
360 print F
"\t\t${uuid}.Release|x64.ActiveCfg = Release|x64\n";
361 print F
"\t\t${uuid}.Release|x64.Build.0 = Release|x64\n";
362 print F
"\t\t${uuid}.Release|x86.ActiveCfg = Release|Win32\n";
363 print F
"\t\t${uuid}.Release|x86.Build.0 = Release|Win32\n";
367 my $uuid = $build_structure{"LIBS_${libname}_GUID"};
368 print F
"\t\t${uuid}.Debug|x64.ActiveCfg = Debug|x64\n";
369 print F
"\t\t${uuid}.Debug|x64.Build.0 = Debug|x64\n";
370 print F
"\t\t${uuid}.Debug|x86.ActiveCfg = Debug|Win32\n";
371 print F
"\t\t${uuid}.Debug|x86.Build.0 = Debug|Win32\n";
372 print F
"\t\t${uuid}.Release|x64.ActiveCfg = Release|x64\n";
373 print F
"\t\t${uuid}.Release|x64.Build.0 = Release|x64\n";
374 print F
"\t\t${uuid}.Release|x86.ActiveCfg = Release|Win32\n";
375 print F
"\t\t${uuid}.Release|x86.Build.0 = Release|Win32\n";
380 GlobalSection
(SolutionProperties
) = preSolution
381 HideSolutionNode
= FALSE