Skip to content

Commit e1c1e21

Browse files
committed
Enable building with Microsoft Visual Studio 2012.
Backpatch to release 9.2 Brar Piening and Noah Misch, reviewed by Craig Ringer.
1 parent 5a1cd89 commit e1c1e21

File tree

11 files changed

+213
-39
lines changed

11 files changed

+213
-39
lines changed

doc/src/sgml/install-windows.sgml

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
<para>
2020
There are several different ways of building PostgreSQL on
2121
<productname>Windows</productname>. The simplest way to build with
22-
Microsoft tools is to install a supported version of the
23-
<productname>Microsoft Windows SDK</productname> and use the included
22+
Microsoft tools is to install <productname>Visual Studio Express 2012
23+
for Windows Desktop</productname> and use the included
2424
compiler. It is also possible to build with the full
2525
<productname>Microsoft Visual C++ 2005, 2008 or 2010</productname>. In some cases
2626
that requires the installation of the <productname>Windows SDK</productname>
@@ -77,17 +77,18 @@
7777
<productname>Visual Studio Express</productname> or some versions of the
7878
<productname>Microsoft Windows SDK</productname>. If you do not already have a
7979
<productname>Visual Studio</productname> environment set up, the easiest
80-
way is to use the compilers in the <productname>Windows SDK</productname>,
81-
which is a free download from Microsoft.
80+
ways are to use the compilers in the <productname>Windows SDK 7.1</productname>
81+
or those from <productname>Visual Studio Express 2012 for Windows
82+
Desktop</productname>, which are both free downloads from Microsoft.
8283
</para>
8384

8485
<para>
8586
PostgreSQL is known to support compilation using the compilers shipped with
8687
<productname>Visual Studio 2005</productname> to
87-
<productname>Visual Studio 2010</productname> (including Express editions),
88+
<productname>Visual Studio 2012</productname> (including Express editions),
8889
as well as standalone Windows SDK releases 6.0 to 7.1.
8990
64-bit PostgreSQL builds are only supported with
90-
<productname>Microsoft Windows SDK</productname> version 6.0a and above or
91+
<productname>Microsoft Windows SDK</productname> version 6.0a to 7.1 or
9192
<productname>Visual Studio 2008</productname> and above.
9293
</para>
9394

@@ -149,17 +150,20 @@ $ENV{PATH}=$ENV{PATH} . ';c:\some\where\bison\bin';
149150
<varlistentry>
150151
<term><productname>Microsoft Windows SDK</productname></term>
151152
<listitem><para>
152-
It is recommended that you upgrade to the latest supported version
153-
of the <productname>Microsoft Windows SDK</productname> (currently
153+
If your build environment doesn't ship with a supported version of the
154+
<productname>Microsoft Windows SDK</productname> it
155+
is recommended that you upgrade to the latest version (currently
154156
version 7.1), available for download from
155157
<ulink url="http://www.microsoft.com/downloads/"></>.
156158
</para>
157159
<para>
158160
You must always include the
159161
<application>Windows Headers and Libraries</application> part of the SDK.
160-
If you install the <productname>Windows SDK</productname>
162+
If you install a <productname>Windows SDK</productname>
161163
including the <application>Visual C++ Compilers</application>,
162164
you don't need <productname>Visual Studio</productname> to build.
165+
Note that as of Version 8.0a the Windows SDK no longer ships with a
166+
complete command-line build environment.
163167
</para></listitem>
164168
</varlistentry>
165169

src/backend/utils/adt/pg_locale.c

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -715,12 +715,41 @@ cache_locale_time(void)
715715

716716
#if defined(WIN32) && defined(LC_MESSAGES)
717717
/*
718-
* Convert Windows locale name to the ISO formatted one
719-
* if possible.
718+
* Convert a Windows setlocale() argument to a Unix-style one.
720719
*
721-
* This function returns NULL if conversion is impossible,
722-
* otherwise returns the pointer to a static area which
723-
* contains the iso formatted locale name.
720+
* Regardless of platform, we install message catalogs under a Unix-style
721+
* LL[_CC][.ENCODING][@VARIANT] naming convention. Only LC_MESSAGES settings
722+
* following that style will elicit localized interface strings.
723+
*
724+
* Before Visual Studio 2012 (msvcr110.dll), Windows setlocale() accepted "C"
725+
* (but not "c") and strings of the form <Language>[_<Country>][.<CodePage>],
726+
* case-insensitive. setlocale() returns the fully-qualified form; for
727+
* example, setlocale("thaI") returns "Thai_Thailand.874". Internally,
728+
* setlocale() and _create_locale() select a "locale identifier"[1] and store
729+
* it in an undocumented _locale_t field. From that LCID, we can retrieve the
730+
* ISO 639 language and the ISO 3166 country. Character encoding does not
731+
* matter, because the server and client encodings govern that.
732+
*
733+
* Windows Vista introduced the "locale name" concept[2], closely following
734+
* RFC 4646. Locale identifiers are now deprecated. Starting with Visual
735+
* Studio 2012, setlocale() accepts locale names in addition to the strings it
736+
* accepted historically. It does not standardize them; setlocale("Th-tH")
737+
* returns "Th-tH". setlocale(category, "") still returns a traditional
738+
* string. Furthermore, msvcr110.dll changed the undocumented _locale_t
739+
* content to carry locale names instead of locale identifiers.
740+
*
741+
* MinGW headers declare _create_locale(), but msvcrt.dll lacks that symbol.
742+
* IsoLocaleName() always fails in a MinGW-built postgres.exe, so only
743+
* Unix-style values of the lc_messages GUC can elicit localized messages. In
744+
* particular, every lc_messages setting that initdb can select automatically
745+
* will yield only C-locale messages. XXX This could be fixed by running the
746+
* fully-qualified locale name through a lookup table.
747+
*
748+
* This function returns a pointer to a static buffer bearing the converted
749+
* name or NULL if conversion fails.
750+
*
751+
* [1] http://msdn.microsoft.com/en-us/library/windows/desktop/dd373763.aspx
752+
* [2] http://msdn.microsoft.com/en-us/library/windows/desktop/dd373814.aspx
724753
*/
725754
static char *
726755
IsoLocaleName(const char *winlocname)
@@ -739,6 +768,34 @@ IsoLocaleName(const char *winlocname)
739768
loct = _create_locale(LC_CTYPE, winlocname);
740769
if (loct != NULL)
741770
{
771+
#if (_MSC_VER >= 1700) /* Visual Studio 2012 or later */
772+
size_t rc;
773+
char *hyphen;
774+
775+
/* Locale names use only ASCII, any conversion locale suffices. */
776+
rc = wchar2char(iso_lc_messages, loct->locinfo->locale_name[LC_CTYPE],
777+
sizeof(iso_lc_messages), NULL);
778+
_free_locale(loct);
779+
if (rc == -1 || rc == sizeof(iso_lc_messages))
780+
return NULL;
781+
782+
/*
783+
* Since the message catalogs sit on a case-insensitive filesystem, we
784+
* need not standardize letter case here. So long as we do not ship
785+
* message catalogs for which it would matter, we also need not
786+
* translate the script/variant portion, e.g. uz-Cyrl-UZ to
787+
* uz_UZ@cyrillic. Simply replace the hyphen with an underscore.
788+
*
789+
* Note that the locale name can be less-specific than the value we
790+
* would derive under earlier Visual Studio releases. For example,
791+
* French_France.1252 yields just "fr". This does not affect any of
792+
* the country-specific message catalogs available as of this writing
793+
* (pt_BR, zh_CN, zh_TW).
794+
*/
795+
hyphen = strchr(iso_lc_messages, '-');
796+
if (hyphen)
797+
*hyphen = '_';
798+
#else
742799
char isolang[32],
743800
isocrty[32];
744801
LCID lcid;
@@ -753,6 +810,7 @@ IsoLocaleName(const char *winlocname)
753810
if (!GetLocaleInfoA(lcid, LOCALE_SISO3166CTRYNAME, isocrty, sizeof(isocrty)))
754811
return NULL;
755812
snprintf(iso_lc_messages, sizeof(iso_lc_messages) - 1, "%s_%s", isolang, isocrty);
813+
#endif
756814
return iso_lc_messages;
757815
}
758816
return NULL;

src/bin/initdb/initdb.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -935,14 +935,22 @@ find_matching_ts_config(const char *lc_type)
935935

936936
/*
937937
* Convert lc_ctype to a language name by stripping everything after an
938-
* underscore. Just for paranoia, we also stop at '.' or '@'.
938+
* underscore (usual case) or a hyphen (Windows "locale name"; see
939+
* comments at IsoLocaleName()).
940+
*
941+
* XXX Should ' ' be a stop character? This would select "norwegian" for
942+
* the Windows locale "Norwegian (Nynorsk)_Norway.1252". If we do so, we
943+
* should also accept the "nn" and "nb" Unix locales.
944+
*
945+
* Just for paranoia, we also stop at '.' or '@'.
939946
*/
940947
if (lc_type == NULL)
941948
langname = pg_strdup("");
942949
else
943950
{
944951
ptr = langname = pg_strdup(lc_type);
945-
while (*ptr && *ptr != '_' && *ptr != '.' && *ptr != '@')
952+
while (*ptr &&
953+
*ptr != '_' && *ptr != '-' && *ptr != '.' && *ptr != '@')
946954
ptr++;
947955
*ptr = '\0';
948956
}

src/port/chklocale.c

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -189,26 +189,49 @@ static const struct encoding_match encoding_match_list[] = {
189189

190190
#ifdef WIN32
191191
/*
192-
* On Windows, use CP<codepage number> instead of the nl_langinfo() result
192+
* On Windows, use CP<code page number> instead of the nl_langinfo() result
193+
*
194+
* Visual Studio 2012 expanded the set of valid LC_CTYPE values, so have its
195+
* locale machinery determine the code page. See comments at IsoLocaleName().
196+
* For other compilers, follow the locale's predictable format.
197+
*
198+
* Returns a malloc()'d string for the caller to free.
193199
*/
194200
static char *
195201
win32_langinfo(const char *ctype)
196202
{
197-
char *r;
203+
char *r = NULL;
204+
205+
#if (_MSC_VER >= 1700)
206+
_locale_t loct = NULL;
207+
208+
loct = _create_locale(LC_CTYPE, ctype);
209+
if (loct != NULL)
210+
{
211+
r = malloc(16); /* excess */
212+
if (r != NULL)
213+
sprintf(r, "CP%u", loct->locinfo->lc_codepage);
214+
_free_locale(loct);
215+
}
216+
#else
198217
char *codepage;
199-
int ln;
200218

201219
/*
202220
* Locale format on Win32 is <Language>_<Country>.<CodePage> . For
203-
* example, English_USA.1252.
221+
* example, English_United States.1252.
204222
*/
205223
codepage = strrchr(ctype, '.');
206-
if (!codepage)
207-
return NULL;
208-
codepage++;
209-
ln = strlen(codepage);
210-
r = malloc(ln + 3);
211-
sprintf(r, "CP%s", codepage);
224+
if (codepage != NULL)
225+
{
226+
int ln;
227+
228+
codepage++;
229+
ln = strlen(codepage);
230+
r = malloc(ln + 3);
231+
if (r != NULL)
232+
sprintf(r, "CP%s", codepage);
233+
}
234+
#endif
212235

213236
return r;
214237
}

src/port/win32env.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ pgwin32_putenv(const char *envval)
6060
{
6161
"msvcr90", 0, NULL
6262
}, /* Visual Studio 2008 */
63+
{
64+
"msvcr100", 0, NULL
65+
}, /* Visual Studio 2010 */
66+
{
67+
"msvcr110", 0, NULL
68+
}, /* Visual Studio 2012 */
6369
{
6470
NULL, 0, NULL
6571
}

src/tools/msvc/MSBuildProject.pm

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package MSBuildProject;
22

33
#
4-
# Package that encapsulates a MSBuild (Visual C++ 2010) project file
4+
# Package that encapsulates a MSBuild project file (Visual C++ 2010 or greater)
55
#
66
# src/tools/msvc/MSBuildProject.pm
77
#
@@ -397,4 +397,46 @@ sub new
397397
return $self;
398398
}
399399

400+
package VC2012Project;
401+
402+
#
403+
# Package that encapsulates a Visual C++ 2012 project file
404+
#
405+
406+
use strict;
407+
use warnings;
408+
use base qw(MSBuildProject);
409+
410+
sub new
411+
{
412+
my $classname = shift;
413+
my $self = $classname->SUPER::_new(@_);
414+
bless($self, $classname);
415+
416+
$self->{vcver} = '11.00';
417+
418+
return $self;
419+
}
420+
421+
# This override adds the <PlatformToolset> element
422+
# to the PropertyGroup labeled "Configuration"
423+
sub WriteConfigurationPropertyGroup
424+
{
425+
my ($self, $f, $cfgname, $p) = @_;
426+
my $cfgtype =
427+
($self->{type} eq "exe")
428+
?'Application'
429+
:($self->{type} eq "dll"?'DynamicLibrary':'StaticLibrary');
430+
431+
print $f <<EOF;
432+
<PropertyGroup Condition="'\$(Configuration)|\$(Platform)'=='$cfgname|$self->{platform}'" Label="Configuration">
433+
<ConfigurationType>$cfgtype</ConfigurationType>
434+
<UseOfMfc>false</UseOfMfc>
435+
<CharacterSet>MultiByte</CharacterSet>
436+
<WholeProgramOptimization>$p->{wholeopt}</WholeProgramOptimization>
437+
<PlatformToolset>v110</PlatformToolset>
438+
</PropertyGroup>
439+
EOF
440+
}
441+
400442
1;

src/tools/msvc/README

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,11 @@ These configuration arguments are passed over to Mkvcbuild::mkvcbuild
9292
(Mkvcbuild.pm) which creates the Visual Studio project and solution files.
9393
It does this by using VSObjectFactory::CreateSolution to create an object
9494
implementing the Solution interface (this could be either a VS2005Solution,
95-
a VS2008Solution or a VS2010Solution, all in Solution.pm, depending on the
96-
user's build environment) and adding objects implementing the corresponding
97-
Project interface (VC2005Project or VC2008Project from VCBuildProject.pm or
98-
VC2010Project from MSBuildProject.pm) to it.
95+
a VS2008Solution, a VS2010Solution or a VS2012Solution, all in Solution.pm,
96+
depending on the user's build environment) and adding objects implementing
97+
the corresponding Project interface (VC2005Project or VC2008Project from
98+
VCBuildProject.pm or VC2010Project or VC2012Project from MSBuildProject.pm)
99+
to it.
99100
When Solution::Save is called, the implementations of Solution and Project
100101
save their content in the appropriate format.
101102
The final step of starting the appropriate build program (msbuild or vcbuild)

src/tools/msvc/Solution.pm

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,12 @@ sub DeterminePlatform
6363
{
6464
my $self = shift;
6565

66-
# Determine if we are in 32 or 64-bit mode. Do this by seeing if CL has
67-
# 64-bit only parameters.
66+
# Examine CL help output to determine if we are in 32 or 64-bit mode.
6867
$self->{platform} = 'Win32';
69-
open(P, "cl /? 2>NUL|") || die "cl command not found";
68+
open(P, "cl /? 2>&1 |") || die "cl command not found";
7069
while (<P>)
7170
{
72-
if (/^\/favor:</)
71+
if (/^\/favor:<.+AMD64/)
7372
{
7473
$self->{platform} = 'x64';
7574
last;
@@ -700,4 +699,28 @@ sub new
700699
return $self;
701700
}
702701

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+
703726
1;

0 commit comments

Comments
 (0)