1 package Generators::Vcproj;
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 createLibProject($_, $git_dir, $out_dir, $rel_dir, \%build_structure);
30 my @apps = @{$build_structure{"APPS"}};
32 createAppProject($_, $git_dir, $out_dir, $rel_dir, \%build_structure);
35 createGlueProject($git_dir, $out_dir, $rel_dir, %build_structure);
39 sub createLibProject {
40 my ($libname, $git_dir, $out_dir, $rel_dir, $build_structure) = @_;
41 print "Generate $libname vcproj lib project\n";
42 $rel_dir = "..\\$rel_dir";
43 $rel_dir =~ s/\//\\/g;
45 my $target = $libname;
49 my $uuid = generate_guid($libname);
50 $$build_structure{"LIBS_${target}_GUID"} = $uuid;
52 my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"LIBS_${libname}_SOURCES"}}));
58 my $defines = join(",", sort(@{$$build_structure{"LIBS_${libname}_DEFINES"}}));
59 my $includes= join(";", sort(map(""$rel_dir\\$_"", @{$$build_structure{"LIBS_${libname}_INCLUDES"}})));
60 my $cflags = join(" ", sort(@{$$build_structure{"LIBS_${libname}_CFLAGS"}}));
61 $cflags =~ s/\"/"/g;
63 my $cflags_debug = $cflags;
64 $cflags_debug =~ s/-MT/-MTd/;
65 $cflags_debug =~ s/-O.//;
67 my $cflags_release = $cflags;
68 $cflags_release =~ s/-MTd/-MT/;
70 my @tmp = @{$$build_structure{"LIBS_${libname}_LFLAGS"}};
75 $_ =~ s/^-L/-LIBPATH:$rel_dir\//;
79 my $lflags = join(" ", sort(@tmp));
82 $defines =~ s/\"/\\"/g;
85 mkdir "$target" || die "Could not create the directory $target for lib project!\n";
86 open F, ">$target/$target.vcproj" || die "Could not open $target/$target.pro for writing!\n";
89 <?xml version="1.0" encoding = "Windows-1252"?>
91 ProjectType="Visual C++"
104 OutputDirectory="$rel_dir"
105 ConfigurationType="4"
107 IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
110 Name="VCPreBuildEventTool"
113 Name="VCCustomBuildTool"
116 Name="VCXMLDataGeneratorTool"
119 Name="VCWebServiceProxyGeneratorTool"
125 Name="VCCLCompilerTool"
126 AdditionalOptions="$cflags_debug"
128 InlineFunctionExpansion="1"
129 AdditionalIncludeDirectories="$includes"
130 PreprocessorDefinitions="WIN32,_DEBUG,$defines"
131 MinimalRebuild="true"
133 UsePrecompiledHeader="0"
134 ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
136 DebugInformationFormat="3"
139 Name="VCManagedResourceCompilerTool"
142 Name="VCResourceCompilerTool"
145 Name="VCPreLinkEventTool"
148 Name="VCLibrarianTool"
149 SuppressStartupBanner="true"
164 Name="VCPostBuildEventTool"
169 OutputDirectory="$rel_dir"
170 ConfigurationType="4"
172 WholeProgramOptimization="1"
173 IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
176 Name="VCPreBuildEventTool"
179 Name="VCCustomBuildTool"
182 Name="VCXMLDataGeneratorTool"
185 Name="VCWebServiceProxyGeneratorTool"
191 Name="VCCLCompilerTool"
192 AdditionalOptions="$cflags_release"
194 InlineFunctionExpansion="1"
195 EnableIntrinsicFunctions="true"
196 AdditionalIncludeDirectories="$includes"
197 PreprocessorDefinitions="WIN32,NDEBUG,$defines"
199 EnableFunctionLevelLinking="true"
200 UsePrecompiledHeader="0"
201 ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
203 DebugInformationFormat="3"
206 Name="VCManagedResourceCompilerTool"
209 Name="VCResourceCompilerTool"
212 Name="VCPreLinkEventTool"
215 Name="VCLibrarianTool"
216 SuppressStartupBanner="true"
231 Name="VCPostBuildEventTool"
238 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
239 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
252 </VisualStudioProject>
257 sub createAppProject {
258 my ($appname, $git_dir, $out_dir, $rel_dir, $build_structure) = @_;
259 print "Generate $appname vcproj app project\n";
260 $rel_dir = "..\\$rel_dir";
261 $rel_dir =~ s/\//\\/g;
263 my $target = $appname;
265 $target =~ s/\.exe//;
267 my $uuid = generate_guid($appname);
268 $$build_structure{"APPS_${target}_GUID"} = $uuid;
270 my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"APPS_${appname}_SOURCES"}}));
276 my $defines = join(",", sort(@{$$build_structure{"APPS_${appname}_DEFINES"}}));
277 my $includes= join(";", sort(map(""$rel_dir\\$_"", @{$$build_structure{"APPS_${appname}_INCLUDES"}})));
278 my $cflags = join(" ", sort(@{$$build_structure{"APPS_${appname}_CFLAGS"}}));
279 $cflags =~ s/\"/"/g;
281 my $cflags_debug = $cflags;
282 $cflags_debug =~ s/-MT/-MTd/;
283 $cflags_debug =~ s/-O.//;
285 my $cflags_release = $cflags;
286 $cflags_release =~ s/-MTd/-MT/;
289 foreach (sort(@{$$build_structure{"APPS_${appname}_LIBS"}})) {
293 my @tmp = @{$$build_structure{"APPS_${appname}_LFLAGS"}};
298 $_ =~ s/^-L/-LIBPATH:$rel_dir\//;
302 my $lflags = join(" ", sort(@tmp)) . " -LIBPATH:$rel_dir";
305 $defines =~ s/\"/\\"/g;
307 $defines =~ s/\\\\/\\/g;
308 $includes =~ s/-I//g;
309 mkdir "$target" || die "Could not create the directory $target for lib project!\n";
310 open F, ">$target/$target.vcproj" || die "Could not open $target/$target.pro for writing!\n";
313 <?xml version="1.0" encoding = "Windows-1252"?>
315 ProjectType="Visual C++"
328 OutputDirectory="$rel_dir"
329 ConfigurationType="1"
331 IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
334 Name="VCPreBuildEventTool"
337 Name="VCCustomBuildTool"
340 Name="VCXMLDataGeneratorTool"
343 Name="VCWebServiceProxyGeneratorTool"
349 Name="VCCLCompilerTool"
350 AdditionalOptions="$cflags_debug"
352 InlineFunctionExpansion="1"
353 AdditionalIncludeDirectories="$includes"
354 PreprocessorDefinitions="WIN32,_DEBUG,$defines"
355 MinimalRebuild="true"
357 UsePrecompiledHeader="0"
358 ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
360 DebugInformationFormat="3"
363 Name="VCManagedResourceCompilerTool"
366 Name="VCResourceCompilerTool"
369 Name="VCPreLinkEventTool"
373 AdditionalDependencies="$libs"
374 AdditionalOptions="$lflags"
376 GenerateDebugInformation="true"
393 Name="VCPostBuildEventTool"
398 OutputDirectory="$rel_dir"
399 ConfigurationType="1"
401 WholeProgramOptimization="1"
402 IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
405 Name="VCPreBuildEventTool"
408 Name="VCCustomBuildTool"
411 Name="VCXMLDataGeneratorTool"
414 Name="VCWebServiceProxyGeneratorTool"
420 Name="VCCLCompilerTool"
421 AdditionalOptions="$cflags_release"
423 InlineFunctionExpansion="1"
424 EnableIntrinsicFunctions="true"
425 AdditionalIncludeDirectories="$includes"
426 PreprocessorDefinitions="WIN32,NDEBUG,$defines"
428 EnableFunctionLevelLinking="true"
429 UsePrecompiledHeader="0"
430 ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
432 DebugInformationFormat="3"
435 Name="VCManagedResourceCompilerTool"
438 Name="VCResourceCompilerTool"
441 Name="VCPreLinkEventTool"
445 AdditionalDependencies="$libs"
446 AdditionalOptions="$lflags"
448 GenerateDebugInformation="true"
451 OptimizeReferences="2"
452 EnableCOMDATFolding="2"
467 Name="VCPostBuildEventTool"
474 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
475 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
488 </VisualStudioProject>
493 sub createGlueProject {
494 my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
495 print "Generate solutions file\n";
496 $rel_dir = "..\\$rel_dir";
497 $rel_dir =~ s/\//\\/g;
498 my $SLN_HEAD = "Microsoft Visual Studio Solution File, Format Version 10.00\n# Visual Studio 2008\n";
499 my $SLN_PRE = "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = ";
500 my $SLN_POST = "\nEndProject\n";
502 my @libs = @{$build_structure{"LIBS"}};
511 my @apps = @{$build_structure{"APPS"}};
520 open F, ">git.sln" || die "Could not open git.sln for writing!\n";
525 my $uuid = $build_structure{"LIBS_${libname}_GUID"};
527 print F "\"${libname}\", \"${libname}\\${libname}.vcproj\", \"${uuid}\"";
530 my $uuid_libgit = $build_structure{"LIBS_libgit_GUID"};
531 my $uuid_xdiff_lib = $build_structure{"LIBS_xdiff_lib_GUID"};
534 my $uuid = $build_structure{"APPS_${appname}_GUID"};
536 print F "\"${appname}\", \"${appname}\\${appname}.vcproj\", \"${uuid}\"\n";
537 print F " ProjectSection(ProjectDependencies) = postProject\n";
538 print F " ${uuid_libgit} = ${uuid_libgit}\n";
539 print F " ${uuid_xdiff_lib} = ${uuid_xdiff_lib}\n";
540 print F " EndProjectSection";
546 GlobalSection(SolutionConfigurationPlatforms) = preSolution
547 Debug|Win32 = Debug|Win32
548 Release|Win32 = Release|Win32
552 GlobalSection(ProjectConfigurationPlatforms) = postSolution
556 my $uuid = $build_structure{"LIBS_${libname}_GUID"};
557 print F "\t\t${uuid}.Debug|Win32.ActiveCfg = Debug|Win32\n";
558 print F "\t\t${uuid}.Debug|Win32.Build.0 = Debug|Win32\n";
559 print F "\t\t${uuid}.Release|Win32.ActiveCfg = Release|Win32\n";
560 print F "\t\t${uuid}.Release|Win32.Build.0 = Release|Win32\n";
564 my $uuid = $build_structure{"APPS_${appname}_GUID"};
565 print F "\t\t${uuid}.Debug|Win32.ActiveCfg = Debug|Win32\n";
566 print F "\t\t${uuid}.Debug|Win32.Build.0 = Debug|Win32\n";
567 print F "\t\t${uuid}.Release|Win32.ActiveCfg = Release|Win32\n";
568 print F "\t\t${uuid}.Release|Win32.Build.0 = Release|Win32\n";