mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-14 10:13:05 +02:00
57d7809297
Code generation saved files even when they had not changed, which often caused code generation cascades. So, don't save files unless they have changed. Use rsync to determine which files have changed since the last test run. The manifest of changed files is saved and not removed until all code generation and builds have completed. If an error occurs the work will be redone on the next run. The eventual goal is to do all the builds from the test/repo directory created by rsync but for now it is only used to track changes.
195 lines
7.6 KiB
Perl
195 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 pgBackRest::Storage::Local;
|
|
use pgBackRest::Storage::Posix::Driver;
|
|
|
|
use pgBackRestBuild::Build::Common;
|
|
|
|
####################################################################################################################################
|
|
# 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 pgBackRest::Storage::Local(
|
|
$strBuildPath, new pgBackRest::Storage::Posix::Driver({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;
|