[PATCH] testbot/build: Move the common build functions to Build::Utils.
Francois Gouget
fgouget at codeweavers.com
Wed Aug 22 03:18:58 CDT 2018
This reduces the build scripts code duplication.
A side-effect is that the status lines now all start with the 'Task:'
prefix.
Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
---
testbot/bin/build/Build.pl | 89 +-------
testbot/bin/build/Reconfig.pl | 113 +---------
testbot/bin/build/WineReconfig.pl | 247 ++------------------
testbot/bin/build/WineTest.pl | 111 +--------
testbot/lib/Build/Utils.pm | 363 ++++++++++++++++++++++++++++++
5 files changed, 409 insertions(+), 514 deletions(-)
create mode 100644 testbot/lib/Build/Utils.pm
diff --git a/testbot/bin/build/Build.pl b/testbot/bin/build/Build.pl
index e1133aaee..7f94c8595 100755
--- a/testbot/bin/build/Build.pl
+++ b/testbot/bin/build/Build.pl
@@ -43,98 +43,23 @@ sub BEGIN
}
$::BuildEnv = 1;
}
-my $Name0 = $0;
-$Name0 =~ s+^.*/++;
-
+use Build::Utils;
use WineTestBot::Config;
-use WineTestBot::PatchUtils;
use WineTestBot::Utils;
-#
-# Logging and error handling helpers
-#
-
-sub InfoMsg(@)
-{
- print @_;
-}
-
-sub LogMsg(@)
-{
- print "Build: ", @_;
-}
-
-sub Error(@)
-{
- print STDERR "$Name0:error: ", @_;
-}
-
-
#
# Build helpers
#
-my $ncpus;
-sub CountCPUs()
-{
- if (open(my $fh, "<", "/proc/cpuinfo"))
- {
- # Linux
- map { $ncpus++ if (/^processor/); } <$fh>;
- close($fh);
- }
- $ncpus ||= 1;
-}
-
-sub ApplyPatch($)
-{
- my ($PatchFile) = @_;
-
- InfoMsg "Applying patch\n";
- system("cd '$DataDir/wine' && ".
- "echo wine:HEAD=`git rev-parse HEAD` && ".
- "set -x && ".
- "git apply --verbose ". ShQuote($PatchFile) ." && ".
- "git add -A");
- if ($? != 0)
- {
- LogMsg "Patch failed to apply\n";
- return undef;
- }
-
- my $Impacts = GetPatchImpact($PatchFile, "nounits");
- if ($Impacts->{MakeMakefiles})
- {
- InfoMsg "\nRunning make_makefiles\n";
- system("cd '$DataDir/wine' && set -x && ./tools/make_makefiles");
- if ($? != 0)
- {
- LogMsg "make_makefiles failed\n";
- return undef;
- }
- }
-
- if ($Impacts->{Autoconf} && !$Impacts->{HasConfigure})
- {
- InfoMsg "\nRunning autoconf\n";
- system("cd '$DataDir/wine' && set -x && autoconf");
- if ($? != 0)
- {
- LogMsg "Autoconf failed\n";
- return undef;
- }
- }
-
- return $Impacts;
-}
sub BuildNative()
{
InfoMsg "\nRebuilding native tools\n";
+ my $CPUCount = GetCPUCount();
system("cd '$DataDir/build-native' && set -x && ".
- "time make -j$ncpus __tooldeps__");
+ "time make -j$CPUCount __tooldeps__");
if ($? != 0)
{
LogMsg "Rebuild of native tools failed\n";
@@ -160,8 +85,9 @@ sub BuildTestExecutables($$$)
}
InfoMsg "\nBuilding the $Bits-bit test executable(s)\n";
+ my $CPUCount = GetCPUCount();
system("cd '$DataDir/build-mingw$Bits' && set -x && ".
- "time make -j$ncpus ". join(" ", sort @BuildDirs));
+ "time make -j$CPUCount ". join(" ", sort @BuildDirs));
if ($? != 0)
{
LogMsg "Rebuild of $Bits-bit crossbuild failed\n";
@@ -262,6 +188,7 @@ if (!defined $Usage)
}
if (defined $Usage)
{
+ my $Name0 = GetToolName();
if ($Usage)
{
Error "try '$Name0 --help' for more information\n";
@@ -292,9 +219,7 @@ if ($DataDir =~ /'/)
# Run the builds
#
-CountCPUs();
-
-my $Impacts = ApplyPatch($PatchFile);
+my $Impacts = ApplyPatch("wine", $PatchFile);
if (!$Impacts or
($Impacts->{WineBuild} and !BuildNative()) or
diff --git a/testbot/bin/build/Reconfig.pl b/testbot/bin/build/Reconfig.pl
index 4aada3242..36748d66e 100755
--- a/testbot/bin/build/Reconfig.pl
+++ b/testbot/bin/build/Reconfig.pl
@@ -39,112 +39,15 @@ sub BEGIN
}
$::BuildEnv = 1;
}
-my $Name0 = $0;
-$Name0 =~ s+^.*/++;
-
+use Build::Utils;
use WineTestBot::Config;
-use WineTestBot::PatchUtils;
-
-
-#
-# Logging and error handling helpers
-#
-
-sub InfoMsg(@)
-{
- print @_;
-}
-
-sub LogMsg(@)
-{
- print "Reconfig: ", @_;
-}
-
-sub Error(@)
-{
- print STDERR "$Name0:error: ", @_;
-}
#
# Build helpers
#
-my $ncpus;
-sub CountCPUs()
-{
- if (open(my $fh, "<", "/proc/cpuinfo"))
- {
- # Linux
- map { $ncpus++ if (/^processor/); } <$fh>;
- close($fh);
- }
- $ncpus ||= 1;
-}
-
-sub BuildTestAgentd()
-{
- # If testagentd already exists it's likely already running
- # so don't rebuild it.
- if (! -x "$BinDir/build/testagentd")
- {
- InfoMsg "\nBuilding the native testagentd\n";
- system("cd '$::RootDir/src/testagentd' && set -x && ".
- "time make -j$ncpus build");
- if ($? != 0)
- {
- LogMsg "Build testagentd failed\n";
- return !1;
- }
- }
-
- InfoMsg "\nRebuilding the Windows TestAgentd\n";
- system("cd '$::RootDir/src/testagentd' && set -x && ".
- "time make -j$ncpus iso");
- if ($? != 0)
- {
- LogMsg "Build winetestbot.iso failed\n";
- return !1;
- }
-
- return 1;
-}
-
-sub BuildTestLauncher()
-{
- InfoMsg "\nRebuilding TestLauncher\n";
- system("cd '$::RootDir/src/TestLauncher' && set -x && ".
- "time make -j$ncpus");
- if ($? != 0)
- {
- LogMsg "Build TestLauncher failed\n";
- return !1;
- }
-
- return 1;
-}
-
-sub GitPull()
-{
- InfoMsg "\nUpdating the Wine source\n";
- system("cd '$DataDir/wine' && git pull");
- if ($? != 0)
- {
- LogMsg "Git pull failed\n";
- return !1;
- }
-
- my $ErrMessage = UpdateWineData("$DataDir/wine");
- if ($ErrMessage)
- {
- LogMsg "$ErrMessage\n";
- return !1;
- }
-
- return 1;
-}
-
sub BuildNative($)
{
my ($NoRm) = @_;
@@ -153,10 +56,11 @@ sub BuildNative($)
# Rebuild from scratch to make sure cruft will not accumulate
InfoMsg "\nRebuilding native tools\n";
+ my $CPUCount = GetCPUCount();
system("cd '$DataDir/build-native' && set -x && ".
($NoRm ? "" : "rm -rf * && ") .
"time ../wine/configure --enable-win64 --without-x --without-freetype --disable-winetest && ".
- "time make -j$ncpus __tooldeps__");
+ "time make -j$CPUCount __tooldeps__");
if ($? != 0)
{
@@ -176,11 +80,12 @@ sub BuildCross($$$)
# Rebuild from scratch to make sure cruft will not accumulate
InfoMsg "\nRebuilding the $Bits-bit test executables\n";
+ my $CPUCount = GetCPUCount();
my $Host = ($Bits == 64 ? "x86_64-w64-mingw32" : "i686-w64-mingw32");
system("cd '$DataDir/build-mingw$Bits' && set -x && ".
($NoRm ? "" : "rm -rf * && ") .
"time ../wine/configure --host=$Host --with-wine-tools=../build-native --without-x --without-freetype --disable-winetest && ".
- "time make -j$ncpus buildtests");
+ "time make -j$CPUCount buildtests");
if ($? != 0)
{
LogMsg "Build cross ($Bits bits) failed\n";
@@ -271,6 +176,7 @@ if (!defined $Usage)
}
if (defined $Usage)
{
+ my $Name0 = GetToolName();
if ($Usage)
{
Error "try '$Name0 --help' for more information\n";
@@ -308,10 +214,9 @@ if (! -d "$DataDir/staging" and ! mkdir "$DataDir/staging")
# Run the builds
#
-CountCPUs();
-
-exit(1) if (!BuildTestAgentd() or !BuildTestLauncher());
-exit(1) if ($OptUpdate and !GitPull());
+exit(1) if (!BuildNativeTestAgentd() or !BuildWindowsTestAgentd());
+exit(1) if (!BuildTestLauncher());
+exit(1) if ($OptUpdate and !GitPull("wine"));
exit(1) if ($OptBuild and !UpdateWineBuilds($Targets, $OptNoRm));
LogMsg "ok\n";
diff --git a/testbot/bin/build/WineReconfig.pl b/testbot/bin/build/WineReconfig.pl
index 77722734c..b30ddd190 100755
--- a/testbot/bin/build/WineReconfig.pl
+++ b/testbot/bin/build/WineReconfig.pl
@@ -36,92 +36,15 @@ sub BEGIN
}
$::BuildEnv = 1;
}
-my $Name0 = $0;
-$Name0 =~ s+^.*/++;
-
-
-use Digest::SHA;
-use File::Path;
+use Build::Utils;
use WineTestBot::Config;
-use WineTestBot::PatchUtils;
-
-
-#
-# Logging and error handling helpers
-#
-
-sub InfoMsg(@)
-{
- print @_;
-}
-
-sub LogMsg(@)
-{
- print "Reconfig: ", @_;
-}
-
-sub Error(@)
-{
- print STDERR "$Name0:error: ", @_;
-}
#
# Build helpers
#
-my $ncpus;
-sub CountCPUs()
-{
- if (open(my $fh, "<", "/proc/cpuinfo"))
- {
- # Linux
- map { $ncpus++ if (/^processor/); } <$fh>;
- close($fh);
- }
- $ncpus ||= 1;
-}
-
-sub BuildTestAgentd()
-{
- # If testagentd already exists it's likely already running
- # so don't rebuild it.
- if (! -x "$BinDir/build/testagentd")
- {
- InfoMsg "\nBuilding the native testagentd\n";
- system("cd '$::RootDir/src/testagentd' && set -x && ".
- "time make -j$ncpus build");
- if ($? != 0)
- {
- LogMsg "Build testagentd failed\n";
- return !1;
- }
- }
-
- return 1;
-}
-
-sub GitPull()
-{
- InfoMsg "\nUpdating the Wine source\n";
- system("cd '$DataDir/wine' && git pull");
- if ($? != 0)
- {
- LogMsg "Git pull failed\n";
- return !1;
- }
-
- my $ErrMessage = UpdateWineData("$DataDir/wine");
- if ($ErrMessage)
- {
- LogMsg "$ErrMessage\n";
- return !1;
- }
-
- return 1;
-}
-
sub BuildWine($$$$)
{
my ($Targets, $NoRm, $Build, $Extras) = @_;
@@ -132,10 +55,11 @@ sub BuildWine($$$$)
# If $NoRm is not set, rebuild from scratch to make sure cruft will not
# accumulate
InfoMsg "\nRebuilding the $Build Wine\n";
+ my $CPUCount = GetCPUCount();
system("cd '$DataDir/build-$Build' && set -x && ".
($NoRm ? "" : "rm -rf * && ") .
"time ../wine/configure $Extras && ".
- "time make -j$ncpus");
+ "time make -j$CPUCount");
if ($? != 0)
{
LogMsg "The $Build build failed\n";
@@ -159,160 +83,30 @@ sub UpdateWineBuilds($$)
# WinePrefix helpers
#
-sub VerifyAddOn($$)
-{
- my ($AddOn, $Arch) = @_;
-
- my $Sha256 = Digest::SHA->new(256);
- eval { $Sha256->addfile("$DataDir/$AddOn->{name}/$AddOn->{filename}") };
- return "$@" if ($@);
-
- my $Checksum = $Sha256->hexdigest();
- return undef if ($Checksum eq $AddOn->{$Arch});
- return "Bad checksum for '$AddOn->{filename}'";
-}
-
-sub UpdateAddOn($$$)
+sub UpdateWinePrefixes($)
{
- my ($AddOn, $Name, $Arch) = @_;
+ my ($Targets) = @_;
- if (!defined $AddOn)
- {
- LogMsg "Could not get information on the $Name addon\n";
- return 0;
- }
- if (!$AddOn->{version})
- {
- LogMsg "Could not get the $Name version\n";
- return 0;
- }
- if (!$AddOn->{$Arch})
+ # Set up brand new WinePrefixes ready for use for testing.
+ # This way we do it once instead of doing it for every test, thus saving
+ # time. Note that this requires using a different wineprefix for each build.
+ foreach my $Build ("win32", "wow64", "wow32")
{
- LogMsg "Could not get the $Name $Arch checksum\n";
- return 0;
- }
-
- $AddOn->{filename} = "wine". ($Name eq "gecko" ? "_" : "-") .
- "$Name-$AddOn->{version}".
- ($Arch eq "" ? "" : "-$Arch") .".msi";
- return 1 if (!VerifyAddOn($AddOn, $Arch));
+ next if (!$Targets->{$Build});
- InfoMsg "Downloading $AddOn->{filename}\n";
- mkdir "$DataDir/$Name";
-
- my $Url="http://dl.winehq.org/wine/wine-$Name/$AddOn->{version}/$AddOn->{filename}";
- for (1..3)
- {
- system("cd '$DataDir/$Name' && set -x && ".
- "wget --no-verbose -O- '$Url' >'$AddOn->{filename}'");
- last if ($? == 0);
- }
- my $ErrMessage = VerifyAddOn($AddOn, $Arch);
- return 1 if (!defined $ErrMessage);
- LogMsg "$ErrMessage\n";
- return 0;
-}
-
-sub UpdateAddOns()
-{
- my %AddOns;
- if (open(my $fh, "<", "$DataDir/wine/dlls/appwiz.cpl/addons.c"))
- {
- my $Arch = "";
- while (my $Line= <$fh>)
+ # Wait for the wineprefix creation to complete so it is really done
+ # before the snapshot gets updated.
+ SetupWineEnvironment($Build);
+ my $ErrMessage = CreateWinePrefix($Build, "wait");
+ if (defined $ErrMessage)
{
- if ($Line =~ /^\s*#\s*define\s+ARCH_STRING\s+"([^"]+)"/)
- {
- $Arch = $1;
- }
- elsif ($Line =~ /^\s*#\s*define\s*(GECKO|MONO)_VERSION\s*"([^"]+)"/)
- {
- my ($AddOn, $Version) = ($1, $2);
- $AddOn =~ tr/A-Z/a-z/;
- $AddOns{$AddOn}->{name} = $AddOn;
- $AddOns{$AddOn}->{version} = $Version;
- }
- elsif ($Line =~ /^\s*#\s*define\s*(GECKO|MONO)_SHA\s*"([^"]+)"/)
- {
- my ($AddOn, $Checksum) = ($1, $2);
- $AddOn =~ tr/A-Z/a-z/;
- $AddOns{$AddOn}->{$Arch} = $Checksum;
- $Arch = "";
- }
+ LogMsg "$ErrMessage\n";
+ return 0;
}
- close($fh);
- }
- else
- {
- LogMsg "Could not open 'wine/dlls/appwiz.cpl/addons.c': $!\n";
- return 0;
- }
-
- return UpdateAddOn($AddOns{gecko}, "gecko", "x86") &&
- UpdateAddOn($AddOns{gecko}, "gecko", "x86_64") &&
- UpdateAddOn($AddOns{mono}, "mono", "");
-}
-
-# See also WineTest.pl
-sub SetupWineEnvironment($)
-{
- my ($Build) = @_;
-
- $ENV{WINEPREFIX} = "$DataDir/wineprefix-$Build";
- $ENV{DISPLAY} ||= ":0.0";
-}
-
-# See also WineTest.pl
-sub RunWine($$$)
-{
- my ($Build, $Cmd, $CmdArgs) = @_;
-
- my $Magic = `cd '$DataDir/build-$Build' && file $Cmd`;
- my $Wine = ($Magic =~ /ELF 64/ ? "./wine64" : "./wine");
- return system("cd '$DataDir/build-$Build' && set -x && ".
- "time $Wine $Cmd $CmdArgs");
-}
-
-# Setup a brand new WinePrefix ready for use for testing.
-# This way we do it once instead of doing it for every test, thus saving
-# time. Note that this requires using a different wineprefix for each build.
-sub NewWinePrefix($$)
-{
- my ($Targets, $Build) = @_;
-
- return 1 if (!$Targets->{$Build});
-
- InfoMsg "\nRecreating the $Build wineprefix\n";
- SetupWineEnvironment($Build);
- rmtree($ENV{WINEPREFIX});
-
- # Crash dialogs cause delays so disable them
- if (RunWine($Build, "./programs/reg/reg.exe.so", "ADD HKCU\\\\Software\\\\Wine\\\\WineDbg /v ShowCrashDialog /t REG_DWORD /d 0"))
- {
- LogMsg "Failed to disable the $Build build crash dialogs: $!\n";
- return 0;
}
-
- # Ensure the WinePrefix has been fully created before updating the snapshot
- system("cd '$DataDir/build-$Build' && ./server/wineserver -w");
-
return 1;
}
-sub UpdateWinePrefixes($)
-{
- my ($Targets) = @_;
-
- return NewWinePrefix($Targets, "win32") &&
- # The wow32 and wow64 wineprefixes:
- # - Are essentially identical.
- # - Must be created after both WoW builds have been updated.
- # - Make it possible to run the wow32 and wow64 tests in separate
- # prefixes, thus ensuring they don't interfere with each other.
- NewWinePrefix($Targets, "wow64") &&
- NewWinePrefix($Targets, "wow32");
-}
-
#
# Setup and command line processing
@@ -393,6 +187,7 @@ if (!defined $Usage)
}
if (defined $Usage)
{
+ my $Name0 = GetToolName();
if ($Usage)
{
Error "try '$Name0 --help' for more information\n";
@@ -436,10 +231,8 @@ if ($DataDir =~ /'/)
# Run the builds and/or tests
#
-CountCPUs();
-
-exit(1) if (!BuildTestAgentd());
-exit(1) if ($OptUpdate and !GitPull());
+exit(1) if (!BuildNativeTestAgentd());
+exit(1) if ($OptUpdate and !GitPull("wine"));
exit(1) if ($OptAddOns and !UpdateAddOns());
exit(1) if ($OptBuild and !UpdateWineBuilds($Targets, $OptNoRm));
exit(1) if ($OptWinePrefix and !UpdateWinePrefixes($Targets));
diff --git a/testbot/bin/build/WineTest.pl b/testbot/bin/build/WineTest.pl
index b29440e21..9c264b485 100755
--- a/testbot/bin/build/WineTest.pl
+++ b/testbot/bin/build/WineTest.pl
@@ -40,93 +40,16 @@ sub BEGIN
}
$::BuildEnv = 1;
}
-my $Name0 = $0;
-$Name0 =~ s+^.*/++;
-
+use Build::Utils;
use WineTestBot::Config;
-use WineTestBot::PatchUtils;
use WineTestBot::Utils;
-#
-# Logging and error handling helpers
-#
-
-sub InfoMsg(@)
-{
- print @_;
-}
-
-sub LogMsg(@)
-{
- print "Task: ", @_;
-}
-
-sub Error(@)
-{
- print STDERR "$Name0:error: ", @_;
-}
-
-
#
# Build helpers
#
-my $ncpus;
-sub CountCPUs()
-{
- if (open(my $fh, "<", "/proc/cpuinfo"))
- {
- # Linux
- map { $ncpus++ if (/^processor/); } <$fh>;
- close($fh);
- }
- $ncpus ||= 1;
-}
-
-sub ApplyPatch($)
-{
- my ($PatchFile) = @_;
-
- InfoMsg "Applying patch\n";
- system("cd '$DataDir/wine' && ".
- "echo wine:HEAD=`git rev-parse HEAD` && ".
- "set -x && ".
- "git apply --verbose ". ShQuote($PatchFile) ." && ".
- "git add -A");
- if ($? != 0)
- {
- LogMsg "Patch failed to apply\n";
- return undef;
- }
-
- my $Impacts = GetPatchImpact($PatchFile, "nounits");
- if ($Impacts->{MakeMakefiles})
- {
- InfoMsg "\nRunning make_makefiles\n";
- system("cd '$DataDir/wine' && set -x && ./tools/make_makefiles");
- if ($? != 0)
- {
- LogMsg "make_makefiles failed\n";
- return undef;
- }
- }
-
- if ($Impacts->{Autoconf} && !$Impacts->{HasConfigure})
- {
- InfoMsg "\nRunning autoconf\n";
- system("cd '$DataDir/wine' && set -x && autoconf");
- if ($? != 0)
- {
- LogMsg "Autoconf failed\n";
- return undef;
- }
- }
-
- return $Impacts;
-}
-
sub BuildWine($$)
{
my ($Targets, $Build) = @_;
@@ -134,8 +57,9 @@ sub BuildWine($$)
return 1 if (!$Targets->{$Build});
InfoMsg "\nRebuilding the $Build Wine\n";
+ my $CPUCount = GetCPUCount();
system("cd '$DataDir/build-$Build' && set -x && ".
- "time make -j$ncpus");
+ "time make -j$CPUCount");
if ($? != 0)
{
LogMsg "The $Build build failed\n";
@@ -150,25 +74,6 @@ sub BuildWine($$)
# Test helpers
#
-# See also WineReconfig.pl
-sub SetupWineEnvironment($)
-{
- my ($Build) = @_;
-
- $ENV{WINEPREFIX} = "$DataDir/wineprefix-$Build";
- $ENV{DISPLAY} ||= ":0.0";
-}
-
-# See also WineReconfig.pl
-sub RunWine($$$)
-{
- my ($Build, $Cmd, $CmdArgs) = @_;
-
- my $Magic = `cd '$DataDir/build-$Build' && file $Cmd`;
- my $Wine = ($Magic =~ /ELF 64/ ? "./wine64" : "./wine");
- return system("cd '$DataDir/build-$Build' && set -x && ".
- "time $Wine $Cmd $CmdArgs");
-}
sub DailyWineTest($$$$$)
{
@@ -330,6 +235,12 @@ if (!defined $Usage)
}
if (defined $Usage)
{
+ my $Name0 = GetToolName();
+ if ($Usage)
+ {
+ Error "try '$Name0 --help' for more information\n";
+ exit $Usage;
+ }
print "Usage: $Name0 [--help] --testpatch TARGETS PATCH\n";
print "or $Name0 [--help] --winetest [--no-submit] TARGETS BASETAG ARGS\n";
print "\n";
@@ -365,11 +276,9 @@ if ($DataDir =~ /'/)
# Clean up old reports
map { unlink("$_.report") } keys %AllTargets;
-CountCPUs();
-
if ($Action eq "testpatch")
{
- my $Impacts = ApplyPatch($FileName);
+ my $Impacts = ApplyPatch("wine", $FileName);
exit(1) if (!$Impacts or
!BuildWine($Targets, "win32") or
!BuildWine($Targets, "wow64") or
diff --git a/testbot/lib/Build/Utils.pm b/testbot/lib/Build/Utils.pm
new file mode 100644
index 000000000..038c188f2
--- /dev/null
+++ b/testbot/lib/Build/Utils.pm
@@ -0,0 +1,363 @@
+# -*- Mode: Perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# Copyright 2018 Francois Gouget
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+
+use strict;
+
+package Build::Utils;
+
+=head1 NAME
+
+Build::Utils - Utility functions for the build scripts
+
+=cut
+
+use Exporter 'import';
+our @EXPORT = qw(GetToolName InfoMsg LogMsg Error
+ GitPull ApplyPatch
+ GetCPUCount BuildNativeTestAgentd BuildWindowsTestAgentd
+ BuildTestLauncher UpdateAddOns
+ SetupWineEnvironment RunWine CreateWinePrefix);
+
+use Digest::SHA;
+use File::Path;
+
+use WineTestBot::Config;
+use WineTestBot::PatchUtils;
+use WineTestBot::Utils;
+
+
+#
+# Logging and error handling
+#
+
+my $Name0 = $0;
+$Name0 =~ s+^.*/++;
+
+sub GetToolName()
+{
+ return $Name0;
+}
+
+sub InfoMsg(@)
+{
+ print @_;
+}
+
+sub LogMsg(@)
+{
+ print "Task: ", @_;
+}
+
+sub Error(@)
+{
+ print STDERR "$Name0:error: ", @_;
+}
+
+
+#
+# Repository updates
+#
+
+sub GitPull($)
+{
+ my ($Dir) = @_;
+
+ InfoMsg "\nUpdating the $Dir source\n";
+ system("cd '$DataDir/$Dir' && git pull");
+ if ($? != 0)
+ {
+ LogMsg "Git pull failed\n";
+ return !1;
+ }
+
+ if ($Dir eq "wine")
+ {
+ my $ErrMessage = UpdateWineData("$DataDir/$Dir");
+ if ($ErrMessage)
+ {
+ LogMsg "$ErrMessage\n";
+ return !1;
+ }
+ }
+
+ return 1;
+}
+
+sub ApplyPatch($$)
+{
+ my ($Dir, $PatchFile) = @_;
+
+ InfoMsg "Applying patch\n";
+ system("cd '$DataDir/$Dir' && ".
+ "echo $Dir:HEAD=`git rev-parse HEAD` && ".
+ "set -x && ".
+ "git apply --verbose ". ShQuote($PatchFile) ." && ".
+ "git add -A");
+ if ($? != 0)
+ {
+ LogMsg "Patch failed to apply\n";
+ return undef;
+ }
+
+ my $Impacts = GetPatchImpact($PatchFile, "nounits");
+ if ($Impacts->{MakeMakefiles})
+ {
+ InfoMsg "\nRunning make_makefiles\n";
+ system("cd '$DataDir/$Dir' && set -x && ./tools/make_makefiles");
+ if ($? != 0)
+ {
+ LogMsg "make_makefiles failed\n";
+ return undef;
+ }
+ }
+
+ if ($Impacts->{Autoconf} && !$Impacts->{HasConfigure})
+ {
+ InfoMsg "\nRunning autoconf\n";
+ system("cd '$DataDir/$Dir' && set -x && autoconf");
+ if ($? != 0)
+ {
+ LogMsg "Autoconf failed\n";
+ return undef;
+ }
+ }
+
+ return $Impacts;
+}
+
+
+#
+# Build helpers
+#
+
+my $_CPUCount;
+
+sub GetCPUCount()
+{
+ if (!defined $_CPUCount)
+ {
+ if (open(my $Fh, "<", "/proc/cpuinfo"))
+ {
+ # Linux
+ map { $_CPUCount++ if (/^processor/); } <$Fh>;
+ close($Fh);
+ }
+ $_CPUCount ||= 1;
+ }
+ return $_CPUCount;
+}
+
+sub BuildNativeTestAgentd()
+{
+ # If testagentd already exists it's likely already running
+ # so don't rebuild it.
+ return 1 if (-x "$BinDir/build/testagentd");
+
+ InfoMsg "\nBuilding the native testagentd\n";
+ my $CPUCount = GetCPUCount();
+ system("cd '$::RootDir/src/testagentd' && set -x && ".
+ "time make -j$CPUCount build");
+ if ($? != 0)
+ {
+ LogMsg "Build testagentd failed\n";
+ return !1;
+ }
+
+ return 1;
+}
+
+sub BuildWindowsTestAgentd()
+{
+ InfoMsg "\nRebuilding the Windows TestAgentd\n";
+ my $CPUCount = GetCPUCount();
+ system("cd '$::RootDir/src/testagentd' && set -x && ".
+ "time make -j$CPUCount iso");
+ if ($? != 0)
+ {
+ LogMsg "Build winetestbot.iso failed\n";
+ return !1;
+ }
+
+ return 1;
+}
+
+sub BuildTestLauncher()
+{
+ InfoMsg "\nRebuilding TestLauncher\n";
+ my $CPUCount = GetCPUCount();
+ system("cd '$::RootDir/src/TestLauncher' && set -x && ".
+ "time make -j$CPUCount");
+ if ($? != 0)
+ {
+ LogMsg "Build TestLauncher failed\n";
+ return !1;
+ }
+
+ return 1;
+}
+
+
+#
+# Wine addons updates
+#
+
+sub _VerifyAddOn($$)
+{
+ my ($AddOn, $Arch) = @_;
+
+ my $Sha256 = Digest::SHA->new(256);
+ eval { $Sha256->addfile("$DataDir/$AddOn->{name}/$AddOn->{filename}") };
+ return "$@" if ($@);
+
+ my $Checksum = $Sha256->hexdigest();
+ return undef if ($Checksum eq $AddOn->{$Arch});
+ return "Bad checksum for '$AddOn->{filename}'";
+}
+
+sub _UpdateAddOn($$$)
+{
+ my ($AddOn, $Name, $Arch) = @_;
+
+ if (!defined $AddOn)
+ {
+ LogMsg "Could not get information on the $Name addon\n";
+ return 0;
+ }
+ if (!$AddOn->{version})
+ {
+ LogMsg "Could not get the $Name version\n";
+ return 0;
+ }
+ if (!$AddOn->{$Arch})
+ {
+ LogMsg "Could not get the $Name $Arch checksum\n";
+ return 0;
+ }
+
+ $AddOn->{filename} = "wine". ($Name eq "gecko" ? "_" : "-") .
+ "$Name-$AddOn->{version}".
+ ($Arch eq "" ? "" : "-$Arch") .".msi";
+ return 1 if (!_VerifyAddOn($AddOn, $Arch));
+
+ InfoMsg "Downloading $AddOn->{filename}\n";
+ mkdir "$DataDir/$Name";
+
+ my $Url="http://dl.winehq.org/wine/wine-$Name/$AddOn->{version}/$AddOn->{filename}";
+ for (1..3)
+ {
+ system("cd '$DataDir/$Name' && set -x && ".
+ "wget --no-verbose -O- '$Url' >'$AddOn->{filename}'");
+ last if ($? == 0);
+ }
+ my $ErrMessage = _VerifyAddOn($AddOn, $Arch);
+ return 1 if (!defined $ErrMessage);
+ LogMsg "$ErrMessage\n";
+ return 0;
+}
+
+sub UpdateAddOns()
+{
+ my %AddOns;
+ if (open(my $fh, "<", "$DataDir/wine/dlls/appwiz.cpl/addons.c"))
+ {
+ my $Arch = "";
+ while (my $Line= <$fh>)
+ {
+ if ($Line =~ /^\s*#\s*define\s+ARCH_STRING\s+"([^"]+)"/)
+ {
+ $Arch = $1;
+ }
+ elsif ($Line =~ /^\s*#\s*define\s*(GECKO|MONO)_VERSION\s*"([^"]+)"/)
+ {
+ my ($AddOn, $Version) = ($1, $2);
+ $AddOn =~ tr/A-Z/a-z/;
+ $AddOns{$AddOn}->{name} = $AddOn;
+ $AddOns{$AddOn}->{version} = $Version;
+ }
+ elsif ($Line =~ /^\s*#\s*define\s*(GECKO|MONO)_SHA\s*"([^"]+)"/)
+ {
+ my ($AddOn, $Checksum) = ($1, $2);
+ $AddOn =~ tr/A-Z/a-z/;
+ $AddOns{$AddOn}->{$Arch} = $Checksum;
+ $Arch = "";
+ }
+ }
+ close($fh);
+ }
+ else
+ {
+ LogMsg "Could not open 'wine/dlls/appwiz.cpl/addons.c': $!\n";
+ return 0;
+ }
+
+ return _UpdateAddOn($AddOns{gecko}, "gecko", "x86") &&
+ _UpdateAddOn($AddOns{gecko}, "gecko", "x86_64") &&
+ _UpdateAddOn($AddOns{mono}, "mono", "");
+}
+
+
+#
+# Wine helpers
+#
+
+sub SetupWineEnvironment($)
+{
+ my ($Build) = @_;
+
+ $ENV{WINEPREFIX} = "$DataDir/wineprefix-$Build";
+ $ENV{DISPLAY} ||= ":0.0";
+}
+
+sub RunWine($$$)
+{
+ my ($Build, $Cmd, $CmdArgs) = @_;
+
+ my $Magic = `cd '$DataDir/build-$Build' && file $Cmd`;
+ my $Wine = ($Magic =~ /ELF 64/ ? "./wine64" : "./wine");
+ return system("cd '$DataDir/build-$Build' && set -x && ".
+ "time $Wine $Cmd $CmdArgs");
+}
+
+
+#
+# WinePrefix helpers
+#
+
+sub CreateWinePrefix($$)
+{
+ my ($Build, $Wait) = @_;
+
+ return "\$WINEPREFIX is not set!" if (!$ENV{WINEPREFIX});
+ rmtree($ENV{WINEPREFIX});
+
+ # Crash dialogs cause delays so disable them
+ if (RunWine($Build, "./programs/reg/reg.exe.so", "ADD HKCU\\\\Software\\\\Wine\\\\WineDbg /v ShowCrashDialog /t REG_DWORD /d 0"))
+ {
+ return "Failed to disable the $Build build crash dialogs: $!";
+ }
+
+ if ($Wait)
+ {
+ # Ensure the WinePrefix has been fully created and the registry files
+ # saved before returning.
+ system("cd '$DataDir/build-$Build' && ./server/wineserver -w");
+ }
+
+ return undef;
+}
+
+1;
--
2.18.0
More information about the wine-devel
mailing list