1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-21 10:42:50 +03:00
Files
postgres/src/tools/msvc/MSBuildProject.pm
Andrew Dunstan 6e5417d773 Honor MSVC WindowsSDKVersion if set
Add a line to the project file setting the target SDK. Otherwise, in for
example VS2017, if the default but optional 8.1 SDK is not installed the
build will fail.

Patch from Peifeng Qiu, slightly edited by me.

Discussion: https://postgr.es/m/CABmtVJhw1boP_bd4=b3Qv5YnqEdL696NtHFi2ruiyQ6mFHkeQQ@mail.gmail.com

Backpatch to all live branches.
2019-07-25 11:39:26 -04:00

509 lines
14 KiB
Perl

package MSBuildProject;
#
# Package that encapsulates a MSBuild project file (Visual C++ 2013 or greater)
#
# src/tools/msvc/MSBuildProject.pm
#
use Carp;
use strict;
use warnings;
use base qw(Project);
no warnings qw(redefine); ## no critic
sub _new
{
my $classname = shift;
my $self = $classname->SUPER::_new(@_);
bless($self, $classname);
$self->{filenameExtension} = '.vcxproj';
$self->{ToolsVersion} = '4.0';
return $self;
}
sub WriteHeader
{
my ($self, $f) = @_;
print $f <<EOF;
<?xml version="1.0" encoding="Windows-1252"?>
<Project DefaultTargets="Build" ToolsVersion="$self->{ToolsVersion}" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
EOF
$self->WriteConfigurationHeader($f, 'Debug');
$self->WriteConfigurationHeader($f, 'Release');
print $f <<EOF;
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>$self->{guid}</ProjectGuid>
EOF
# Check whether WindowsSDKVersion env variable is present.
# Add WindowsTargetPlatformVersion node if so.
my $sdkVersion = $ENV{'WindowsSDKVersion'};
if (defined($sdkVersion))
{
# remove trailing backslash if necessary.
$sdkVersion, =~ s/\\$//;
print $f <<EOF
<WindowsTargetPlatformVersion>$sdkVersion</WindowsTargetPlatformVersion>
EOF
}
print $f <<EOF;
</PropertyGroup>
<Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
EOF
$self->WriteConfigurationPropertyGroup($f, 'Release',
{ wholeopt => 'false' });
$self->WriteConfigurationPropertyGroup($f, 'Debug',
{ wholeopt => 'false' });
print $f <<EOF;
<Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
EOF
$self->WritePropertySheetsPropertyGroup($f, 'Release');
$self->WritePropertySheetsPropertyGroup($f, 'Debug');
print $f <<EOF;
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
EOF
$self->WriteAdditionalProperties($f, 'Debug');
$self->WriteAdditionalProperties($f, 'Release');
print $f <<EOF;
</PropertyGroup>
EOF
$self->WriteItemDefinitionGroup(
$f, 'Debug',
{
defs => "_DEBUG;DEBUG=1",
opt => 'Disabled',
strpool => 'false',
runtime => 'MultiThreadedDebugDLL'
});
$self->WriteItemDefinitionGroup(
$f,
'Release',
{
defs => "",
opt => 'Full',
strpool => 'true',
runtime => 'MultiThreadedDLL'
});
return;
}
sub AddDefine
{
my ($self, $def) = @_;
$self->{defines} .= $def . ';';
return;
}
sub WriteReferences
{
my ($self, $f) = @_;
my @references = @{ $self->{references} };
if (scalar(@references))
{
print $f <<EOF;
<ItemGroup>
EOF
foreach my $ref (@references)
{
print $f <<EOF;
<ProjectReference Include="$ref->{name}$ref->{filenameExtension}">
<Project>$ref->{guid}</Project>
</ProjectReference>
EOF
}
print $f <<EOF;
</ItemGroup>
EOF
}
return;
}
sub WriteFiles
{
my ($self, $f) = @_;
print $f <<EOF;
<ItemGroup>
EOF
my @grammarFiles = ();
my @resourceFiles = ();
my %uniquefiles;
foreach my $fileNameWithPath (sort keys %{ $self->{files} })
{
confess "Bad format filename '$fileNameWithPath'\n"
unless ($fileNameWithPath =~ m!^(.*)/([^/]+)\.(c|cpp|y|l|rc)$!);
my $dir = $1;
my $fileName = $2;
if ($fileNameWithPath =~ /\.y$/ or $fileNameWithPath =~ /\.l$/)
{
push @grammarFiles, $fileNameWithPath;
}
elsif ($fileNameWithPath =~ /\.rc$/)
{
push @resourceFiles, $fileNameWithPath;
}
elsif (defined($uniquefiles{$fileName}))
{
# File already exists, so fake a new name
my $obj = $dir;
$obj =~ s!/!_!g;
print $f <<EOF;
<ClCompile Include="$fileNameWithPath">
<ObjectFileName Condition="'\$(Configuration)|\$(Platform)'=='Debug|$self->{platform}'">.\\debug\\$self->{name}\\${obj}_$fileName.obj</ObjectFileName>
<ObjectFileName Condition="'\$(Configuration)|\$(Platform)'=='Release|$self->{platform}'">.\\release\\$self->{name}\\${obj}_$fileName.obj</ObjectFileName>
</ClCompile>
EOF
}
else
{
$uniquefiles{$fileName} = 1;
print $f <<EOF;
<ClCompile Include="$fileNameWithPath" />
EOF
}
}
print $f <<EOF;
</ItemGroup>
EOF
if (scalar(@grammarFiles))
{
print $f <<EOF;
<ItemGroup>
EOF
foreach my $grammarFile (@grammarFiles)
{
(my $outputFile = $grammarFile) =~ s/\.(y|l)$/.c/;
if ($grammarFile =~ /\.y$/)
{
$outputFile =~
s{^src\\pl\\plpgsql\\src\\gram.c$}{src\\pl\\plpgsql\\src\\pl_gram.c};
print $f <<EOF;
<CustomBuild Include="$grammarFile">
<Message Condition="'\$(Configuration)|\$(Platform)'=='Debug|$self->{platform}'">Running bison on $grammarFile</Message>
<Command Condition="'\$(Configuration)|\$(Platform)'=='Debug|$self->{platform}'">perl "src\\tools\\msvc\\pgbison.pl" "$grammarFile"</Command>
<AdditionalInputs Condition="'\$(Configuration)|\$(Platform)'=='Debug|$self->{platform}'">%(AdditionalInputs)</AdditionalInputs>
<Outputs Condition="'\$(Configuration)|\$(Platform)'=='Debug|$self->{platform}'">$outputFile;%(Outputs)</Outputs>
<Message Condition="'\$(Configuration)|\$(Platform)'=='Release|$self->{platform}'">Running bison on $grammarFile</Message>
<Command Condition="'\$(Configuration)|\$(Platform)'=='Release|$self->{platform}'">perl "src\\tools\\msvc\\pgbison.pl" "$grammarFile"</Command>
<AdditionalInputs Condition="'\$(Configuration)|\$(Platform)'=='Release|$self->{platform}'">%(AdditionalInputs)</AdditionalInputs>
<Outputs Condition="'\$(Configuration)|\$(Platform)'=='Release|$self->{platform}'">$outputFile;%(Outputs)</Outputs>
</CustomBuild>
EOF
}
else #if ($grammarFile =~ /\.l$/)
{
print $f <<EOF;
<CustomBuild Include="$grammarFile">
<Message Condition="'\$(Configuration)|\$(Platform)'=='Debug|$self->{platform}'">Running flex on $grammarFile</Message>
<Command Condition="'\$(Configuration)|\$(Platform)'=='Debug|$self->{platform}'">perl "src\\tools\\msvc\\pgflex.pl" "$grammarFile"</Command>
<AdditionalInputs Condition="'\$(Configuration)|\$(Platform)'=='Debug|$self->{platform}'">%(AdditionalInputs)</AdditionalInputs>
<Outputs Condition="'\$(Configuration)|\$(Platform)'=='Debug|$self->{platform}'">$outputFile;%(Outputs)</Outputs>
<Message Condition="'\$(Configuration)|\$(Platform)'=='Release|$self->{platform}'">Running flex on $grammarFile</Message>
<Command Condition="'\$(Configuration)|\$(Platform)'=='Release|$self->{platform}'">perl "src\\tools\\msvc\\pgflex.pl" "$grammarFile"</Command>
<AdditionalInputs Condition="'\$(Configuration)|\$(Platform)'=='Release|$self->{platform}'">%(AdditionalInputs)</AdditionalInputs>
<Outputs Condition="'\$(Configuration)|\$(Platform)'=='Release|$self->{platform}'">$outputFile;%(Outputs)</Outputs>
</CustomBuild>
EOF
}
}
print $f <<EOF;
</ItemGroup>
EOF
}
if (scalar(@resourceFiles))
{
print $f <<EOF;
<ItemGroup>
EOF
foreach my $rcFile (@resourceFiles)
{
print $f <<EOF;
<ResourceCompile Include="$rcFile" />
EOF
}
print $f <<EOF;
</ItemGroup>
EOF
}
return;
}
sub WriteConfigurationHeader
{
my ($self, $f, $cfgname) = @_;
print $f <<EOF;
<ProjectConfiguration Include="$cfgname|$self->{platform}">
<Configuration>$cfgname</Configuration>
<Platform>$self->{platform}</Platform>
</ProjectConfiguration>
EOF
return;
}
sub WriteConfigurationPropertyGroup
{
my ($self, $f, $cfgname, $p) = @_;
my $cfgtype =
($self->{type} eq "exe")
? 'Application'
: ($self->{type} eq "dll" ? 'DynamicLibrary' : 'StaticLibrary');
print $f <<EOF;
<PropertyGroup Condition="'\$(Configuration)|\$(Platform)'=='$cfgname|$self->{platform}'" Label="Configuration">
<ConfigurationType>$cfgtype</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>$p->{wholeopt}</WholeProgramOptimization>
<PlatformToolset>$self->{PlatformToolset}</PlatformToolset>
</PropertyGroup>
EOF
return;
}
sub WritePropertySheetsPropertyGroup
{
my ($self, $f, $cfgname) = @_;
print $f <<EOF;
<ImportGroup Condition="'\$(Configuration)|\$(Platform)'=='$cfgname|$self->{platform}'" Label="PropertySheets">
<Import Project="\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props" Condition="exists('\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
EOF
return;
}
sub WriteAdditionalProperties
{
my ($self, $f, $cfgname) = @_;
print $f <<EOF;
<OutDir Condition="'\$(Configuration)|\$(Platform)'=='$cfgname|$self->{platform}'">.\\$cfgname\\$self->{name}\\</OutDir>
<IntDir Condition="'\$(Configuration)|\$(Platform)'=='$cfgname|$self->{platform}'">.\\$cfgname\\$self->{name}\\</IntDir>
<LinkIncremental Condition="'\$(Configuration)|\$(Platform)'=='$cfgname|$self->{platform}'">false</LinkIncremental>
EOF
return;
}
sub WriteItemDefinitionGroup
{
my ($self, $f, $cfgname, $p) = @_;
my $cfgtype =
($self->{type} eq "exe")
? 'Application'
: ($self->{type} eq "dll" ? 'DynamicLibrary' : 'StaticLibrary');
my $libs = $self->GetAdditionalLinkerDependencies($cfgname, ';');
my $targetmachine =
$self->{platform} eq 'Win32' ? 'MachineX86' : 'MachineX64';
my $includes = $self->{includes};
unless ($includes eq '' or $includes =~ /;$/)
{
$includes .= ';';
}
print $f <<EOF;
<ItemDefinitionGroup Condition="'\$(Configuration)|\$(Platform)'=='$cfgname|$self->{platform}'">
<ClCompile>
<Optimization>$p->{opt}</Optimization>
<AdditionalIncludeDirectories>$self->{prefixincludes}src/include;src/include/port/win32;src/include/port/win32_msvc;$includes\%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINDOWS;__WINDOWS__;__WIN32__;EXEC_BACKEND;WIN32_STACK_RLIMIT=4194304;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE$self->{defines}$p->{defs}\%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>$p->{strpool}</StringPooling>
<RuntimeLibrary>$p->{runtime}</RuntimeLibrary>
<DisableSpecificWarnings>$self->{disablewarnings};\%(DisableSpecificWarnings)</DisableSpecificWarnings>
<AdditionalOptions>/MP \%(AdditionalOptions)</AdditionalOptions>
<AssemblerOutput>
</AssemblerOutput>
<AssemblerListingLocation>.\\$cfgname\\$self->{name}\\</AssemblerListingLocation>
<ObjectFileName>.\\$cfgname\\$self->{name}\\</ObjectFileName>
<ProgramDataBaseFileName>.\\$cfgname\\$self->{name}\\</ProgramDataBaseFileName>
<BrowseInformation>false</BrowseInformation>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
</ClCompile>
<Link>
<OutputFile>.\\$cfgname\\$self->{name}\\$self->{name}.$self->{type}</OutputFile>
<AdditionalDependencies>$libs;\%(AdditionalDependencies)</AdditionalDependencies>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>\%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>libc;\%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
<StackReserveSize>4194304</StackReserveSize>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\\$cfgname\\$self->{name}\\$self->{name}.pdb</ProgramDatabaseFile>
<GenerateMapFile>false</GenerateMapFile>
<MapFileName>.\\$cfgname\\$self->{name}\\$self->{name}.map</MapFileName>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<!-- Permit links to MinGW-built, 32-bit DLLs (default before VS2012). -->
<ImageHasSafeExceptionHandlers/>
<SubSystem>Console</SubSystem>
<TargetMachine>$targetmachine</TargetMachine>
EOF
if ($self->{disablelinkerwarnings})
{
print $f
" <AdditionalOptions>/ignore:$self->{disablelinkerwarnings} \%(AdditionalOptions)</AdditionalOptions>\n";
}
if ($self->{implib})
{
my $l = $self->{implib};
$l =~ s/__CFGNAME__/$cfgname/g;
print $f " <ImportLibrary>$l</ImportLibrary>\n";
}
if ($self->{def})
{
my $d = $self->{def};
$d =~ s/__CFGNAME__/$cfgname/g;
print $f " <ModuleDefinitionFile>$d</ModuleDefinitionFile>\n";
}
print $f <<EOF;
</Link>
<ResourceCompile>
<AdditionalIncludeDirectories>src\\include;\%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
EOF
if ($self->{builddef})
{
print $f <<EOF;
<PreLinkEvent>
<Message>Generate DEF file</Message>
<Command>perl src\\tools\\msvc\\gendef.pl $cfgname\\$self->{name} $self->{platform}</Command>
</PreLinkEvent>
EOF
}
print $f <<EOF;
</ItemDefinitionGroup>
EOF
return;
}
sub Footer
{
my ($self, $f) = @_;
$self->WriteReferences($f);
print $f <<EOF;
<Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
EOF
return;
}
package VC2013Project;
#
# Package that encapsulates a Visual C++ 2013 project file
#
use strict;
use warnings;
use base qw(MSBuildProject);
no warnings qw(redefine); ## no critic
sub new
{
my $classname = shift;
my $self = $classname->SUPER::_new(@_);
bless($self, $classname);
$self->{vcver} = '12.00';
$self->{PlatformToolset} = 'v120';
$self->{ToolsVersion} = '12.0';
return $self;
}
package VC2015Project;
#
# Package that encapsulates a Visual C++ 2015 project file
#
use strict;
use warnings;
use base qw(MSBuildProject);
no warnings qw(redefine); ## no critic
sub new
{
my $classname = shift;
my $self = $classname->SUPER::_new(@_);
bless($self, $classname);
$self->{vcver} = '14.00';
$self->{PlatformToolset} = 'v140';
$self->{ToolsVersion} = '14.0';
return $self;
}
package VC2017Project;
#
# Package that encapsulates a Visual C++ 2017 project file
#
use strict;
use warnings;
use base qw(MSBuildProject);
no warnings qw(redefine); ## no critic
sub new
{
my $classname = shift;
my $self = $classname->SUPER::_new(@_);
bless($self, $classname);
$self->{vcver} = '15.00';
$self->{PlatformToolset} = 'v141';
$self->{ToolsVersion} = '15.0';
return $self;
}
package VC2019Project;
#
# Package that encapsulates a Visual C++ 2019 project file
#
use strict;
use warnings;
use base qw(MSBuildProject);
no warnings qw(redefine); ## no critic
sub new
{
my $classname = shift;
my $self = $classname->SUPER::_new(@_);
bless($self, $classname);
$self->{vcver} = '16.00';
$self->{PlatformToolset} = 'v142';
$self->{ToolsVersion} = '16.0';
return $self;
}
1;