1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00
pgbackrest/libc/build/lib/pgBackRestLibC/Build.pm
David Steele 801e2a5a2c Rename PGBACKREST/BACKREST constants to PROJECT.
This brings consistency between the C and Perl constants and allows for easier code reuse.
2018-11-24 19:05:03 -05:00

418 lines
12 KiB
Perl

####################################################################################################################################
# Auto-Generate XS and PM Files Required for Perl
####################################################################################################################################
package pgBackRestLibC::Build;
use strict;
use warnings FATAL => qw(all);
use Carp qw(confess);
use English '-no_match_vars';
use Cwd qw(abs_path);
use Exporter qw(import);
our @EXPORT = qw();
use File::Basename qw(dirname);
use Storable qw(dclone);
use lib dirname($0) . '/../build/lib';
use lib dirname($0) . '/../lib';
use pgBackRest::Common::Log;
use pgBackRest::Common::String;
use pgBackRest::Storage::Local;
use pgBackRest::Storage::Posix::Driver;
use pgBackRest::Version;
use pgBackRestBuild::Build;
use pgBackRestBuild::Build::Common;
use pgBackRestBuild::Config::Data;
use pgBackRestBuild::Error::Data;
####################################################################################################################################
# Perl function and constant exports
####################################################################################################################################
use constant BLD_EXPORTTYPE_SUB => 'sub';
use constant BLD_EXPORTTYPE_CONSTANT => 'constant';
use constant LIB_AUTO_NAME => 'LibCAuto';
####################################################################################################################################
# Save contents to a file if the file is missing or the contents are different. This saves write IO and prevents the timestamp from
# changing.
####################################################################################################################################
sub buildPutDiffers
{
my $oStorage = shift;
my $strFile = shift;
my $strContents = shift;
# Attempt to load the file
my $bSave = true;
my $oFile = $oStorage->openRead($strFile, {bIgnoreMissing => true});
# If file was found see if the content is the same
if (defined($oFile) && ${$oStorage->get($oFile)} eq $strContents)
{
$bSave = false;
}
# Save if the contents are different or missing
if ($bSave)
{
$oStorage->put($strFile, $strContents);
}
return $bSave;
}
####################################################################################################################################
# Static exports
####################################################################################################################################
my $rhExport =
{
'checksum' =>
{
&BLD_EXPORTTYPE_SUB => [qw(
pageChecksum
pageChecksumBufferTest
pageChecksumTest
)],
},
'config' =>
{
&BLD_EXPORTTYPE_SUB => [qw(
cfgCommandName
cfgOptionIndex
cfgOptionIndexTotal
cfgOptionName
)],
},
'configDefine' =>
{
&BLD_EXPORTTYPE_SUB => [qw(
cfgCommandId
cfgDefOptionDefault
cfgDefOptionPrefix
cfgDefOptionSecure
cfgDefOptionType
cfgDefOptionValid
cfgOptionId
cfgOptionTotal
)],
},
'crypto' =>
{
&BLD_EXPORTTYPE_SUB => [qw(
CIPHER_MODE_ENCRYPT
CIPHER_MODE_DECRYPT
cryptoHashOne
)],
},
'debug' =>
{
&BLD_EXPORTTYPE_SUB => [qw(
libcUvSize
)],
},
'encode' =>
{
&BLD_EXPORTTYPE_CONSTANT => [qw(
ENCODE_TYPE_BASE64
)],
&BLD_EXPORTTYPE_SUB => [qw(
decodeToBin
encodeToStr
)],
},
'lock' =>
{
&BLD_EXPORTTYPE_SUB => [qw(
lockAcquire
lockRelease
)],
},
'random' =>
{
&BLD_EXPORTTYPE_SUB => [qw(
cryptoRandomBytes
)],
},
'storage' =>
{
&BLD_EXPORTTYPE_SUB => [qw(
storageDriverPosixPathRemove
)],
},
'test' =>
{
&BLD_EXPORTTYPE_SUB => [qw(
cfgParseTest
)],
},
};
####################################################################################################################################
# Execute all build functions
####################################################################################################################################
sub buildXsAll
{
my $strBuildPath = shift;
# List of files built
my @stryBuilt;
# Storage
my $oStorage = new pgBackRest::Storage::Local(
$strBuildPath, new pgBackRest::Storage::Posix::Driver({bFileSync => false, bPathSync => false}));
# Build interface file
my $strContent =
('#' x 132) . "\n" .
'# ' . bldAutoWarning('Build.pm') . "\n" .
('#' x 132) . "\n" .
"package pgBackRest::LibCAuto;\n" .
"\n" .
"use strict;\n" .
"use warnings;\n";
# Generate constants for options that have a list of strings as allowed values
my $rhConfigDefine = cfgDefine();
my $strConstantBlock;
foreach my $strOption (sort(keys(%{$rhConfigDefine})))
{
my $rhOption = $rhConfigDefine->{$strOption};
next if $rhOption->{&CFGDEF_TYPE} ne CFGDEF_TYPE_STRING;
next if $strOption =~ /^log-level-/;
if (defined($rhOption->{&CFGDEF_ALLOW_LIST}))
{
$strConstantBlock .= defined($strConstantBlock) ? "\n" : '';
foreach my $strValue (@{$rhOption->{&CFGDEF_ALLOW_LIST}})
{
my $strConstant = 'CFGOPTVAL_' . uc("${strOption}_${strValue}");
$strConstant =~ s/\-/\_/g;
$strConstantBlock .= " ${strConstant}" . (' ' x (69 - length($strConstant) - 4)) . "=> '${strValue}',\n";
push(@{$rhExport->{'config'}{&BLD_EXPORTTYPE_CONSTANT}}, $strConstant);
}
}
foreach my $strCommand (sort(keys(%{$rhOption->{&CFGDEF_COMMAND}})))
{
my $rhCommand = $rhOption->{&CFGDEF_COMMAND}{$strCommand};
if (defined($rhCommand->{&CFGDEF_ALLOW_LIST}))
{
$strConstantBlock .= defined($strConstantBlock) ? "\n" : '';
foreach my $strValue (@{$rhCommand->{&CFGDEF_ALLOW_LIST}})
{
my $strConstant = 'CFGOPTVAL_' . uc("${strCommand}_${strOption}_${strValue}");
$strConstant =~ s/\-/\_/g;
$strConstantBlock .= " ${strConstant}" . (' ' x (69 - length($strConstant) - 4)) . "=> '${strValue}',\n";
push(@{$rhExport->{'config'}{&BLD_EXPORTTYPE_CONSTANT}}, $strConstant);
}
}
}
}
# Generate command constants
foreach my $strCommand (cfgDefineCommandList())
{
my $strConstant = "CFGCMD_" . uc($strCommand);
$strConstant =~ s/\-/\_/g;
push(@{$rhExport->{'config'}{&BLD_EXPORTTYPE_CONSTANT}}, $strConstant);
}
# Generate option constants
foreach my $strOption (sort(keys(%{$rhConfigDefine})))
{
# Build Perl constant
my $strConstant = "CFGOPT_" . uc($strOption);
$strConstant =~ s/\-/\_/g;
# Builds option data
for (my $iOptionIndex = 1; $iOptionIndex <= $rhConfigDefine->{$strOption}{&CFGDEF_INDEX_TOTAL}; $iOptionIndex++)
{
push(@{$rhExport->{'config'}{&BLD_EXPORTTYPE_CONSTANT}}, $strConstant . ($iOptionIndex == 1 ? '' : $iOptionIndex));
}
}
# Generate option type constants
$strConstantBlock .= defined($strConstantBlock) ? "\n" : '';
my $iIndex = 0;
foreach my $strOptionType (cfgDefineOptionTypeList())
{
# Build Perl constant
my $strConstant = "CFGDEF_TYPE_" . uc($strOptionType);
$strConstant =~ s/\-/\_/g;
$strConstantBlock .=
" ${strConstant}" . (' ' x (69 - length($strConstant) - 4)) . "=> $iIndex,\n";
push(@{$rhExport->{'configDefine'}{&BLD_EXPORTTYPE_CONSTANT}}, $strConstant);
$iIndex++;
};
# Generate encode type constants
$strConstantBlock .= defined($strConstantBlock) ? "\n" : '';
my $strConstant = "ENCODE_TYPE_BASE64";
$strConstantBlock .=
" ${strConstant}" . (' ' x (69 - length($strConstant) - 4)) . "=> 0,\n";
# Generate cipher type constants
$strConstantBlock .= defined($strConstantBlock) ? "\n" : '';
$strConstant = "CIPHER_MODE_ENCRYPT";
$strConstantBlock .=
" ${strConstant}" . (' ' x (69 - length($strConstant) - 4)) . "=> 0,\n";
$strConstant = "CIPHER_MODE_DECRYPT";
$strConstantBlock .=
" ${strConstant}" . (' ' x (69 - length($strConstant) - 4)) . "=> 1,\n";
$strContent .=
"\n" .
"# Configuration option value constants\n" .
"sub libcAutoConstant\n" .
"{\n" .
" return\n" .
" {\n" .
" " . trim($strConstantBlock) . "\n" .
" }\n" .
"}\n";
# Generate export tags
my $strExportTags;
foreach my $strSection (sort(keys(%{$rhExport})))
{
my $rhExportSection = $rhExport->{$strSection};
$strExportTags .= (defined($strExportTags) ? "\n" : '') . " ${strSection} =>\n [\n";
if (defined($rhExportSection->{&BLD_EXPORTTYPE_CONSTANT}) && @{$rhExportSection->{&BLD_EXPORTTYPE_CONSTANT}} > 0)
{
foreach my $strConstant (@{$rhExportSection->{&BLD_EXPORTTYPE_CONSTANT}})
{
$strExportTags .= " '${strConstant}',\n";
}
}
if (defined($rhExportSection->{&BLD_EXPORTTYPE_SUB}) && @{$rhExportSection->{&BLD_EXPORTTYPE_SUB}} > 0)
{
foreach my $strSub (@{$rhExportSection->{&BLD_EXPORTTYPE_SUB}})
{
$strExportTags .= " '${strSub}',\n";
}
}
$strExportTags .= " ],\n";
}
$strContent .=
"\n" .
"# Export function and constants\n" .
"sub libcAutoExportTag\n" .
"{\n" .
" return\n" .
" {\n" .
$strExportTags .
" }\n" .
"}\n";
# Add module end marker
$strContent .=
"\n" .
"1;\n";
# Save the file
my $strFile = 'lib/' . PROJECT_NAME . '/' . LIB_AUTO_NAME . '.pm';
if (buildPutDiffers($oStorage, "../${strFile}", $strContent))
{
push(@stryBuilt, $strFile);
}
# Build error file
#-------------------------------------------------------------------------------------------------------------------------------
my $rhErrorDefine = errorDefine();
# Order by id for the list that is id ordered
my $rhErrorId = {};
foreach my $strType (sort(keys(%{$rhErrorDefine})))
{
my $iCode = $rhErrorDefine->{$strType};
$rhErrorId->{$iCode} = $strType;
}
# Output errors
$strContent =
('#' x 132) . "\n" .
"# COMMON EXCEPTION AUTO MODULE\n" .
"# \n" .
'# ' . bldAutoWarning('Build.pm') . "\n" .
('#' x 132) . "\n" .
"package pgBackRest::Common::ExceptionAuto;\n" .
"\n" .
"use strict;\n" .
"use warnings FATAL => qw(all);\n" .
"\n" .
"use Exporter qw(import);\n" .
" our \@EXPORT = qw();\n" .
"\n" .
('#' x 132) . "\n" .
"# Error Definitions\n" .
('#' x 132) . "\n" .
"use constant ERROR_MINIMUM => " . ERRDEF_MIN . ";\n" .
"push \@EXPORT, qw(ERROR_MINIMUM);\n" .
"use constant ERROR_MAXIMUM => " . ERRDEF_MAX . ";\n" .
"push \@EXPORT, qw(ERROR_MAXIMUM);\n" .
"\n";
foreach my $iCode (sort({sprintf("%03d", $a) cmp sprintf("%03d", $b)} keys(%{$rhErrorId})))
{
my $strType = "ERROR_" . uc($rhErrorId->{$iCode});
$strType =~ s/\-/\_/g;
$strContent .=
"use constant ${strType}" . (' ' x (54 - length($strType))) . " => $iCode;\n" .
"push \@EXPORT, qw(${strType});\n"
}
$strContent .=
"\n" .
"1;\n";
$strFile = 'lib/' . PROJECT_NAME . '/Common/ExceptionAuto.pm';
if (buildPutDiffers($oStorage, "../${strFile}", $strContent))
{
push(@stryBuilt, $strFile);
}
# Return list of files built
return @stryBuilt;
}
push @EXPORT, qw(buildXsAll);
1;