Vcproj.pm: auto-generate GUIDs
[git/raj.git] / contrib / buildsystems / Generators / Vcproj.pm
blobc79b706bc8de4fff4ef04b735e309b314022aaf5
1 package Generators::Vcproj;
2 require Exporter;
4 use strict;
5 use vars qw($VERSION);
6 use Digest::SHA qw(sha256_hex);
8 our $VERSION = '1.00';
9 our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE);
10 @ISA = qw(Exporter);
12 BEGIN {
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}/;
19 $hex =~ tr/a-z/A-Z/;
20 return $hex;
23 sub generate {
24 my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
25 my @libs = @{$build_structure{"LIBS"}};
26 foreach (@libs) {
27 createLibProject($_, $git_dir, $out_dir, $rel_dir, \%build_structure);
30 my @apps = @{$build_structure{"APPS"}};
31 foreach (@apps) {
32 createAppProject($_, $git_dir, $out_dir, $rel_dir, \%build_structure);
35 createGlueProject($git_dir, $out_dir, $rel_dir, %build_structure);
36 return 0;
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;
46 $target =~ s/\//_/g;
47 $target =~ s/\.a//;
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"}}));
53 my @sources;
54 foreach (@srcs) {
55 $_ =~ s/\//\\/g;
56 push(@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"}};
71 my @tmp2 = ();
72 foreach (@tmp) {
73 if (/^-LTCG/) {
74 } elsif (/^-L/) {
75 $_ =~ s/^-L/-LIBPATH:$rel_dir\//;
77 push(@tmp2, $_);
79 my $lflags = join(" ", sort(@tmp));
81 $defines =~ s/-D//g;
82 $defines =~ s/\"/\\"/g;
83 $defines =~ s/\'//g;
84 $includes =~ s/-I//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";
87 binmode F, ":crlf";
88 print F << "EOM";
89 <?xml version="1.0" encoding = "Windows-1252"?>
90 <VisualStudioProject
91 ProjectType="Visual C++"
92 Version="9,00"
93 Name="$target"
94 ProjectGUID="$uuid">
95 <Platforms>
96 <Platform
97 Name="Win32"/>
98 </Platforms>
99 <ToolFiles>
100 </ToolFiles>
101 <Configurations>
102 <Configuration
103 Name="Debug|Win32"
104 OutputDirectory="$rel_dir"
105 ConfigurationType="4"
106 CharacterSet="0"
107 IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
109 <Tool
110 Name="VCPreBuildEventTool"
112 <Tool
113 Name="VCCustomBuildTool"
115 <Tool
116 Name="VCXMLDataGeneratorTool"
118 <Tool
119 Name="VCWebServiceProxyGeneratorTool"
121 <Tool
122 Name="VCMIDLTool"
124 <Tool
125 Name="VCCLCompilerTool"
126 AdditionalOptions="$cflags_debug"
127 Optimization="0"
128 InlineFunctionExpansion="1"
129 AdditionalIncludeDirectories="$includes"
130 PreprocessorDefinitions="WIN32,_DEBUG,$defines"
131 MinimalRebuild="true"
132 RuntimeLibrary="1"
133 UsePrecompiledHeader="0"
134 ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
135 WarningLevel="3"
136 DebugInformationFormat="3"
138 <Tool
139 Name="VCManagedResourceCompilerTool"
141 <Tool
142 Name="VCResourceCompilerTool"
144 <Tool
145 Name="VCPreLinkEventTool"
147 <Tool
148 Name="VCLibrarianTool"
149 SuppressStartupBanner="true"
151 <Tool
152 Name="VCALinkTool"
154 <Tool
155 Name="VCXDCMakeTool"
157 <Tool
158 Name="VCBscMakeTool"
160 <Tool
161 Name="VCFxCopTool"
163 <Tool
164 Name="VCPostBuildEventTool"
166 </Configuration>
167 <Configuration
168 Name="Release|Win32"
169 OutputDirectory="$rel_dir"
170 ConfigurationType="4"
171 CharacterSet="0"
172 WholeProgramOptimization="1"
173 IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
175 <Tool
176 Name="VCPreBuildEventTool"
178 <Tool
179 Name="VCCustomBuildTool"
181 <Tool
182 Name="VCXMLDataGeneratorTool"
184 <Tool
185 Name="VCWebServiceProxyGeneratorTool"
187 <Tool
188 Name="VCMIDLTool"
190 <Tool
191 Name="VCCLCompilerTool"
192 AdditionalOptions="$cflags_release"
193 Optimization="2"
194 InlineFunctionExpansion="1"
195 EnableIntrinsicFunctions="true"
196 AdditionalIncludeDirectories="$includes"
197 PreprocessorDefinitions="WIN32,NDEBUG,$defines"
198 RuntimeLibrary="0"
199 EnableFunctionLevelLinking="true"
200 UsePrecompiledHeader="0"
201 ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
202 WarningLevel="3"
203 DebugInformationFormat="3"
205 <Tool
206 Name="VCManagedResourceCompilerTool"
208 <Tool
209 Name="VCResourceCompilerTool"
211 <Tool
212 Name="VCPreLinkEventTool"
214 <Tool
215 Name="VCLibrarianTool"
216 SuppressStartupBanner="true"
218 <Tool
219 Name="VCALinkTool"
221 <Tool
222 Name="VCXDCMakeTool"
224 <Tool
225 Name="VCBscMakeTool"
227 <Tool
228 Name="VCFxCopTool"
230 <Tool
231 Name="VCPostBuildEventTool"
233 </Configuration>
234 </Configurations>
235 <Files>
236 <Filter
237 Name="Source Files"
238 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
239 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
241 foreach(@sources) {
242 print F << "EOM";
243 <File
244 RelativePath="$_"/>
247 print F << "EOM";
248 </Filter>
249 </Files>
250 <Globals>
251 </Globals>
252 </VisualStudioProject>
254 close F;
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;
264 $target =~ s/\//_/g;
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"}}));
271 my @sources;
272 foreach (@srcs) {
273 $_ =~ s/\//\\/g;
274 push(@sources, $_);
276 my $defines = join(",", sort(@{$$build_structure{"APPS_${appname}_DEFINES"}}));
277 my $includes= join(";", sort(map("&quot;$rel_dir\\$_&quot;", @{$$build_structure{"APPS_${appname}_INCLUDES"}})));
278 my $cflags = join(" ", sort(@{$$build_structure{"APPS_${appname}_CFLAGS"}}));
279 $cflags =~ s/\"/&quot;/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/;
288 my $libs;
289 foreach (sort(@{$$build_structure{"APPS_${appname}_LIBS"}})) {
290 $_ =~ s/\//_/g;
291 $libs .= " $_";
293 my @tmp = @{$$build_structure{"APPS_${appname}_LFLAGS"}};
294 my @tmp2 = ();
295 foreach (@tmp) {
296 if (/^-LTCG/) {
297 } elsif (/^-L/) {
298 $_ =~ s/^-L/-LIBPATH:$rel_dir\//;
300 push(@tmp2, $_);
302 my $lflags = join(" ", sort(@tmp)) . " -LIBPATH:$rel_dir";
304 $defines =~ s/-D//g;
305 $defines =~ s/\"/\\&quot;/g;
306 $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";
311 binmode F, ":crlf";
312 print F << "EOM";
313 <?xml version="1.0" encoding = "Windows-1252"?>
314 <VisualStudioProject
315 ProjectType="Visual C++"
316 Version="9,00"
317 Name="$target"
318 ProjectGUID="$uuid">
319 <Platforms>
320 <Platform
321 Name="Win32"/>
322 </Platforms>
323 <ToolFiles>
324 </ToolFiles>
325 <Configurations>
326 <Configuration
327 Name="Debug|Win32"
328 OutputDirectory="$rel_dir"
329 ConfigurationType="1"
330 CharacterSet="0"
331 IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
333 <Tool
334 Name="VCPreBuildEventTool"
336 <Tool
337 Name="VCCustomBuildTool"
339 <Tool
340 Name="VCXMLDataGeneratorTool"
342 <Tool
343 Name="VCWebServiceProxyGeneratorTool"
345 <Tool
346 Name="VCMIDLTool"
348 <Tool
349 Name="VCCLCompilerTool"
350 AdditionalOptions="$cflags_debug"
351 Optimization="0"
352 InlineFunctionExpansion="1"
353 AdditionalIncludeDirectories="$includes"
354 PreprocessorDefinitions="WIN32,_DEBUG,$defines"
355 MinimalRebuild="true"
356 RuntimeLibrary="1"
357 UsePrecompiledHeader="0"
358 ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
359 WarningLevel="3"
360 DebugInformationFormat="3"
362 <Tool
363 Name="VCManagedResourceCompilerTool"
365 <Tool
366 Name="VCResourceCompilerTool"
368 <Tool
369 Name="VCPreLinkEventTool"
371 <Tool
372 Name="VCLinkerTool"
373 AdditionalDependencies="$libs"
374 AdditionalOptions="$lflags"
375 LinkIncremental="2"
376 GenerateDebugInformation="true"
377 SubSystem="1"
378 TargetMachine="1"
380 <Tool
381 Name="VCALinkTool"
383 <Tool
384 Name="VCXDCMakeTool"
386 <Tool
387 Name="VCBscMakeTool"
389 <Tool
390 Name="VCFxCopTool"
392 <Tool
393 Name="VCPostBuildEventTool"
395 </Configuration>
396 <Configuration
397 Name="Release|Win32"
398 OutputDirectory="$rel_dir"
399 ConfigurationType="1"
400 CharacterSet="0"
401 WholeProgramOptimization="1"
402 IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
404 <Tool
405 Name="VCPreBuildEventTool"
407 <Tool
408 Name="VCCustomBuildTool"
410 <Tool
411 Name="VCXMLDataGeneratorTool"
413 <Tool
414 Name="VCWebServiceProxyGeneratorTool"
416 <Tool
417 Name="VCMIDLTool"
419 <Tool
420 Name="VCCLCompilerTool"
421 AdditionalOptions="$cflags_release"
422 Optimization="2"
423 InlineFunctionExpansion="1"
424 EnableIntrinsicFunctions="true"
425 AdditionalIncludeDirectories="$includes"
426 PreprocessorDefinitions="WIN32,NDEBUG,$defines"
427 RuntimeLibrary="0"
428 EnableFunctionLevelLinking="true"
429 UsePrecompiledHeader="0"
430 ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
431 WarningLevel="3"
432 DebugInformationFormat="3"
434 <Tool
435 Name="VCManagedResourceCompilerTool"
437 <Tool
438 Name="VCResourceCompilerTool"
440 <Tool
441 Name="VCPreLinkEventTool"
443 <Tool
444 Name="VCLinkerTool"
445 AdditionalDependencies="$libs"
446 AdditionalOptions="$lflags"
447 LinkIncremental="1"
448 GenerateDebugInformation="true"
449 SubSystem="1"
450 TargetMachine="1"
451 OptimizeReferences="2"
452 EnableCOMDATFolding="2"
454 <Tool
455 Name="VCALinkTool"
457 <Tool
458 Name="VCXDCMakeTool"
460 <Tool
461 Name="VCBscMakeTool"
463 <Tool
464 Name="VCFxCopTool"
466 <Tool
467 Name="VCPostBuildEventTool"
469 </Configuration>
470 </Configurations>
471 <Files>
472 <Filter
473 Name="Source Files"
474 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
475 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
477 foreach(@sources) {
478 print F << "EOM";
479 <File
480 RelativePath="$_"/>
483 print F << "EOM";
484 </Filter>
485 </Files>
486 <Globals>
487 </Globals>
488 </VisualStudioProject>
490 close F;
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"}};
503 my @tmp;
504 foreach (@libs) {
505 $_ =~ s/\//_/g;
506 $_ =~ s/\.a//;
507 push(@tmp, $_);
509 @libs = @tmp;
511 my @apps = @{$build_structure{"APPS"}};
512 @tmp = ();
513 foreach (@apps) {
514 $_ =~ s/\//_/g;
515 $_ =~ s/\.exe//;
516 push(@tmp, $_);
518 @apps = @tmp;
520 open F, ">git.sln" || die "Could not open git.sln for writing!\n";
521 binmode F, ":crlf";
522 print F "$SLN_HEAD";
523 foreach (@libs) {
524 my $libname = $_;
525 my $uuid = $build_structure{"LIBS_${libname}_GUID"};
526 print F "$SLN_PRE";
527 print F "\"${libname}\", \"${libname}\\${libname}.vcproj\", \"${uuid}\"";
528 print F "$SLN_POST";
530 my $uuid_libgit = $build_structure{"LIBS_libgit_GUID"};
531 my $uuid_xdiff_lib = $build_structure{"LIBS_xdiff_lib_GUID"};
532 foreach (@apps) {
533 my $appname = $_;
534 my $uuid = $build_structure{"APPS_${appname}_GUID"};
535 print F "$SLN_PRE";
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";
541 print F "$SLN_POST";
544 print F << "EOM";
545 Global
546 GlobalSection(SolutionConfigurationPlatforms) = preSolution
547 Debug|Win32 = Debug|Win32
548 Release|Win32 = Release|Win32
549 EndGlobalSection
551 print F << "EOM";
552 GlobalSection(ProjectConfigurationPlatforms) = postSolution
554 foreach (@libs) {
555 my $libname = $_;
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";
562 foreach (@apps) {
563 my $appname = $_;
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";
571 print F << "EOM";
572 EndGlobalSection
573 EndGlobal
575 close F;