465 lines
11 KiB
Perl
465 lines
11 KiB
Perl
#!/usr/solar/bin/perl
|
|
#
|
|
#
|
|
#
|
|
|
|
use Cwd;
|
|
|
|
#########################
|
|
# #
|
|
# Globale Variablen #
|
|
# #
|
|
#########################
|
|
$QuantityToBuild = 0;
|
|
%LocalDepsHash = ();
|
|
%DepsArchive = ();
|
|
%BuildQueue = ();
|
|
%PathHash = ();
|
|
%PlatformHash = ();
|
|
%DeadDependencies = ();
|
|
%ParentDepsHash = ();
|
|
@UnresolvedParents = ();
|
|
%DeadParents = ();
|
|
$CurrentPrj = "";
|
|
$StandDir = GetStandDir();
|
|
$QuantityToBuild = GetQuantityToBuild();
|
|
$BuildAllParents = HowToBuild();
|
|
|
|
$dmake = GetDmakeCommando();
|
|
BuildAll();
|
|
@TotenEltern = keys %DeadParents;
|
|
if ($#TotenEltern != -1) {
|
|
my ($DeadPrj);
|
|
print "\nWARNING! Project(s):\n\n";
|
|
foreach $DeadPrj (@TotenEltern) {
|
|
print "$DeadPrj\n";
|
|
};
|
|
print "\nnot found and couldn't be built. Correct build.lsts.\n";
|
|
};
|
|
|
|
|
|
#########################
|
|
# #
|
|
# Procedures #
|
|
# #
|
|
#########################
|
|
|
|
|
|
#
|
|
# Get dependencies hash of the current and all parent projects
|
|
#
|
|
sub GetParentDeps {
|
|
my ($ParentsString, @DepsArray, $Prj, $Parent, @TotenEltern);
|
|
$ParentsString = GetParentsString(".");
|
|
@DepsArray = GetDependenciesArray($ParentsString);
|
|
@UnresolvedParents = @DepsArray;
|
|
$ParentDepsHash{$CurrentPrj} = [@DepsArray];
|
|
ResolveParentsLoop:
|
|
while ($Prj = pop(@UnresolvedParents)) {
|
|
my (@DepsArray);
|
|
if (!($ParentsString = GetParentsString($StandDir.$Prj))) {
|
|
$DeadParents{$Prj} = 1;
|
|
$ParentDepsHash{$Prj} = [];
|
|
next ResolveParentsLoop;
|
|
};
|
|
@DepsArray = GetDependenciesArray($ParentsString);
|
|
$ParentDepsHash{$Prj} = [@DepsArray];
|
|
foreach $Parent (@DepsArray) {
|
|
if (!defined($ParentDepsHash{$Parent})) {
|
|
push (@UnresolvedParents, $Parent);
|
|
};
|
|
};
|
|
};
|
|
print "\n";
|
|
@TotenEltern = keys %DeadParents;
|
|
foreach $Parent (@TotenEltern) {
|
|
RemoveFromDependencies($Parent, %ParentDepsHash);
|
|
};
|
|
};
|
|
|
|
|
|
#
|
|
# Build everything that should be built
|
|
#
|
|
sub BuildAll {
|
|
if ($BuildAllParents) {
|
|
my ($Prj, $PrjDir, $DeadPrj, @TotenEltern);
|
|
GetParentDeps();
|
|
@TotenEltern = keys %DeadParents;
|
|
foreach $DeadPrj (@TotenEltern) {
|
|
delete $ParentDepsHash{$DeadPrj};
|
|
RemoveFromDependencies($DeadPrj, \%ParentDepsHash);
|
|
};
|
|
while ($Prj = PickPrjToBuild(\%ParentDepsHash)) {
|
|
print "\nBuild project $Prj\n";
|
|
$PrjDir = CorrectPath($StandDir.$Prj);
|
|
BuildPrj($PrjDir);
|
|
RemoveFromDependencies($Prj, \%ParentDepsHash);
|
|
};
|
|
} else {
|
|
BuildPrj(".");
|
|
};
|
|
};
|
|
|
|
|
|
#
|
|
# Start build given project
|
|
#
|
|
sub MakeDir {
|
|
my ($DirToBuild, $BuildDir, $error, );
|
|
$DirToBuild = $_[0];
|
|
$BuildDir = CorrectPath($StandDir.$PathHash{$DirToBuild});
|
|
if ($ENV{GUI} eq "UNX") {
|
|
use Cwd 'chdir';
|
|
};
|
|
chdir ($BuildDir);
|
|
print $BuildDir, "\n";
|
|
cwd();
|
|
$error = system ("$dmake");
|
|
if (!$error) {
|
|
RemoveFromDependencies($DirToBuild, \%LocalDepsHash);
|
|
} else {
|
|
print "Error $error occurred while making $BuildDir\n";
|
|
exit();
|
|
};
|
|
};
|
|
|
|
|
|
#
|
|
# Make dependeCheck if project should be built when all parent projects are built
|
|
#
|
|
sub GetParentsString {
|
|
my ($ParentPrjs, @Arr, $PrjDir);
|
|
$PrjDir = $_[0];
|
|
if (!open (PrjBuildFile, $PrjDir."/prj/build.lst")) {
|
|
return "";
|
|
};
|
|
@Arr = <PrjBuildFile>;
|
|
$Arr[0] =~ /(\:)([\t | \s]+)/;
|
|
$ParentPrjs = $';
|
|
close PrjBuildFile;
|
|
return $';
|
|
};
|
|
|
|
#
|
|
# Check if project should be built when all parent projects are built
|
|
#
|
|
sub HowToBuild {
|
|
my ($i);
|
|
foreach $i (0 .. $#ARGV) {
|
|
if ($ARGV[$i] =~ /^-all/) {
|
|
splice(@ARGV, $i, 1);
|
|
return 1;
|
|
};
|
|
};
|
|
return 0;
|
|
}
|
|
|
|
#
|
|
# Getting hashes of all internal dependencies and additional
|
|
# infos for given project
|
|
#
|
|
sub BuildPrj {
|
|
my ($dummy, $PrjToBuild);
|
|
$PrjToBuild = $_[0];
|
|
if ($ENV{GUI} eq "UNX") {
|
|
use Cwd 'chdir';
|
|
};
|
|
chdir $PrjToBuild;
|
|
cwd();
|
|
|
|
open (PrjBuildFile, "prj/build.lst");
|
|
BuildLstLoop:
|
|
while (<PrjBuildFile>) {
|
|
s/\r\n//;
|
|
if ($_ =~ /nmake/) {
|
|
my ($Platform, $Dependencies, $Dir, $DirAlias, @Array);
|
|
$Dependencies = $';
|
|
$dummy = $`;
|
|
$dummy =~ /(\w+)\t([\w | \\ | \.]+)/;
|
|
$Dir = $2;
|
|
$Dependencies =~ /(\t\-\t)(\w+)/; #(\t)(\S+)(\s)/;
|
|
$Platform = $2;
|
|
$Dependencies = $';
|
|
while ($Dependencies =~ /,(\w+)/) {
|
|
$Dependencies = $';
|
|
};
|
|
$Dependencies =~ /(\s)(\S+)(\s)/;
|
|
$DirAlias = $2;
|
|
if (!CheckPlatform($Platform)) {
|
|
$DeadDependencies{$DirAlias} = 1;
|
|
next BuildLstLoop;
|
|
};
|
|
$PlatformHash{$DirAlias} = 1;
|
|
$Dependencies = $';
|
|
@Array = GetDependenciesArray($Dependencies);
|
|
$LocalDepsHash{$DirAlias} = [@Array];
|
|
$BuildQueue{$DirAlias} = 1;
|
|
$PathHash{$DirAlias} = $Dir;
|
|
};
|
|
};
|
|
%DepsArchive = %LocalDepsHash;
|
|
foreach $Dir (keys %DeadDependencies) {
|
|
if (!IsHashNative($Dir)) {
|
|
RemoveFromDependencies($Dir, \%LocalDepsHash);
|
|
delete $DeadDependencies{$Dir};
|
|
};
|
|
};
|
|
BuildDependent();
|
|
};
|
|
|
|
|
|
#
|
|
# Convert path from abstract (with '\' and/or '/' delimiters)
|
|
# to system-dependent
|
|
#
|
|
sub CorrectPath {
|
|
$_ = $_[0];
|
|
if ($ENV{GUI} eq "UNX") {
|
|
s/\\/\//g;
|
|
} elsif ( ($ENV{GUI} eq "WNT") ||
|
|
($ENV{GUI} eq "WIN") ||
|
|
($ENV{GUI} eq "MACOSX") ||
|
|
($ENV{GUI} eq "OS2")) {
|
|
s/\//\\/g;
|
|
} else {
|
|
die "\nNo environment set\n";
|
|
};
|
|
return $_;
|
|
};
|
|
|
|
|
|
#
|
|
# Get platform-dependent dmake commando
|
|
#
|
|
sub GetDmakeCommando {
|
|
my ($dmake, $arg);
|
|
|
|
# Setting alias for dmake
|
|
$dmake = "dmake";
|
|
#if (defined $ENV{PROFULLSWITCH}) {
|
|
# $dmake .= " ".$ENV{PROFULLSWITCH};
|
|
#};
|
|
while ($arg = pop(@ARGV)) {
|
|
$dmake .= " "."$arg";
|
|
};
|
|
return $dmake;
|
|
};
|
|
|
|
|
|
#
|
|
# Procedure returns quantity of folders to be built syncronously
|
|
#
|
|
sub GetQuantityToBuild {
|
|
my ($i);
|
|
foreach $i (0 .. $#ARGV) {
|
|
if ($ARGV[$i] =~ /^-PP/) {
|
|
splice(@ARGV, $i, 1);
|
|
return $';
|
|
};
|
|
};
|
|
};
|
|
|
|
|
|
#
|
|
# Procedure prooves if current dir is a root dir in the drive
|
|
#
|
|
sub IsRootDir {
|
|
my ($Dir);
|
|
$Dir = $_[0];
|
|
if (($ENV{GUI} eq "UNX") ||
|
|
($ENV{GUI} eq "MACOSX") ||
|
|
($Dir eq "\/")) {
|
|
return 1;
|
|
} elsif ( ($ENV{GUI} eq "WNT") ||
|
|
($ENV{GUI} eq "WIN") ||
|
|
($ENV{GUI} eq "OS2") &&
|
|
($Dir =~ /\S:\/$/)) {
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
};
|
|
};
|
|
|
|
|
|
#
|
|
# Procedure retrieves list of projects to be built from build.lst
|
|
#
|
|
sub GetStandDir {
|
|
my ($StandDir);
|
|
DirLoop:
|
|
do {
|
|
$StandDir = cwd();
|
|
if (open(PrjBuildFile, "prj/build.lst")) {
|
|
$StandDir =~ /(\w+$)/;
|
|
$StandDir = $`;
|
|
$CurrentPrj = $1;
|
|
close(PrjBuildFile);
|
|
return $StandDir;
|
|
} elsif (IsRootDir($StandDir)) {
|
|
die "Found no project to build\n"
|
|
};
|
|
}
|
|
while (chdir '..');
|
|
};
|
|
|
|
|
|
#
|
|
# Build the entire project according to queue of dependencies
|
|
#
|
|
sub BuildDependent {
|
|
my ($Dir);
|
|
while ($Dir = PickPrjToBuild(\%LocalDepsHash)) {
|
|
MakeDir($Dir);
|
|
$Dir = "";
|
|
};
|
|
};
|
|
|
|
|
|
#
|
|
# Picks project which can be build now from hash and deletes it from hash
|
|
#
|
|
sub PickPrjToBuild {
|
|
my ($Prj, $DepsHash);
|
|
$DepsHash = $_[0];
|
|
$Prj = FindIndepPrj($DepsHash);
|
|
delete $$DepsHash{$Prj};
|
|
#print "$Prj\n";
|
|
return $Prj;
|
|
};
|
|
|
|
|
|
#
|
|
# Make a decision if the project should be built on this platform
|
|
#
|
|
sub CheckPlatform {
|
|
my ($Platform);
|
|
$Platform = $_[0];
|
|
if ($Platform eq "all") {
|
|
return 1;
|
|
} elsif (($ENV{GUI} eq "WNT") &&
|
|
(($Platform eq "w") || ($Platform eq "n"))) {
|
|
return 1;
|
|
} elsif (($ENV{GUI} eq "WIN") && ($Platform eq "w")) {
|
|
return 1;
|
|
} elsif (($ENV{GUI} eq "UNX") && ($Platform eq "u")) {
|
|
return 1;
|
|
} elsif (($ENV{GUI} eq "MACOSX") && ($Platform eq "m")) {
|
|
return 1;
|
|
} elsif (($ENV{GUI} eq "OS2") && ($Platform eq "p")) {
|
|
return 1;
|
|
};
|
|
return 0;
|
|
};
|
|
|
|
|
|
#
|
|
# Remove project to build ahead from dependencies and make an array
|
|
# of all from given project dependent projects
|
|
#
|
|
sub RemoveFromDependencies {
|
|
my ($ExclPrj, $i, $Prj, $Dependencies);
|
|
$ExclPrj = $_[0];
|
|
$Dependencies = $_[1];
|
|
foreach $Prj (keys %$Dependencies) {
|
|
PrjDepsLoop:
|
|
foreach $i (0 .. $#{$$Dependencies{$Prj}}) {
|
|
#print $Prj, " $i ", ${$$Dependencies{$Prj}}[$i], "\n";
|
|
if (${$$Dependencies{$Prj}}[$i] eq $ExclPrj) {
|
|
splice (@{$$Dependencies{$Prj}}, $i, 1);
|
|
$i = 0;
|
|
last PrjDepsLoop;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
|
|
#
|
|
# Find undependent project
|
|
#
|
|
sub FindIndepPrj {
|
|
my ($Prj, @Prjs, @PrjDeps, $Dependencies, $i);
|
|
$Dependencies = $_[0];
|
|
@Prjs = keys %$Dependencies;
|
|
if ($#Prjs != -1) {
|
|
PrjLoop:
|
|
foreach $Prj (@Prjs) {
|
|
if (IsHashNative($Prj)) {
|
|
next PrjLoop;
|
|
};
|
|
@PrjDeps = @{$$Dependencies{$Prj}};
|
|
if ($#PrjDeps == -1) {
|
|
return $Prj;
|
|
};
|
|
};
|
|
# If there are only dependent projects in hash - generate error
|
|
print "\nError: projects";
|
|
DeadPrjLoop:
|
|
foreach $Prj (keys %$Dependencies) {
|
|
if (IsHashNative($Prj)) {
|
|
next DeadPrjLoop;
|
|
};
|
|
$i = 0;
|
|
print "\n", $Prj, " depends on:";
|
|
foreach $i (0 .. $#{$$Dependencies{$Prj}}) {
|
|
print " ", ${$$Dependencies{$Prj}}[$i];
|
|
};
|
|
};
|
|
print "\nhave dead or circular dependencies\n\n";
|
|
exit ();
|
|
};
|
|
};
|
|
|
|
|
|
|
|
#
|
|
# Check if given entry is HASH-native, that is not a user-defined data
|
|
#
|
|
sub IsHashNative {
|
|
my ($Prj);
|
|
$Prj = $_[0];
|
|
if ($Prj =~ /^HASH\(0x[\d | a | b | c | d | e | f]{6,}\)/) {
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
};
|
|
};
|
|
|
|
|
|
#
|
|
# Getting array of dependencies from the string given
|
|
#
|
|
sub GetDependenciesArray {
|
|
my ($DepString, @Dependencies, $ParentPrj);
|
|
@Dependencies = ();
|
|
$DepString = $_[0];
|
|
while (!($DepString =~ /^NULL/)) {
|
|
$DepString =~ /(\S+)(\s)/;
|
|
$ParentPrj = $1;
|
|
$DepString = $';
|
|
if ($ParentPrj =~ /(\S+)(\.)(\w)/) {
|
|
$ParentPrj = $1;
|
|
if (CheckPlatform($3)) {
|
|
push(@Dependencies, $ParentPrj);
|
|
};
|
|
} else {
|
|
push(@Dependencies, $ParentPrj);
|
|
};
|
|
};
|
|
return @Dependencies;
|
|
};
|
|
|
|
|
|
#
|
|
# Getting current directory list
|
|
#
|
|
sub GetDirectoryList {
|
|
my ($Path);
|
|
$Path = $_[0];
|
|
opendir(CurrentDirList, $Path);
|
|
@DirectoryList = readdir(CurrentDirList);
|
|
closedir(CurrentDirList);
|
|
return @DirectoryList;
|
|
};
|
|
|