1package Generators::Vcproj;
2require Exporter;
3
4use strict;
5use vars qw($VERSION);
6
7our $VERSION = '1.00';
8our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE);
9@ISA = qw(Exporter);
10
11BEGIN {
12 push @EXPORT_OK, qw(generate);
13}
14
15my $guid_index = 0;
16my @GUIDS = (
17 "{E07B9989-2BF7-4F21-8918-BE22BA467AC3}",
18 "{278FFB51-0296-4A44-A81A-22B87B7C3592}",
19 "{7346A2C4-F0FD-444F-9EBE-1AF23B2B5650}",
20 "{67F421AC-EB34-4D49-820B-3196807B423F}",
21 "{385DCFE1-CC8C-4211-A451-80FCFC31CA51}",
22 "{97CC46C5-D2CC-4D26-B634-E75792B79916}",
23 "{C7CE21FE-6EF8-4012-A5C7-A22BCEDFBA11}",
24 "{51575134-3FDF-42D1-BABD-3FB12669C6C9}",
25 "{0AE195E4-9823-4B87-8E6F-20C5614AF2FF}",
26 "{4B918255-67CA-43BB-A46C-26704B666E6B}",
27 "{18CCFEEF-C8EE-4CC1-A265-26F95C9F4649}",
28 "{5D5D90FA-01B7-4973-AFE5-CA88C53AC197}",
29 "{1F054320-036D-49E1-B384-FB5DF0BC8AC0}",
30 "{7CED65EE-F2D9-4171-825B-C7D561FE5786}",
31 "{8D341679-0F07-4664-9A56-3BA0DE88B9BC}",
32 "{C189FEDC-2957-4BD7-9FA4-7622241EA145}",
33 "{66844203-1B9F-4C53-9274-164FFF95B847}",
34 "{E4FEA145-DECC-440D-AEEA-598CF381FD43}",
35 "{73300A8E-C8AC-41B0-B555-4F596B681BA7}",
36 "{873FDEB1-D01D-40BF-A1BF-8BBC58EC0F51}",
37 "{7922C8BE-76C5-4AC6-8BF7-885C0F93B782}",
38 "{E245D370-308B-4A49-BFC1-1E527827975F}",
39 "{F6FA957B-66FC-4ED7-B260-E59BBE4FE813}",
40 "{E6055070-0198-431A-BC49-8DB6CEE770AE}",
41 "{54159234-C3EB-43DA-906B-CE5DA5C74654}",
42 "{594CFC35-0B60-46F6-B8EF-9983ACC1187D}",
43 "{D93FCAB7-1F01-48D2-B832-F761B83231A5}",
44 "{DBA5E6AC-E7BE-42D3-8703-4E787141526E}",
45 "{6171953F-DD26-44C7-A3BE-CC45F86FC11F}",
46 "{9E19DDBE-F5E4-4A26-A2FE-0616E04879B8}",
47 "{AE81A615-99E3-4885-9CE0-D9CAA193E867}",
48 "{FBF4067E-1855-4F6C-8BCD-4D62E801A04D}",
49 "{17007948-6593-4AEB-8106-F7884B4F2C19}",
50 "{199D4C8D-8639-4DA6-82EF-08668C35DEE0}",
51 "{E085E50E-C140-4CF3-BE4B-094B14F0DDD6}",
52 "{00785268-A9CC-4E40-AC29-BAC0019159CE}",
53 "{4C06F56A-DCDB-46A6-B67C-02339935CF12}",
54 "{3A62D3FD-519E-4EC9-8171-D2C1BFEA022F}",
55 "{3A62D3FD-519E-4EC9-8171-D2C1BFEA022F}",
56 "{9392EB58-D7BA-410B-B1F0-B2FAA6BC89A7}",
57 "{2ACAB2D5-E0CE-4027-BCA0-D78B2D7A6C66}",
58 "{86E216C3-43CE-481A-BCB2-BE5E62850635}",
59 "{FB631291-7923-4B91-9A57-7B18FDBB7A42}",
60 "{0A176EC9-E934-45B8-B87F-16C7F4C80039}",
61 "{DF55CA80-46E8-4C53-B65B-4990A23DD444}",
62 "{3A0F9895-55D2-4710-BE5E-AD7498B5BF44}",
63 "{294BDC5A-F448-48B6-8110-DD0A81820F8C}",
64 "{4B9F66E9-FAC9-47AB-B1EF-C16756FBFD06}",
65 "{72EA49C6-2806-48BD-B81B-D4905102E19C}",
66 "{5728EB7E-8929-486C-8CD5-3238D060E768}"
67);
68
69sub generate {
70 my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
71 my @libs = @{$build_structure{"LIBS"}};
72 foreach (@libs) {
73 createLibProject($_, $git_dir, $out_dir, $rel_dir, \%build_structure);
74 }
75
76 my @apps = @{$build_structure{"APPS"}};
77 foreach (@apps) {
78 createAppProject($_, $git_dir, $out_dir, $rel_dir, \%build_structure);
79 }
80
81 createGlueProject($git_dir, $out_dir, $rel_dir, %build_structure);
82 return 0;
83}
84
85sub createLibProject {
86 my ($libname, $git_dir, $out_dir, $rel_dir, $build_structure) = @_;
87 print "Generate $libname vcproj lib project\n";
88 $rel_dir = "..\\$rel_dir";
89 $rel_dir =~ s/\//\\/g;
90
91 my $target = $libname;
92 $target =~ s/\//_/g;
93 $target =~ s/\.a//;
94
95 my $uuid = $GUIDS[$guid_index];
96 $$build_structure{"LIBS_${target}_GUID"} = $uuid;
97 $guid_index += 1;
98
99 my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"LIBS_${libname}_SOURCES"}}));
100 my @sources;
101 foreach (@srcs) {
102 $_ =~ s/\//\\/g;
103 push(@sources, $_);
104 }
105 my $defines = join(",", sort(@{$$build_structure{"LIBS_${libname}_DEFINES"}}));
106 my $includes= join(";", sort(map(""$rel_dir\\$_"", @{$$build_structure{"LIBS_${libname}_INCLUDES"}})));
107 my $cflags = join(" ", sort(@{$$build_structure{"LIBS_${libname}_CFLAGS"}}));
108 $cflags =~ s/\"/"/g;
109
110 my $cflags_debug = $cflags;
111 $cflags_debug =~ s/-MT/-MTd/;
112 $cflags_debug =~ s/-O.//;
113
114 my $cflags_release = $cflags;
115 $cflags_release =~ s/-MTd/-MT/;
116
117 my @tmp = @{$$build_structure{"LIBS_${libname}_LFLAGS"}};
118 my @tmp2 = ();
119 foreach (@tmp) {
120 if (/^-LTCG/) {
121 } elsif (/^-L/) {
122 $_ =~ s/^-L/-LIBPATH:$rel_dir\//;
123 }
124 push(@tmp2, $_);
125 }
126 my $lflags = join(" ", sort(@tmp));
127
128 $defines =~ s/-D//g;
129 $defines =~ s/\"/\\"/g;
130 $defines =~ s/\'//g;
131 $includes =~ s/-I//g;
132 mkdir "$target" || die "Could not create the directory $target for lib project!\n";
133 open F, ">$target/$target.vcproj" || die "Could not open $target/$target.pro for writing!\n";
134 binmode F, ":crlf";
135 print F << "EOM";
136<?xml version="1.0" encoding = "Windows-1252"?>
137<VisualStudioProject
138 ProjectType="Visual C++"
139 Version="9,00"
140 Name="$target"
141 ProjectGUID="$uuid">
142 <Platforms>
143 <Platform
144 Name="Win32"/>
145 </Platforms>
146 <ToolFiles>
147 </ToolFiles>
148 <Configurations>
149 <Configuration
150 Name="Debug|Win32"
151 OutputDirectory="$rel_dir"
152 ConfigurationType="4"
153 CharacterSet="0"
154 IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
155 >
156 <Tool
157 Name="VCPreBuildEventTool"
158 />
159 <Tool
160 Name="VCCustomBuildTool"
161 />
162 <Tool
163 Name="VCXMLDataGeneratorTool"
164 />
165 <Tool
166 Name="VCWebServiceProxyGeneratorTool"
167 />
168 <Tool
169 Name="VCMIDLTool"
170 />
171 <Tool
172 Name="VCCLCompilerTool"
173 AdditionalOptions="$cflags_debug"
174 Optimization="0"
175 InlineFunctionExpansion="1"
176 AdditionalIncludeDirectories="$includes"
177 PreprocessorDefinitions="WIN32,_DEBUG,$defines"
178 MinimalRebuild="true"
179 RuntimeLibrary="1"
180 UsePrecompiledHeader="0"
181 ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
182 WarningLevel="3"
183 DebugInformationFormat="3"
184 />
185 <Tool
186 Name="VCManagedResourceCompilerTool"
187 />
188 <Tool
189 Name="VCResourceCompilerTool"
190 />
191 <Tool
192 Name="VCPreLinkEventTool"
193 />
194 <Tool
195 Name="VCLibrarianTool"
196 SuppressStartupBanner="true"
197 />
198 <Tool
199 Name="VCALinkTool"
200 />
201 <Tool
202 Name="VCXDCMakeTool"
203 />
204 <Tool
205 Name="VCBscMakeTool"
206 />
207 <Tool
208 Name="VCFxCopTool"
209 />
210 <Tool
211 Name="VCPostBuildEventTool"
212 />
213 </Configuration>
214 <Configuration
215 Name="Release|Win32"
216 OutputDirectory="$rel_dir"
217 ConfigurationType="4"
218 CharacterSet="0"
219 WholeProgramOptimization="1"
220 IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
221 >
222 <Tool
223 Name="VCPreBuildEventTool"
224 />
225 <Tool
226 Name="VCCustomBuildTool"
227 />
228 <Tool
229 Name="VCXMLDataGeneratorTool"
230 />
231 <Tool
232 Name="VCWebServiceProxyGeneratorTool"
233 />
234 <Tool
235 Name="VCMIDLTool"
236 />
237 <Tool
238 Name="VCCLCompilerTool"
239 AdditionalOptions="$cflags_release"
240 Optimization="2"
241 InlineFunctionExpansion="1"
242 EnableIntrinsicFunctions="true"
243 AdditionalIncludeDirectories="$includes"
244 PreprocessorDefinitions="WIN32,NDEBUG,$defines"
245 RuntimeLibrary="0"
246 EnableFunctionLevelLinking="true"
247 UsePrecompiledHeader="0"
248 ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
249 WarningLevel="3"
250 DebugInformationFormat="3"
251 />
252 <Tool
253 Name="VCManagedResourceCompilerTool"
254 />
255 <Tool
256 Name="VCResourceCompilerTool"
257 />
258 <Tool
259 Name="VCPreLinkEventTool"
260 />
261 <Tool
262 Name="VCLibrarianTool"
263 SuppressStartupBanner="true"
264 />
265 <Tool
266 Name="VCALinkTool"
267 />
268 <Tool
269 Name="VCXDCMakeTool"
270 />
271 <Tool
272 Name="VCBscMakeTool"
273 />
274 <Tool
275 Name="VCFxCopTool"
276 />
277 <Tool
278 Name="VCPostBuildEventTool"
279 />
280 </Configuration>
281 </Configurations>
282 <Files>
283 <Filter
284 Name="Source Files"
285 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
286 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
287EOM
288 foreach(@sources) {
289 print F << "EOM";
290 <File
291 RelativePath="$_"/>
292EOM
293 }
294 print F << "EOM";
295 </Filter>
296 </Files>
297 <Globals>
298 </Globals>
299</VisualStudioProject>
300EOM
301 close F;
302}
303
304sub createAppProject {
305 my ($appname, $git_dir, $out_dir, $rel_dir, $build_structure) = @_;
306 print "Generate $appname vcproj app project\n";
307 $rel_dir = "..\\$rel_dir";
308 $rel_dir =~ s/\//\\/g;
309
310 my $target = $appname;
311 $target =~ s/\//_/g;
312 $target =~ s/\.exe//;
313
314 my $uuid = $GUIDS[$guid_index];
315 $$build_structure{"APPS_${target}_GUID"} = $uuid;
316 $guid_index += 1;
317
318 my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"APPS_${appname}_SOURCES"}}));
319 my @sources;
320 foreach (@srcs) {
321 $_ =~ s/\//\\/g;
322 push(@sources, $_);
323 }
324 my $defines = join(",", sort(@{$$build_structure{"APPS_${appname}_DEFINES"}}));
325 my $includes= join(";", sort(map(""$rel_dir\\$_"", @{$$build_structure{"APPS_${appname}_INCLUDES"}})));
326 my $cflags = join(" ", sort(@{$$build_structure{"APPS_${appname}_CFLAGS"}}));
327 $cflags =~ s/\"/"/g;
328
329 my $cflags_debug = $cflags;
330 $cflags_debug =~ s/-MT/-MTd/;
331 $cflags_debug =~ s/-O.//;
332
333 my $cflags_release = $cflags;
334 $cflags_release =~ s/-MTd/-MT/;
335
336 my $libs;
337 foreach (sort(@{$$build_structure{"APPS_${appname}_LIBS"}})) {
338 $_ =~ s/\//_/g;
339 $libs .= " $_";
340 }
341 my @tmp = @{$$build_structure{"APPS_${appname}_LFLAGS"}};
342 my @tmp2 = ();
343 foreach (@tmp) {
344 if (/^-LTCG/) {
345 } elsif (/^-L/) {
346 $_ =~ s/^-L/-LIBPATH:$rel_dir\//;
347 }
348 push(@tmp2, $_);
349 }
350 my $lflags = join(" ", sort(@tmp)) . " -LIBPATH:$rel_dir";
351
352 $defines =~ s/-D//g;
353 $defines =~ s/\"/\\"/g;
354 $defines =~ s/\'//g;
355 $defines =~ s/\\\\/\\/g;
356 $includes =~ s/-I//g;
357 mkdir "$target" || die "Could not create the directory $target for lib project!\n";
358 open F, ">$target/$target.vcproj" || die "Could not open $target/$target.pro for writing!\n";
359 binmode F, ":crlf";
360 print F << "EOM";
361<?xml version="1.0" encoding = "Windows-1252"?>
362<VisualStudioProject
363 ProjectType="Visual C++"
364 Version="9,00"
365 Name="$target"
366 ProjectGUID="$uuid">
367 <Platforms>
368 <Platform
369 Name="Win32"/>
370 </Platforms>
371 <ToolFiles>
372 </ToolFiles>
373 <Configurations>
374 <Configuration
375 Name="Debug|Win32"
376 OutputDirectory="$rel_dir"
377 ConfigurationType="1"
378 CharacterSet="0"
379 IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
380 >
381 <Tool
382 Name="VCPreBuildEventTool"
383 />
384 <Tool
385 Name="VCCustomBuildTool"
386 />
387 <Tool
388 Name="VCXMLDataGeneratorTool"
389 />
390 <Tool
391 Name="VCWebServiceProxyGeneratorTool"
392 />
393 <Tool
394 Name="VCMIDLTool"
395 />
396 <Tool
397 Name="VCCLCompilerTool"
398 AdditionalOptions="$cflags_debug"
399 Optimization="0"
400 InlineFunctionExpansion="1"
401 AdditionalIncludeDirectories="$includes"
402 PreprocessorDefinitions="WIN32,_DEBUG,$defines"
403 MinimalRebuild="true"
404 RuntimeLibrary="1"
405 UsePrecompiledHeader="0"
406 ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
407 WarningLevel="3"
408 DebugInformationFormat="3"
409 />
410 <Tool
411 Name="VCManagedResourceCompilerTool"
412 />
413 <Tool
414 Name="VCResourceCompilerTool"
415 />
416 <Tool
417 Name="VCPreLinkEventTool"
418 />
419 <Tool
420 Name="VCLinkerTool"
421 AdditionalDependencies="$libs"
422 AdditionalOptions="$lflags"
423 LinkIncremental="2"
424 GenerateDebugInformation="true"
425 SubSystem="1"
426 TargetMachine="1"
427 />
428 <Tool
429 Name="VCALinkTool"
430 />
431 <Tool
432 Name="VCXDCMakeTool"
433 />
434 <Tool
435 Name="VCBscMakeTool"
436 />
437 <Tool
438 Name="VCFxCopTool"
439 />
440 <Tool
441 Name="VCPostBuildEventTool"
442 />
443 </Configuration>
444 <Configuration
445 Name="Release|Win32"
446 OutputDirectory="$rel_dir"
447 ConfigurationType="1"
448 CharacterSet="0"
449 WholeProgramOptimization="1"
450 IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
451 >
452 <Tool
453 Name="VCPreBuildEventTool"
454 />
455 <Tool
456 Name="VCCustomBuildTool"
457 />
458 <Tool
459 Name="VCXMLDataGeneratorTool"
460 />
461 <Tool
462 Name="VCWebServiceProxyGeneratorTool"
463 />
464 <Tool
465 Name="VCMIDLTool"
466 />
467 <Tool
468 Name="VCCLCompilerTool"
469 AdditionalOptions="$cflags_release"
470 Optimization="2"
471 InlineFunctionExpansion="1"
472 EnableIntrinsicFunctions="true"
473 AdditionalIncludeDirectories="$includes"
474 PreprocessorDefinitions="WIN32,NDEBUG,$defines"
475 RuntimeLibrary="0"
476 EnableFunctionLevelLinking="true"
477 UsePrecompiledHeader="0"
478 ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
479 WarningLevel="3"
480 DebugInformationFormat="3"
481 />
482 <Tool
483 Name="VCManagedResourceCompilerTool"
484 />
485 <Tool
486 Name="VCResourceCompilerTool"
487 />
488 <Tool
489 Name="VCPreLinkEventTool"
490 />
491 <Tool
492 Name="VCLinkerTool"
493 AdditionalDependencies="$libs"
494 AdditionalOptions="$lflags"
495 LinkIncremental="1"
496 GenerateDebugInformation="true"
497 SubSystem="1"
498 TargetMachine="1"
499 OptimizeReferences="2"
500 EnableCOMDATFolding="2"
501 />
502 <Tool
503 Name="VCALinkTool"
504 />
505 <Tool
506 Name="VCXDCMakeTool"
507 />
508 <Tool
509 Name="VCBscMakeTool"
510 />
511 <Tool
512 Name="VCFxCopTool"
513 />
514 <Tool
515 Name="VCPostBuildEventTool"
516 />
517 </Configuration>
518 </Configurations>
519 <Files>
520 <Filter
521 Name="Source Files"
522 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
523 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
524EOM
525 foreach(@sources) {
526 print F << "EOM";
527 <File
528 RelativePath="$_"/>
529EOM
530 }
531 print F << "EOM";
532 </Filter>
533 </Files>
534 <Globals>
535 </Globals>
536</VisualStudioProject>
537EOM
538 close F;
539}
540
541sub createGlueProject {
542 my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
543 print "Generate solutions file\n";
544 $rel_dir = "..\\$rel_dir";
545 $rel_dir =~ s/\//\\/g;
546 my $SLN_HEAD = "Microsoft Visual Studio Solution File, Format Version 10.00\n# Visual Studio 2008\n";
547 my $SLN_PRE = "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = ";
548 my $SLN_POST = "\nEndProject\n";
549
550 my @libs = @{$build_structure{"LIBS"}};
551 my @tmp;
552 foreach (@libs) {
553 $_ =~ s/\//_/g;
554 $_ =~ s/\.a//;
555 push(@tmp, $_);
556 }
557 @libs = @tmp;
558
559 my @apps = @{$build_structure{"APPS"}};
560 @tmp = ();
561 foreach (@apps) {
562 $_ =~ s/\//_/g;
563 $_ =~ s/\.exe//;
564 push(@tmp, $_);
565 }
566 @apps = @tmp;
567
568 open F, ">git.sln" || die "Could not open git.sln for writing!\n";
569 binmode F, ":crlf";
570 print F "$SLN_HEAD";
571 foreach (@libs) {
572 my $libname = $_;
573 my $uuid = $build_structure{"LIBS_${libname}_GUID"};
574 print F "$SLN_PRE";
575 print F "\"${libname}\", \"${libname}\\${libname}.vcproj\", \"${uuid}\"";
576 print F "$SLN_POST";
577 }
578 my $uuid_libgit = $build_structure{"LIBS_libgit_GUID"};
579 my $uuid_xdiff_lib = $build_structure{"LIBS_xdiff_lib_GUID"};
580 foreach (@apps) {
581 my $appname = $_;
582 my $uuid = $build_structure{"APPS_${appname}_GUID"};
583 print F "$SLN_PRE";
584 print F "\"${appname}\", \"${appname}\\${appname}.vcproj\", \"${uuid}\"\n";
585 print F " ProjectSection(ProjectDependencies) = postProject\n";
586 print F " ${uuid_libgit} = ${uuid_libgit}\n";
587 print F " ${uuid_xdiff_lib} = ${uuid_xdiff_lib}\n";
588 print F " EndProjectSection";
589 print F "$SLN_POST";
590 }
591
592 print F << "EOM";
593Global
594 GlobalSection(SolutionConfigurationPlatforms) = preSolution
595 Debug|Win32 = Debug|Win32
596 Release|Win32 = Release|Win32
597 EndGlobalSection
598EOM
599 print F << "EOM";
600 GlobalSection(ProjectConfigurationPlatforms) = postSolution
601EOM
602 foreach (@libs) {
603 my $libname = $_;
604 my $uuid = $build_structure{"LIBS_${libname}_GUID"};
605 print F "\t\t${uuid}.Debug|Win32.ActiveCfg = Debug|Win32\n";
606 print F "\t\t${uuid}.Debug|Win32.Build.0 = Debug|Win32\n";
607 print F "\t\t${uuid}.Release|Win32.ActiveCfg = Release|Win32\n";
608 print F "\t\t${uuid}.Release|Win32.Build.0 = Release|Win32\n";
609 }
610 foreach (@apps) {
611 my $appname = $_;
612 my $uuid = $build_structure{"APPS_${appname}_GUID"};
613 print F "\t\t${uuid}.Debug|Win32.ActiveCfg = Debug|Win32\n";
614 print F "\t\t${uuid}.Debug|Win32.Build.0 = Debug|Win32\n";
615 print F "\t\t${uuid}.Release|Win32.ActiveCfg = Release|Win32\n";
616 print F "\t\t${uuid}.Release|Win32.Build.0 = Release|Win32\n";
617 }
618
619 print F << "EOM";
620 EndGlobalSection
621EndGlobal
622EOM
623 close F;
624}
625
6261;