]> granicus.if.org Git - postgresql/blob - src/tools/msvc/Solution.pm
3a173a6a0201385fc8b1b6d2cfb13991912294ab
[postgresql] / src / tools / msvc / Solution.pm
1 package Solution;
2
3 #
4 # Package that encapsulates a Visual C++ solution file generation
5 #
6 # src/tools/msvc/Solution.pm
7 #
8 use Carp;
9 use strict;
10 use warnings;
11 use VSObjectFactory;
12
13 sub _new
14 {
15         my $classname = shift;
16         my $options   = shift;
17         my $self      = {
18                 projects => {},
19                 options  => $options,
20                 numver   => '',
21                 strver   => '',
22                 vcver    => undef,
23                 platform => undef, };
24         bless($self, $classname);
25
26         # integer_datetimes is now the default
27         $options->{integer_datetimes} = 1
28           unless exists $options->{integer_datetimes};
29         $options->{float4byval} = 1
30           unless exists $options->{float4byval};
31         if ($options->{xml})
32         {
33                 if (!($options->{xslt} && $options->{iconv}))
34                 {
35                         die "XML requires both XSLT and ICONV\n";
36                 }
37         }
38         $options->{blocksize} = 8
39           unless $options->{blocksize};    # undef or 0 means default
40         die "Bad blocksize $options->{blocksize}"
41           unless grep { $_ == $options->{blocksize} } (1, 2, 4, 8, 16, 32);
42         $options->{segsize} = 1
43           unless $options->{segsize};      # undef or 0 means default
44          # only allow segsize 1 for now, as we can't do large files yet in windows
45         die "Bad segsize $options->{segsize}"
46           unless $options->{segsize} == 1;
47         $options->{wal_blocksize} = 8
48           unless $options->{wal_blocksize};    # undef or 0 means default
49         die "Bad wal_blocksize $options->{wal_blocksize}"
50           unless grep { $_ == $options->{wal_blocksize} }
51                   (1, 2, 4, 8, 16, 32, 64);
52         $options->{wal_segsize} = 16
53           unless $options->{wal_segsize};      # undef or 0 means default
54         die "Bad wal_segsize $options->{wal_segsize}"
55           unless grep { $_ == $options->{wal_segsize} } (1, 2, 4, 8, 16, 32, 64);
56
57         $self->DeterminePlatform();
58
59         return $self;
60 }
61
62 sub DeterminePlatform
63 {
64         my $self = shift;
65
66         # Examine CL help output to determine if we are in 32 or 64-bit mode.
67         $self->{platform} = 'Win32';
68         open(P, "cl /? 2>&1 |") || die "cl command not found";
69         while (<P>)
70         {
71                 if (/^\/favor:<.+AMD64/)
72                 {
73                         $self->{platform} = 'x64';
74                         last;
75                 }
76         }
77         close(P);
78         print "Detected hardware platform: $self->{platform}\n";
79 }
80
81 # Return 1 if $oldfile is newer than $newfile, or if $newfile doesn't exist.
82 # Special case - if config.pl has changed, always return 1
83 sub IsNewer
84 {
85         my ($newfile, $oldfile) = @_;
86         if (   $oldfile ne 'src\tools\msvc\config.pl'
87                 && $oldfile ne 'src\tools\msvc\config_default.pl')
88         {
89                 return 1
90                   if (-f 'src\tools\msvc\config.pl')
91                   && IsNewer($newfile, 'src\tools\msvc\config.pl');
92                 return 1
93                   if (-f 'src\tools\msvc\config_default.pl')
94                   && IsNewer($newfile, 'src\tools\msvc\config_default.pl');
95         }
96         return 1 if (!(-e $newfile));
97         my @nstat = stat($newfile);
98         my @ostat = stat($oldfile);
99         return 1 if ($nstat[9] < $ostat[9]);
100         return 0;
101 }
102
103 # Copy a file, *not* preserving date. Only works for text files.
104 sub copyFile
105 {
106         my ($src, $dest) = @_;
107         open(I, $src)     || croak "Could not open $src";
108         open(O, ">$dest") || croak "Could not open $dest";
109         while (<I>)
110         {
111                 print O;
112         }
113         close(I);
114         close(O);
115 }
116
117 sub GenerateFiles
118 {
119         my $self = shift;
120         my $bits = $self->{platform} eq 'Win32' ? 32 : 64;
121
122         # Parse configure.in to get version numbers
123         open(C, "configure.in")
124           || confess("Could not open configure.in for reading\n");
125         while (<C>)
126         {
127                 if (/^AC_INIT\(\[PostgreSQL\], \[([^\]]+)\]/)
128                 {
129                         $self->{strver} = $1;
130                         if ($self->{strver} !~ /^(\d+)\.(\d+)(?:\.(\d+))?/)
131                         {
132                                 confess "Bad format of version: $self->{strver}\n";
133                         }
134                         $self->{numver} = sprintf("%d%02d%02d", $1, $2, $3 ? $3 : 0);
135                         $self->{majorver} = sprintf("%d.%d", $1, $2);
136                 }
137         }
138         close(C);
139         confess "Unable to parse configure.in for all variables!"
140           if ($self->{strver} eq '' || $self->{numver} eq '');
141
142         if (IsNewer(
143                         "src\\include\\pg_config_os.h", "src\\include\\port\\win32.h"))
144         {
145                 print "Copying pg_config_os.h...\n";
146                 copyFile("src\\include\\port\\win32.h",
147                         "src\\include\\pg_config_os.h");
148         }
149
150         if (IsNewer(
151                         "src\\include\\pg_config.h", "src\\include\\pg_config.h.win32"))
152         {
153                 print "Generating pg_config.h...\n";
154                 open(I, "src\\include\\pg_config.h.win32")
155                   || confess "Could not open pg_config.h.win32\n";
156                 open(O, ">src\\include\\pg_config.h")
157                   || confess "Could not write to pg_config.h\n";
158                 while (<I>)
159                 {
160                         s{PG_VERSION "[^"]+"}{PG_VERSION "$self->{strver}"};
161                         s{PG_VERSION_NUM \d+}{PG_VERSION_NUM $self->{numver}};
162 s{PG_VERSION_STR "[^"]+"}{__STRINGIFY(x) #x\n#define __STRINGIFY2(z) __STRINGIFY(z)\n#define PG_VERSION_STR "PostgreSQL $self->{strver}, compiled by Visual C++ build " __STRINGIFY2(_MSC_VER) ", $bits-bit"};
163                         print O;
164                 }
165                 print O "#define PG_MAJORVERSION \"$self->{majorver}\"\n";
166                 print O "#define LOCALEDIR \"/share/locale\"\n"
167                   if ($self->{options}->{nls});
168                 print O "/* defines added by config steps */\n";
169                 print O "#ifndef IGNORE_CONFIGURED_SETTINGS\n";
170                 print O "#define USE_ASSERT_CHECKING 1\n"
171                   if ($self->{options}->{asserts});
172                 print O "#define USE_INTEGER_DATETIMES 1\n"
173                   if ($self->{options}->{integer_datetimes});
174                 print O "#define USE_LDAP 1\n"   if ($self->{options}->{ldap});
175                 print O "#define HAVE_LIBZ 1\n"  if ($self->{options}->{zlib});
176                 print O "#define USE_SSL 1\n"    if ($self->{options}->{openssl});
177                 print O "#define ENABLE_NLS 1\n" if ($self->{options}->{nls});
178
179                 print O "#define BLCKSZ ", 1024 * $self->{options}->{blocksize}, "\n";
180                 print O "#define RELSEG_SIZE ",
181                   (1024 / $self->{options}->{blocksize}) *
182                   $self->{options}->{segsize} *
183                   1024, "\n";
184                 print O "#define XLOG_BLCKSZ ",
185                   1024 * $self->{options}->{wal_blocksize}, "\n";
186                 print O "#define XLOG_SEG_SIZE (", $self->{options}->{wal_segsize},
187                   " * 1024 * 1024)\n";
188
189                 if ($self->{options}->{float4byval})
190                 {
191                         print O "#define USE_FLOAT4_BYVAL 1\n";
192                         print O "#define FLOAT4PASSBYVAL true\n";
193                 }
194                 else
195                 {
196                         print O "#define FLOAT4PASSBYVAL false\n";
197                 }
198                 if ($self->{options}->{float8byval})
199                 {
200                         print O "#define USE_FLOAT8_BYVAL 1\n";
201                         print O "#define FLOAT8PASSBYVAL true\n";
202                 }
203                 else
204                 {
205                         print O "#define FLOAT8PASSBYVAL false\n";
206                 }
207
208                 if ($self->{options}->{uuid})
209                 {
210                         print O "#define HAVE_UUID_H\n";
211                 }
212                 if ($self->{options}->{xml})
213                 {
214                         print O "#define HAVE_LIBXML2\n";
215                         print O "#define USE_LIBXML\n";
216                 }
217                 if ($self->{options}->{xslt})
218                 {
219                         print O "#define HAVE_LIBXSLT\n";
220                         print O "#define USE_LIBXSLT\n";
221                 }
222                 if ($self->{options}->{gss})
223                 {
224                         print O "#define ENABLE_GSS 1\n";
225                 }
226                 if (my $port = $self->{options}->{"--with-pgport"})
227                 {
228                         print O "#undef DEF_PGPORT\n";
229                         print O "#undef DEF_PGPORT_STR\n";
230                         print O "#define DEF_PGPORT $port\n";
231                         print O "#define DEF_PGPORT_STR \"$port\"\n";
232                 }
233                 print O "#define VAL_CONFIGURE \""
234                   . $self->GetFakeConfigure() . "\"\n";
235                 print O "#endif /* IGNORE_CONFIGURED_SETTINGS */\n";
236                 close(O);
237                 close(I);
238         }
239
240         if (IsNewer(
241                         "src\\include\\pg_config_ext.h",
242                         "src\\include\\pg_config_ext.h.win32"))
243         {
244                 print "Copying pg_config_ext.h...\n";
245                 copyFile(
246                         "src\\include\\pg_config_ext.h.win32",
247                         "src\\include\\pg_config_ext.h");
248         }
249
250         $self->GenerateDefFile(
251                 "src\\interfaces\\libpq\\libpqdll.def",
252                 "src\\interfaces\\libpq\\exports.txt",
253                 "LIBPQ");
254         $self->GenerateDefFile(
255                 "src\\interfaces\\ecpg\\ecpglib\\ecpglib.def",
256                 "src\\interfaces\\ecpg\\ecpglib\\exports.txt",
257                 "LIBECPG");
258         $self->GenerateDefFile(
259                 "src\\interfaces\\ecpg\\compatlib\\compatlib.def",
260                 "src\\interfaces\\ecpg\\compatlib\\exports.txt",
261                 "LIBECPG_COMPAT");
262         $self->GenerateDefFile(
263                 "src\\interfaces\\ecpg\\pgtypeslib\\pgtypeslib.def",
264                 "src\\interfaces\\ecpg\\pgtypeslib\\exports.txt",
265                 "LIBPGTYPES");
266
267         if (IsNewer(
268                         'src\backend\utils\fmgrtab.c', 'src\include\catalog\pg_proc.h'))
269         {
270                 print "Generating fmgrtab.c and fmgroids.h...\n";
271                 chdir('src\backend\utils');
272                 system(
273 "perl -I ../catalog Gen_fmgrtab.pl ../../../src/include/catalog/pg_proc.h");
274                 chdir('..\..\..');
275         }
276         if (IsNewer(
277                         'src\include\utils\fmgroids.h',
278                         'src\backend\utils\fmgroids.h'))
279         {
280                 copyFile('src\backend\utils\fmgroids.h',
281                         'src\include\utils\fmgroids.h');
282         }
283
284         if (IsNewer('src\include\utils\probes.h', 'src\backend\utils\probes.d'))
285         {
286                 print "Generating probes.h...\n";
287                 system(
288 'psed -f src\backend\utils\Gen_dummy_probes.sed src\backend\utils\probes.d > src\include\utils\probes.h'
289                 );
290         }
291
292         if ($self->{options}->{python}
293                 && IsNewer(
294                         'src\pl\plpython\spiexceptions.h',
295                         'src\include\backend\errcodes.txt'))
296         {
297                 print "Generating spiexceptions.h...\n";
298                 system(
299 'perl src\pl\plpython\generate-spiexceptions.pl src\backend\utils\errcodes.txt > src\pl\plpython\spiexceptions.h'
300                 );
301         }
302
303         if (IsNewer(
304                         'src\include\utils\errcodes.h',
305                         'src\backend\utils\errcodes.txt'))
306         {
307                 print "Generating errcodes.h...\n";
308                 system(
309 'perl src\backend\utils\generate-errcodes.pl src\backend\utils\errcodes.txt > src\backend\utils\errcodes.h'
310                 );
311                 copyFile('src\backend\utils\errcodes.h',
312                         'src\include\utils\errcodes.h');
313         }
314
315         if (IsNewer(
316                         'src\pl\plpgsql\src\plerrcodes.h',
317                         'src\backend\utils\errcodes.txt'))
318         {
319                 print "Generating plerrcodes.h...\n";
320                 system(
321 'perl src\pl\plpgsql\src\generate-plerrcodes.pl src\backend\utils\errcodes.txt > src\pl\plpgsql\src\plerrcodes.h'
322                 );
323         }
324
325         if (IsNewer(
326                         'src\backend\utils\sort\qsort_tuple.c',
327                         'src\backend\utils\sort\gen_qsort_tuple.pl'))
328         {
329                 print "Generating qsort_tuple.c...\n";
330                 system(
331 'perl src\backend\utils\sort\gen_qsort_tuple.pl > src\backend\utils\sort\qsort_tuple.c'
332                 );
333         }
334
335         if (IsNewer(
336                         'src\interfaces\libpq\libpq.rc',
337                         'src\interfaces\libpq\libpq.rc.in'))
338         {
339                 print "Generating libpq.rc...\n";
340                 my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
341                   localtime(time);
342                 my $d = ($year - 100) . "$yday";
343                 open(I, '<', 'src\interfaces\libpq\libpq.rc.in')
344                   || confess "Could not open libpq.rc.in";
345                 open(O, '>', 'src\interfaces\libpq\libpq.rc')
346                   || confess "Could not open libpq.rc";
347                 while (<I>)
348                 {
349                         s/(VERSION.*),0/$1,$d/;
350                         print O;
351                 }
352                 close(I);
353                 close(O);
354         }
355
356         if (IsNewer('src\bin\psql\sql_help.h', 'src\bin\psql\create_help.pl'))
357         {
358                 print "Generating sql_help.h...\n";
359                 chdir('src\bin\psql');
360                 system("perl create_help.pl ../../../doc/src/sgml/ref sql_help");
361                 chdir('..\..\..');
362         }
363
364         if (IsNewer(
365                         'src\interfaces\ecpg\preproc\preproc.y',
366                         'src\backend\parser\gram.y'))
367         {
368                 print "Generating preproc.y...\n";
369                 chdir('src\interfaces\ecpg\preproc');
370                 system('perl parse.pl < ..\..\..\backend\parser\gram.y > preproc.y');
371                 chdir('..\..\..\..');
372         }
373
374         if (IsNewer(
375                         'src\interfaces\ecpg\include\ecpg_config.h',
376                         'src\interfaces\ecpg\include\ecpg_config.h.in'))
377         {
378                 print "Generating ecpg_config.h...\n";
379                 open(O, '>', 'src\interfaces\ecpg\include\ecpg_config.h')
380                   || confess "Could not open ecpg_config.h";
381                 print O <<EOF;
382 #if (_MSC_VER > 1200)
383 #define HAVE_LONG_LONG_INT_64
384 #define ENABLE_THREAD_SAFETY 1
385 EOF
386                 print O "#define USE_INTEGER_DATETIMES 1\n"
387                   if ($self->{options}->{integer_datetimes});
388                 print O "#endif\n";
389                 close(O);
390         }
391
392         unless (-f "src\\port\\pg_config_paths.h")
393         {
394                 print "Generating pg_config_paths.h...\n";
395                 open(O, '>', 'src\port\pg_config_paths.h')
396                   || confess "Could not open pg_config_paths.h";
397                 print O <<EOF;
398 #define PGBINDIR "/bin"
399 #define PGSHAREDIR "/share"
400 #define SYSCONFDIR "/etc"
401 #define INCLUDEDIR "/include"
402 #define PKGINCLUDEDIR "/include"
403 #define INCLUDEDIRSERVER "/include/server"
404 #define LIBDIR "/lib"
405 #define PKGLIBDIR "/lib"
406 #define LOCALEDIR "/share/locale"
407 #define DOCDIR "/doc"
408 #define HTMLDIR "/doc"
409 #define MANDIR "/man"
410 EOF
411                 close(O);
412         }
413
414         my $mf = Project::read_file('src\backend\catalog\Makefile');
415         $mf =~ s{\\s*[\r\n]+}{}mg;
416         $mf =~ /^POSTGRES_BKI_SRCS\s*:?=[^,]+,(.*)\)$/gm
417           || croak "Could not find POSTGRES_BKI_SRCS in Makefile\n";
418         my @allbki = split /\s+/, $1;
419         foreach my $bki (@allbki)
420         {
421                 next if $bki eq "";
422                 if (IsNewer(
423                                 'src/backend/catalog/postgres.bki',
424                                 "src/include/catalog/$bki"))
425                 {
426                         print "Generating postgres.bki and schemapg.h...\n";
427                         chdir('src\backend\catalog');
428                         my $bki_srcs = join(' ../../../src/include/catalog/', @allbki);
429                         system(
430 "perl genbki.pl -I../../../src/include/catalog --set-version=$self->{majorver} $bki_srcs"
431                         );
432                         chdir('..\..\..');
433                         copyFile(
434                                 'src\backend\catalog\schemapg.h',
435                                 'src\include\catalog\schemapg.h');
436                         last;
437                 }
438         }
439
440         open(O, ">doc/src/sgml/version.sgml")
441           || croak "Could not write to version.sgml\n";
442         print O <<EOF;
443 <!ENTITY version "$self->{strver}">
444 <!ENTITY majorversion "$self->{majorver}">
445 EOF
446         close(O);
447 }
448
449 sub GenerateDefFile
450 {
451         my ($self, $deffile, $txtfile, $libname) = @_;
452
453         if (IsNewer($deffile, $txtfile))
454         {
455                 print "Generating $deffile...\n";
456                 open(I, $txtfile)    || confess("Could not open $txtfile\n");
457                 open(O, ">$deffile") || confess("Could not open $deffile\n");
458                 print O "LIBRARY $libname\nEXPORTS\n";
459                 while (<I>)
460                 {
461                         next if (/^#/);
462                         next if (/^\s*$/);
463                         my ($f, $o) = split;
464                         print O " $f @ $o\n";
465                 }
466                 close(O);
467                 close(I);
468         }
469 }
470
471 sub AddProject
472 {
473         my ($self, $name, $type, $folder, $initialdir) = @_;
474
475         my $proj =
476           VSObjectFactory::CreateProject($self->{vcver}, $name, $type, $self);
477         push @{ $self->{projects}->{$folder} }, $proj;
478         $proj->AddDir($initialdir) if ($initialdir);
479         if ($self->{options}->{zlib})
480         {
481                 $proj->AddIncludeDir($self->{options}->{zlib} . '\include');
482                 $proj->AddLibrary($self->{options}->{zlib} . '\lib\zdll.lib');
483         }
484         if ($self->{options}->{openssl})
485         {
486                 $proj->AddIncludeDir($self->{options}->{openssl} . '\include');
487                 $proj->AddLibrary(
488                         $self->{options}->{openssl} . '\lib\VC\ssleay32.lib', 1);
489                 $proj->AddLibrary(
490                         $self->{options}->{openssl} . '\lib\VC\libeay32.lib', 1);
491         }
492         if ($self->{options}->{nls})
493         {
494                 $proj->AddIncludeDir($self->{options}->{nls} . '\include');
495                 $proj->AddLibrary($self->{options}->{nls} . '\lib\libintl.lib');
496         }
497         if ($self->{options}->{gss})
498         {
499                 $proj->AddIncludeDir($self->{options}->{gss} . '\inc\krb5');
500                 $proj->AddLibrary($self->{options}->{gss} . '\lib\i386\krb5_32.lib');
501                 $proj->AddLibrary(
502                         $self->{options}->{gss} . '\lib\i386\comerr32.lib');
503                 $proj->AddLibrary(
504                         $self->{options}->{gss} . '\lib\i386\gssapi32.lib');
505         }
506         if ($self->{options}->{iconv})
507         {
508                 $proj->AddIncludeDir($self->{options}->{iconv} . '\include');
509                 $proj->AddLibrary($self->{options}->{iconv} . '\lib\iconv.lib');
510         }
511         if ($self->{options}->{xml})
512         {
513                 $proj->AddIncludeDir($self->{options}->{xml} . '\include');
514                 $proj->AddLibrary($self->{options}->{xml} . '\lib\libxml2.lib');
515         }
516         if ($self->{options}->{xslt})
517         {
518                 $proj->AddIncludeDir($self->{options}->{xslt} . '\include');
519                 $proj->AddLibrary($self->{options}->{xslt} . '\lib\libxslt.lib');
520         }
521         return $proj;
522 }
523
524 sub Save
525 {
526         my ($self) = @_;
527         my %flduid;
528
529         $self->GenerateFiles();
530         foreach my $fld (keys %{ $self->{projects} })
531         {
532                 foreach my $proj (@{ $self->{projects}->{$fld} })
533                 {
534                         $proj->Save();
535                 }
536         }
537
538         open(SLN, ">pgsql.sln") || croak "Could not write to pgsql.sln\n";
539         print SLN <<EOF;
540 Microsoft Visual Studio Solution File, Format Version $self->{solutionFileVersion}
541 # $self->{visualStudioName}
542 EOF
543
544         foreach my $fld (keys %{ $self->{projects} })
545         {
546                 foreach my $proj (@{ $self->{projects}->{$fld} })
547                 {
548                         print SLN <<EOF;
549 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "$proj->{name}", "$proj->{name}$proj->{filenameExtension}", "$proj->{guid}"
550 EndProject
551 EOF
552                 }
553                 if ($fld ne "")
554                 {
555                         $flduid{$fld} = Win32::GuidGen();
556                         print SLN <<EOF;
557 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "$fld", "$fld", "$flduid{$fld}"
558 EndProject
559 EOF
560                 }
561         }
562
563         print SLN <<EOF;
564 Global
565         GlobalSection(SolutionConfigurationPlatforms) = preSolution
566                 Debug|$self->{platform}= Debug|$self->{platform}
567                 Release|$self->{platform} = Release|$self->{platform}
568         EndGlobalSection
569         GlobalSection(ProjectConfigurationPlatforms) = postSolution
570 EOF
571
572         foreach my $fld (keys %{ $self->{projects} })
573         {
574                 foreach my $proj (@{ $self->{projects}->{$fld} })
575                 {
576                         print SLN <<EOF;
577                 $proj->{guid}.Debug|$self->{platform}.ActiveCfg = Debug|$self->{platform}
578                 $proj->{guid}.Debug|$self->{platform}.Build.0  = Debug|$self->{platform}
579                 $proj->{guid}.Release|$self->{platform}.ActiveCfg = Release|$self->{platform}
580                 $proj->{guid}.Release|$self->{platform}.Build.0 = Release|$self->{platform}
581 EOF
582                 }
583         }
584
585         print SLN <<EOF;
586         EndGlobalSection
587         GlobalSection(SolutionProperties) = preSolution
588                 HideSolutionNode = FALSE
589         EndGlobalSection
590         GlobalSection(NestedProjects) = preSolution
591 EOF
592
593         foreach my $fld (keys %{ $self->{projects} })
594         {
595                 next if ($fld eq "");
596                 foreach my $proj (@{ $self->{projects}->{$fld} })
597                 {
598                         print SLN "\t\t$proj->{guid} = $flduid{$fld}\n";
599                 }
600         }
601
602         print SLN <<EOF;
603         EndGlobalSection
604 EndGlobal
605 EOF
606         close(SLN);
607 }
608
609 sub GetFakeConfigure
610 {
611         my $self = shift;
612
613         my $cfg = '--enable-thread-safety';
614         $cfg .= ' --enable-cassert' if ($self->{options}->{asserts});
615         $cfg .= ' --enable-integer-datetimes'
616           if ($self->{options}->{integer_datetimes});
617         $cfg .= ' --enable-nls' if ($self->{options}->{nls});
618         $cfg .= ' --with-ldap'  if ($self->{options}->{ldap});
619         $cfg .= ' --without-zlib' unless ($self->{options}->{zlib});
620         $cfg .= ' --with-openssl'   if ($self->{options}->{ssl});
621         $cfg .= ' --with-ossp-uuid' if ($self->{options}->{uuid});
622         $cfg .= ' --with-libxml'    if ($self->{options}->{xml});
623         $cfg .= ' --with-libxslt'   if ($self->{options}->{xslt});
624         $cfg .= ' --with-gssapi'    if ($self->{options}->{gss});
625         $cfg .= ' --with-tcl'       if ($self->{options}->{tcl});
626         $cfg .= ' --with-perl'      if ($self->{options}->{perl});
627         $cfg .= ' --with-python'    if ($self->{options}->{python});
628
629         return $cfg;
630 }
631
632 package VS2005Solution;
633
634 #
635 # Package that encapsulates a Visual Studio 2005 solution file
636 #
637
638 use strict;
639 use warnings;
640 use base qw(Solution);
641
642 sub new
643 {
644         my $classname = shift;
645         my $self      = $classname->SUPER::_new(@_);
646         bless($self, $classname);
647
648         $self->{solutionFileVersion} = '9.00';
649         $self->{vcver}               = '8.00';
650         $self->{visualStudioName}    = 'Visual Studio 2005';
651
652         return $self;
653 }
654
655 package VS2008Solution;
656
657 #
658 # Package that encapsulates a Visual Studio 2008 solution file
659 #
660
661 use strict;
662 use warnings;
663 use base qw(Solution);
664
665 sub new
666 {
667         my $classname = shift;
668         my $self      = $classname->SUPER::_new(@_);
669         bless($self, $classname);
670
671         $self->{solutionFileVersion} = '10.00';
672         $self->{vcver}               = '9.00';
673         $self->{visualStudioName}    = 'Visual Studio 2008';
674
675         return $self;
676 }
677
678 package VS2010Solution;
679
680 #
681 # Package that encapsulates a Visual Studio 2010 solution file
682 #
683
684 use Carp;
685 use strict;
686 use warnings;
687 use base qw(Solution);
688
689 sub new
690 {
691         my $classname = shift;
692         my $self      = $classname->SUPER::_new(@_);
693         bless($self, $classname);
694
695         $self->{solutionFileVersion} = '11.00';
696         $self->{vcver}               = '10.00';
697         $self->{visualStudioName}    = 'Visual Studio 2010';
698
699         return $self;
700 }
701
702 package VS2012Solution;
703
704 #
705 # Package that encapsulates a Visual Studio 2012 solution file
706 #
707
708 use Carp;
709 use strict;
710 use warnings;
711 use base qw(Solution);
712
713 sub new
714 {
715         my $classname = shift;
716         my $self      = $classname->SUPER::_new(@_);
717         bless($self, $classname);
718
719         $self->{solutionFileVersion} = '12.00';
720         $self->{vcver}               = '11.00';
721         $self->{visualStudioName}    = 'Visual Studio 2012';
722
723         return $self;
724 }
725
726 1;