Merge branch 'ms/msvc'
[git] / contrib / buildsystems / Generators / Vcproj.pm
1 package Generators::Vcproj;
2 require Exporter;
3
4 use strict;
5 use vars qw($VERSION);
6
7 our $VERSION = '1.00';
8 our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE);
9 @ISA = qw(Exporter);
10
11 BEGIN {
12     push @EXPORT_OK, qw(generate);
13 }
14
15 my $guid_index = 0;
16 my @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
69 sub 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
85 sub 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                                 WarningLevel="3"
182                                 DebugInformationFormat="3"
183                         />
184                         <Tool
185                                 Name="VCManagedResourceCompilerTool"
186                         />
187                         <Tool
188                                 Name="VCResourceCompilerTool"
189                         />
190                         <Tool
191                                 Name="VCPreLinkEventTool"
192                         />
193                         <Tool
194                                 Name="VCLibrarianTool"
195                                 SuppressStartupBanner="true"
196                         />
197                         <Tool
198                                 Name="VCALinkTool"
199                         />
200                         <Tool
201                                 Name="VCXDCMakeTool"
202                         />
203                         <Tool
204                                 Name="VCBscMakeTool"
205                         />
206                         <Tool
207                                 Name="VCFxCopTool"
208                         />
209                         <Tool
210                                 Name="VCPostBuildEventTool"
211                         />
212                 </Configuration>
213                 <Configuration
214                         Name="Release|Win32"
215                         OutputDirectory="$rel_dir"
216                         ConfigurationType="4"
217                         CharacterSet="0"
218                         WholeProgramOptimization="1"
219                         IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
220                         >
221                         <Tool
222                                 Name="VCPreBuildEventTool"
223                         />
224                         <Tool
225                                 Name="VCCustomBuildTool"
226                         />
227                         <Tool
228                                 Name="VCXMLDataGeneratorTool"
229                         />
230                         <Tool
231                                 Name="VCWebServiceProxyGeneratorTool"
232                         />
233                         <Tool
234                                 Name="VCMIDLTool"
235                         />
236                         <Tool
237                                 Name="VCCLCompilerTool"
238                                 AdditionalOptions="$cflags_release"
239                                 Optimization="2"
240                                 InlineFunctionExpansion="1"
241                                 EnableIntrinsicFunctions="true"
242                                 AdditionalIncludeDirectories="$includes"
243                                 PreprocessorDefinitions="WIN32,NDEBUG,$defines"
244                                 RuntimeLibrary="0"
245                                 EnableFunctionLevelLinking="true"
246                                 UsePrecompiledHeader="0"
247                                 WarningLevel="3"
248                                 DebugInformationFormat="3"
249                         />
250                         <Tool
251                                 Name="VCManagedResourceCompilerTool"
252                         />
253                         <Tool
254                                 Name="VCResourceCompilerTool"
255                         />
256                         <Tool
257                                 Name="VCPreLinkEventTool"
258                         />
259                         <Tool
260                                 Name="VCLibrarianTool"
261                                 SuppressStartupBanner="true"
262                         />
263                         <Tool
264                                 Name="VCALinkTool"
265                         />
266                         <Tool
267                                 Name="VCXDCMakeTool"
268                         />
269                         <Tool
270                                 Name="VCBscMakeTool"
271                         />
272                         <Tool
273                                 Name="VCFxCopTool"
274                         />
275                         <Tool
276                                 Name="VCPostBuildEventTool"
277                         />
278                 </Configuration>
279         </Configurations>
280         <Files>
281                 <Filter
282                         Name="Source Files"
283                         Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
284                         UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
285 EOM
286     foreach(@sources) {
287         print F << "EOM";
288                         <File
289                                 RelativePath="$_"/>
290 EOM
291     }
292     print F << "EOM";
293                 </Filter>
294         </Files>
295         <Globals>
296         </Globals>
297 </VisualStudioProject>
298 EOM
299     close F;
300 }
301
302 sub createAppProject {
303     my ($appname, $git_dir, $out_dir, $rel_dir, $build_structure) = @_;
304     print "Generate $appname vcproj app project\n";
305     $rel_dir = "..\\$rel_dir";
306     $rel_dir =~ s/\//\\/g;
307
308     my $target = $appname;
309     $target =~ s/\//_/g;
310     $target =~ s/\.exe//;
311
312     my $uuid = $GUIDS[$guid_index];
313     $$build_structure{"APPS_${target}_GUID"} = $uuid;
314     $guid_index += 1;
315
316     my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"APPS_${appname}_SOURCES"}}));
317     my @sources;
318     foreach (@srcs) {
319         $_ =~ s/\//\\/g;
320         push(@sources, $_);
321     }
322     my $defines = join(",", sort(@{$$build_structure{"APPS_${appname}_DEFINES"}}));
323     my $includes= join(";", sort(map("&quot;$rel_dir\\$_&quot;", @{$$build_structure{"APPS_${appname}_INCLUDES"}})));
324     my $cflags  = join(" ", sort(@{$$build_structure{"APPS_${appname}_CFLAGS"}}));
325     $cflags =~ s/\"/&quot;/g;
326
327     my $cflags_debug = $cflags;
328     $cflags_debug =~ s/-MT/-MTd/;
329     $cflags_debug =~ s/-O.//;
330
331     my $cflags_release = $cflags;
332     $cflags_release =~ s/-MTd/-MT/;
333
334     my $libs;
335     foreach (sort(@{$$build_structure{"APPS_${appname}_LIBS"}})) {
336         $_ =~ s/\//_/g;
337         $libs .= " $_";
338     }
339     my @tmp  = @{$$build_structure{"APPS_${appname}_LFLAGS"}};
340     my @tmp2 = ();
341     foreach (@tmp) {
342         if (/^-LTCG/) {
343         } elsif (/^-L/) {
344             $_ =~ s/^-L/-LIBPATH:$rel_dir\//;
345         }
346         push(@tmp2, $_);
347     }
348     my $lflags = join(" ", sort(@tmp)) . " -LIBPATH:$rel_dir";
349
350     $defines =~ s/-D//g;
351     $defines =~ s/\"/\\&quot;/g;
352     $defines =~ s/\'//g;
353     $defines =~ s/\\\\/\\/g;
354     $includes =~ s/-I//g;
355     mkdir "$target" || die "Could not create the directory $target for lib project!\n";
356     open F, ">$target/$target.vcproj" || die "Could not open $target/$target.pro for writing!\n";
357     binmode F, ":crlf";
358     print F << "EOM";
359 <?xml version="1.0" encoding = "Windows-1252"?>
360 <VisualStudioProject
361         ProjectType="Visual C++"
362         Version="9,00"
363         Name="$target"
364         ProjectGUID="$uuid">
365         <Platforms>
366                 <Platform
367                         Name="Win32"/>
368         </Platforms>
369         <ToolFiles>
370         </ToolFiles>
371         <Configurations>
372                 <Configuration
373                         Name="Debug|Win32"
374                         OutputDirectory="$rel_dir"
375                         ConfigurationType="1"
376                         CharacterSet="0"
377                         IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
378                         >
379                         <Tool
380                                 Name="VCPreBuildEventTool"
381                         />
382                         <Tool
383                                 Name="VCCustomBuildTool"
384                         />
385                         <Tool
386                                 Name="VCXMLDataGeneratorTool"
387                         />
388                         <Tool
389                                 Name="VCWebServiceProxyGeneratorTool"
390                         />
391                         <Tool
392                                 Name="VCMIDLTool"
393                         />
394                         <Tool
395                                 Name="VCCLCompilerTool"
396                                 AdditionalOptions="$cflags_debug"
397                                 Optimization="0"
398                                 InlineFunctionExpansion="1"
399                                 AdditionalIncludeDirectories="$includes"
400                                 PreprocessorDefinitions="WIN32,_DEBUG,$defines"
401                                 MinimalRebuild="true"
402                                 RuntimeLibrary="1"
403                                 UsePrecompiledHeader="0"
404                                 WarningLevel="3"
405                                 DebugInformationFormat="3"
406                         />
407                         <Tool
408                                 Name="VCManagedResourceCompilerTool"
409                         />
410                         <Tool
411                                 Name="VCResourceCompilerTool"
412                         />
413                         <Tool
414                                 Name="VCPreLinkEventTool"
415                         />
416                         <Tool
417                                 Name="VCLinkerTool"
418                                 AdditionalDependencies="$libs"
419                                 AdditionalOptions="$lflags"
420                                 LinkIncremental="2"
421                                 GenerateDebugInformation="true"
422                                 SubSystem="1"
423                                 TargetMachine="1"
424                         />
425                         <Tool
426                                 Name="VCALinkTool"
427                         />
428                         <Tool
429                                 Name="VCXDCMakeTool"
430                         />
431                         <Tool
432                                 Name="VCBscMakeTool"
433                         />
434                         <Tool
435                                 Name="VCFxCopTool"
436                         />
437                         <Tool
438                                 Name="VCPostBuildEventTool"
439                         />
440                 </Configuration>
441                 <Configuration
442                         Name="Release|Win32"
443                         OutputDirectory="$rel_dir"
444                         ConfigurationType="1"
445                         CharacterSet="0"
446                         WholeProgramOptimization="1"
447                         IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
448                         >
449                         <Tool
450                                 Name="VCPreBuildEventTool"
451                         />
452                         <Tool
453                                 Name="VCCustomBuildTool"
454                         />
455                         <Tool
456                                 Name="VCXMLDataGeneratorTool"
457                         />
458                         <Tool
459                                 Name="VCWebServiceProxyGeneratorTool"
460                         />
461                         <Tool
462                                 Name="VCMIDLTool"
463                         />
464                         <Tool
465                                 Name="VCCLCompilerTool"
466                                 AdditionalOptions="$cflags_release"
467                                 Optimization="2"
468                                 InlineFunctionExpansion="1"
469                                 EnableIntrinsicFunctions="true"
470                                 AdditionalIncludeDirectories="$includes"
471                                 PreprocessorDefinitions="WIN32,NDEBUG,$defines"
472                                 RuntimeLibrary="0"
473                                 EnableFunctionLevelLinking="true"
474                                 UsePrecompiledHeader="0"
475                                 WarningLevel="3"
476                                 DebugInformationFormat="3"
477                         />
478                         <Tool
479                                 Name="VCManagedResourceCompilerTool"
480                         />
481                         <Tool
482                                 Name="VCResourceCompilerTool"
483                         />
484                         <Tool
485                                 Name="VCPreLinkEventTool"
486                         />
487                         <Tool
488                                 Name="VCLinkerTool"
489                                 AdditionalDependencies="$libs"
490                                 AdditionalOptions="$lflags"
491                                 LinkIncremental="1"
492                                 GenerateDebugInformation="true"
493                                 SubSystem="1"
494                                 TargetMachine="1"
495                                 OptimizeReferences="2"
496                                 EnableCOMDATFolding="2"
497                         />
498                         <Tool
499                                 Name="VCALinkTool"
500                         />
501                         <Tool
502                                 Name="VCXDCMakeTool"
503                         />
504                         <Tool
505                                 Name="VCBscMakeTool"
506                         />
507                         <Tool
508                                 Name="VCFxCopTool"
509                         />
510                         <Tool
511                                 Name="VCPostBuildEventTool"
512                         />
513                 </Configuration>
514         </Configurations>
515         <Files>
516                 <Filter
517                         Name="Source Files"
518                         Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
519                         UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
520 EOM
521     foreach(@sources) {
522         print F << "EOM";
523                         <File
524                                 RelativePath="$_"/>
525 EOM
526     }
527     print F << "EOM";
528                 </Filter>
529         </Files>
530         <Globals>
531         </Globals>
532 </VisualStudioProject>
533 EOM
534     close F;
535 }
536
537 sub createGlueProject {
538     my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
539     print "Generate solutions file\n";
540     $rel_dir = "..\\$rel_dir";
541     $rel_dir =~ s/\//\\/g;
542     my $SLN_HEAD = "Microsoft Visual Studio Solution File, Format Version 10.00\n# Visual Studio 2008\n";
543     my $SLN_PRE  = "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = ";
544     my $SLN_POST = "\nEndProject\n";
545
546     my @libs = @{$build_structure{"LIBS"}};
547     my @tmp;
548     foreach (@libs) {
549         $_ =~ s/\//_/g;
550         $_ =~ s/\.a//;
551         push(@tmp, $_);
552     }
553     @libs = @tmp;
554
555     my @apps = @{$build_structure{"APPS"}};
556     @tmp = ();
557     foreach (@apps) {
558         $_ =~ s/\//_/g;
559         $_ =~ s/\.exe//;
560         push(@tmp, $_);
561     }
562     @apps = @tmp;
563
564     open F, ">git.sln" || die "Could not open git.sln for writing!\n";
565     binmode F, ":crlf";
566     print F "$SLN_HEAD";
567     foreach (@libs) {
568         my $libname = $_;
569         my $uuid = $build_structure{"LIBS_${libname}_GUID"};
570         print F "$SLN_PRE";
571         print F "\"${libname}\", \"${libname}\\${libname}.vcproj\", \"${uuid}\"";
572         print F "$SLN_POST";
573     }
574     my $uuid_libgit = $build_structure{"LIBS_libgit_GUID"};
575     my $uuid_xdiff_lib = $build_structure{"LIBS_xdiff_lib_GUID"};
576     foreach (@apps) {
577         my $appname = $_;
578         my $uuid = $build_structure{"APPS_${appname}_GUID"};
579         print F "$SLN_PRE";
580         print F "\"${appname}\", \"${appname}\\${appname}.vcproj\", \"${uuid}\"\n";
581         print F "       ProjectSection(ProjectDependencies) = postProject\n";
582         print F "               ${uuid_libgit} = ${uuid_libgit}\n";
583         print F "               ${uuid_xdiff_lib} = ${uuid_xdiff_lib}\n";
584         print F "       EndProjectSection";
585         print F "$SLN_POST";
586     }
587
588     print F << "EOM";
589 Global
590         GlobalSection(SolutionConfigurationPlatforms) = preSolution
591                 Debug|Win32 = Debug|Win32
592                 Release|Win32 = Release|Win32
593         EndGlobalSection
594 EOM
595     print F << "EOM";
596         GlobalSection(ProjectConfigurationPlatforms) = postSolution
597 EOM
598     foreach (@libs) {
599         my $libname = $_;
600         my $uuid = $build_structure{"LIBS_${libname}_GUID"};
601         print F "\t\t${uuid}.Debug|Win32.ActiveCfg = Debug|Win32\n";
602         print F "\t\t${uuid}.Debug|Win32.Build.0 = Debug|Win32\n";
603         print F "\t\t${uuid}.Release|Win32.ActiveCfg = Release|Win32\n";
604         print F "\t\t${uuid}.Release|Win32.Build.0 = Release|Win32\n";
605     }
606     foreach (@apps) {
607         my $appname = $_;
608         my $uuid = $build_structure{"APPS_${appname}_GUID"};
609         print F "\t\t${uuid}.Debug|Win32.ActiveCfg = Debug|Win32\n";
610         print F "\t\t${uuid}.Debug|Win32.Build.0 = Debug|Win32\n";
611         print F "\t\t${uuid}.Release|Win32.ActiveCfg = Release|Win32\n";
612         print F "\t\t${uuid}.Release|Win32.Build.0 = Release|Win32\n";
613     }
614
615     print F << "EOM";
616         EndGlobalSection
617 EndGlobal
618 EOM
619     close F;
620 }
621
622 1;