2017-08-25 22:47:47 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
# 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 Storable qw(dclone);
|
|
|
|
|
|
|
|
use pgBackRest::Common::Log;
|
|
|
|
use pgBackRest::Common::String;
|
|
|
|
use pgBackRest::Storage::Local;
|
|
|
|
use pgBackRest::Storage::Posix::Driver;
|
|
|
|
|
|
|
|
use pgBackRestBuild::Build::Common;
|
|
|
|
|
2017-09-30 16:44:03 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
# Define generator used for auto generated warning messages
|
|
|
|
####################################################################################################################################
|
|
|
|
use constant GENERATOR => 'Build.pm';
|
|
|
|
|
2017-08-25 22:47:47 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
# buildAll - execute all build functions and generate C source code
|
|
|
|
####################################################################################################################################
|
|
|
|
sub buildAll
|
|
|
|
{
|
|
|
|
my $strBuildPath = shift;
|
2017-11-02 14:14:13 +02:00
|
|
|
my $rhBuild = shift;
|
|
|
|
my $strFileExt = shift;
|
2017-08-25 22:47:47 +02:00
|
|
|
|
|
|
|
# Storage object
|
|
|
|
my $oStorage = new pgBackRest::Storage::Local(
|
|
|
|
$strBuildPath, new pgBackRest::Storage::Posix::Driver({bFileSync => false, bPathSync => false}));
|
|
|
|
|
|
|
|
# Build and output source code
|
|
|
|
#-------------------------------------------------------------------------------------------------------------------------------
|
2017-11-02 14:14:13 +02:00
|
|
|
foreach my $strBuild (sort(keys(%{$rhBuild})))
|
2017-08-25 22:47:47 +02:00
|
|
|
{
|
2017-11-02 14:14:13 +02:00
|
|
|
my $strPath = $rhBuild->{$strBuild}{&BLD_PATH};
|
2017-08-25 22:47:47 +02:00
|
|
|
|
2017-11-02 14:14:13 +02:00
|
|
|
foreach my $strFile (sort(keys(%{$rhBuild->{$strBuild}{&BLD_DATA}{&BLD_FILE}})))
|
2017-08-25 22:47:47 +02:00
|
|
|
{
|
2017-11-02 14:14:13 +02:00
|
|
|
my $rhFile = $rhBuild->{$strBuild}{&BLD_DATA}{&BLD_FILE}{$strFile};
|
2017-08-25 22:47:47 +02:00
|
|
|
my $rhFileConstant = $rhFile->{&BLD_CONSTANT_GROUP};
|
2017-11-02 14:14:13 +02:00
|
|
|
my $rhFileEnum = $rhFile->{&BLD_ENUM};
|
|
|
|
my $rhFileData = $rhFile->{&BLD_DATA};
|
2017-08-25 22:47:47 +02:00
|
|
|
my $rhSource;
|
|
|
|
|
2017-11-02 14:14:13 +02:00
|
|
|
# Build general banner
|
2017-08-25 22:47:47 +02:00
|
|
|
#-------------------------------------------------------------------------------------------------------------------------------
|
2017-11-02 14:14:13 +02:00
|
|
|
my $strBanner = bldBanner($rhFile->{&BLD_SUMMARY}, GENERATOR);
|
|
|
|
|
|
|
|
# Build header file
|
|
|
|
#-------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
if (defined($rhFileEnum) || defined($rhFileConstant))
|
2017-08-25 22:47:47 +02:00
|
|
|
{
|
2017-11-02 14:14:13 +02:00
|
|
|
my $strHeaderDefine = uc("${strPath}/${strFile}") . '_AUTO_H';
|
|
|
|
$strHeaderDefine =~ s/\//_/g;
|
2017-08-25 22:47:47 +02:00
|
|
|
|
2017-11-02 14:14:13 +02:00
|
|
|
my $strHeader =
|
|
|
|
$strBanner .
|
|
|
|
"#ifndef ${strHeaderDefine}\n" .
|
|
|
|
"#define ${strHeaderDefine}\n";
|
2017-08-25 22:47:47 +02:00
|
|
|
|
2017-12-05 16:45:51 +02:00
|
|
|
# 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
|
2017-11-02 14:14:13 +02:00
|
|
|
foreach my $strEnum (sort(keys(%{$rhFileEnum})))
|
|
|
|
{
|
|
|
|
my $rhEnum = $rhFileEnum->{$strEnum};
|
2017-08-25 22:47:47 +02:00
|
|
|
|
2017-11-02 14:14:13 +02:00
|
|
|
$strHeader .=
|
|
|
|
"\n" . bldBanner($rhEnum->{&BLD_SUMMARY} . ' enum');
|
2017-08-25 22:47:47 +02:00
|
|
|
|
2017-11-02 14:14:13 +02:00
|
|
|
$strHeader .=
|
|
|
|
"typedef enum\n" .
|
|
|
|
"{\n";
|
2017-08-25 22:47:47 +02:00
|
|
|
|
2017-11-02 14:14:13 +02:00
|
|
|
my $iExpectedValue = 0;
|
2017-08-25 22:47:47 +02:00
|
|
|
|
2017-11-02 14:14:13 +02:00
|
|
|
# Iterate constants
|
|
|
|
foreach my $strEnumItem (@{$rhEnum->{&BLD_LIST}})
|
2017-08-25 22:47:47 +02:00
|
|
|
{
|
2017-11-02 14:14:13 +02:00
|
|
|
$strHeader .=
|
|
|
|
" ${strEnumItem}";
|
2017-08-25 22:47:47 +02:00
|
|
|
|
2017-11-02 14:14:13 +02:00
|
|
|
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++;
|
2017-08-25 22:47:47 +02:00
|
|
|
}
|
|
|
|
|
2017-11-02 14:14:13 +02:00
|
|
|
$strHeader .=
|
|
|
|
"} " . $rhEnum->{&BLD_NAME} . ";\n";
|
2017-08-25 22:47:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$strHeader .=
|
|
|
|
"\n#endif";
|
|
|
|
|
|
|
|
$rhSource->{&BLD_HEADER} = $strHeader;
|
|
|
|
}
|
|
|
|
|
|
|
|
# Build C file
|
|
|
|
#-----------------------------------------------------------------------------------------------------------------------
|
2017-11-02 14:14:13 +02:00
|
|
|
if (defined($rhFileData))
|
2017-08-25 22:47:47 +02:00
|
|
|
{
|
2017-11-02 14:14:13 +02:00
|
|
|
my $strCode;
|
2017-08-25 22:47:47 +02:00
|
|
|
|
2017-11-02 14:14:13 +02:00
|
|
|
foreach my $strData (sort(keys(%{$rhFileData})))
|
|
|
|
{
|
|
|
|
my $rhData = $rhFileData->{$strData};
|
|
|
|
|
|
|
|
$strCode .= "\n" . bldBanner($rhData->{&BLD_SUMMARY});
|
|
|
|
$strCode .= $rhData->{&BLD_SOURCE};
|
|
|
|
}
|
2017-08-25 22:47:47 +02:00
|
|
|
|
2017-11-02 14:14:13 +02:00
|
|
|
$rhSource->{&BLD_C} = "${strBanner}${strCode}";
|
|
|
|
}
|
2017-08-25 22:47:47 +02:00
|
|
|
|
|
|
|
# Output files
|
|
|
|
#-----------------------------------------------------------------------------------------------------------------------
|
|
|
|
foreach my $strFileType (sort(keys(%{$rhSource})))
|
|
|
|
{
|
2017-11-02 14:14:13 +02:00
|
|
|
my $strExt = $strFileType;
|
|
|
|
|
|
|
|
if (defined($strFileExt))
|
|
|
|
{
|
|
|
|
$strExt = $strFileType eq BLD_C ? $strFileExt : "${strFileExt}h";
|
|
|
|
}
|
|
|
|
|
|
|
|
# Only save the file if the content has changed
|
|
|
|
my $strFileName = "${strPath}/${strFile}.auto.${strExt}";
|
|
|
|
my $strContent = trim($rhSource->{$strFileType}) . "\n";
|
|
|
|
my $bChanged = true;
|
|
|
|
|
|
|
|
if ($oStorage->exists($strFileName))
|
|
|
|
{
|
|
|
|
my $strOldContent = ${$oStorage->get($strFileName)};
|
|
|
|
|
|
|
|
if ($strContent eq $strOldContent)
|
|
|
|
{
|
|
|
|
$bChanged = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($bChanged)
|
|
|
|
{
|
|
|
|
$oStorage->put($strFileName, $strContent);
|
|
|
|
}
|
2017-08-25 22:47:47 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Return build hash to caller for further processing
|
|
|
|
return $rhBuild;
|
|
|
|
}
|
|
|
|
|
|
|
|
push @EXPORT, qw(buildAll);
|
|
|
|
|
|
|
|
1;
|