1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00
pgbackrest/build/lib/pgBackRestBuild/Build.pm
David Steele 0a96a2895d Add storage layer for tests and documentation.
The tests and documentation have been using the core storage layer but soon that will depend entirely on the C library, creating a bootstrap problem (i.e. the storage layer will be needed to build the C library).

Create a simplified Posix storage layer to be used by documentation and the parts of the test code that build and execute the actual tests.  The actual tests will still use the core storage driver so they can interact with any type of storage.
2019-06-17 09:16:44 -04:00

196 lines
7.6 KiB
Perl

####################################################################################################################################
# Auto-Generate C Files Required for Build
####################################################################################################################################
package pgBackRestBuild::Build;
use strict;
use warnings FATAL => qw(all);
use Carp qw(confess);
use English '-no_match_vars';
use Exporter qw(import);
our @EXPORT = qw();
use File::Basename qw(basename);
use Storable qw(dclone);
use pgBackRest::Common::Log;
use pgBackRest::Common::String;
use pgBackRestBuild::Build::Common;
use pgBackRestTest::Common::Storage;
use pgBackRestTest::Common::StoragePosix;
####################################################################################################################################
# Define generator used for auto generated warning messages
####################################################################################################################################
use constant GENERATOR => 'Build.pm';
####################################################################################################################################
# buildAll - execute all build functions and generate C source code
####################################################################################################################################
sub buildAll
{
my $strBuildPath = shift;
my $rhBuild = shift;
my $strFileExt = shift;
# Storage object
my $oStorage = new pgBackRestTest::Common::Storage(
$strBuildPath, new pgBackRestTest::Common::StoragePosix({bFileSync => false, bPathSync => false}));
# List of files actually built
my @stryBuilt;
# Build and output source code
#-------------------------------------------------------------------------------------------------------------------------------
foreach my $strBuild (sort(keys(%{$rhBuild})))
{
my $strPath = $rhBuild->{$strBuild}{&BLD_PATH};
foreach my $strFile (sort(keys(%{$rhBuild->{$strBuild}{&BLD_DATA}{&BLD_FILE}})))
{
my $rhFile = $rhBuild->{$strBuild}{&BLD_DATA}{&BLD_FILE}{$strFile};
my $rhFileConstant = $rhFile->{&BLD_CONSTANT_GROUP};
my $rhFileEnum = $rhFile->{&BLD_ENUM};
my $rhFileDeclare = $rhFile->{&BLD_DECLARE};
my $rhFileData = $rhFile->{&BLD_DATA};
my $rhSource;
# Build general banner
#-------------------------------------------------------------------------------------------------------------------------------
my $strBanner = bldBanner($rhFile->{&BLD_SUMMARY}, GENERATOR);
# Build header file
#-------------------------------------------------------------------------------------------------------------------------------
if (defined($rhFileEnum) || defined($rhFileConstant) || defined($rhFileDeclare))
{
my $strHeaderDefine = uc("${strPath}/${strFile}") . '_AUTO_H';
$strHeaderDefine =~ s/\//_/g;
my $strHeader =
$strBanner .
"#ifndef ${strHeaderDefine}\n" .
"#define ${strHeaderDefine}\n";
# Iterate constant groups
foreach my $strConstantGroup (sort(keys(%{$rhFileConstant})))
{
my $rhConstantGroup = $rhFileConstant->{$strConstantGroup};
$strHeader .= "\n" . bldBanner($rhConstantGroup->{&BLD_SUMMARY} . ' constants');
# Iterate constants
foreach my $strConstant (sort(keys(%{$rhConstantGroup->{&BLD_CONSTANT}})))
{
my $rhConstant = $rhConstantGroup->{&BLD_CONSTANT}{$strConstant};
$strHeader .=
"#define ${strConstant} " . (' ' x (69 - length($strConstant) - 10)) .
$rhConstant->{&BLD_CONSTANT_VALUE} . "\n";
}
}
# Iterate enum groups
foreach my $strEnum (sort(keys(%{$rhFileEnum})))
{
my $rhEnum = $rhFileEnum->{$strEnum};
$strHeader .=
"\n" . bldBanner($rhEnum->{&BLD_SUMMARY} . ' enum');
$strHeader .=
"typedef enum\n" .
"{\n";
my $iExpectedValue = 0;
# Iterate enums
foreach my $strEnumItem (@{$rhEnum->{&BLD_LIST}})
{
$strHeader .=
" ${strEnumItem}";
if (defined($rhEnum->{&BLD_VALUE}{$strEnumItem}) && $rhEnum->{&BLD_VALUE}{$strEnumItem} != $iExpectedValue)
{
$strHeader .= ' = ' . (' ' x (61 - length($strEnumItem))) . $rhEnum->{&BLD_VALUE}{$strEnumItem};
$iExpectedValue = $rhEnum->{&BLD_VALUE}{$strEnumItem};
}
$strHeader .= ",\n";
$iExpectedValue++;
}
$strHeader .=
"} " . $rhEnum->{&BLD_NAME} . ";\n";
}
foreach my $strDeclare (sort(keys(%{$rhFileDeclare})))
{
my $rhDeclare = $rhFileDeclare->{$strDeclare};
$strHeader .= "\n" . bldBanner($rhDeclare->{&BLD_SUMMARY});
$strHeader .= $rhDeclare->{&BLD_SOURCE};
}
$strHeader .=
"\n#endif";
$rhSource->{&BLD_HEADER} = $strHeader;
}
# Build C file
#-----------------------------------------------------------------------------------------------------------------------
if (defined($rhFileData))
{
my $strCode;
foreach my $strData (sort(keys(%{$rhFileData})))
{
my $rhData = $rhFileData->{$strData};
$strCode .= "\n" . bldBanner($rhData->{&BLD_SUMMARY});
$strCode .= $rhData->{&BLD_SOURCE};
}
$rhSource->{&BLD_C} = "${strBanner}${strCode}";
}
# Output files
#-----------------------------------------------------------------------------------------------------------------------
foreach my $strFileType (sort(keys(%{$rhSource})))
{
my $strExt = $strFileType;
if (defined($strFileExt))
{
$strExt = $strFileType eq BLD_C ? $strFileExt : "${strFileExt}h";
}
# Save the file if it has not changed
my $strBuilt = "${strPath}/${strFile}.auto.${strExt}";
my $bSave = true;
my $oFile = $oStorage->openRead($strBuilt, {bIgnoreMissing => true});
if (defined($oFile) && ${$oStorage->get($oFile)} eq (trim($rhSource->{$strFileType}) . "\n"))
{
$bSave = false;
}
if ($bSave)
{
$oStorage->put($strBuilt, trim($rhSource->{$strFileType}) . "\n");
push(@stryBuilt, basename($strBuildPath) . "/${strBuilt}");
}
}
}
}
# Return list of files built
return @stryBuilt;
}
push @EXPORT, qw(buildAll);
1;