From 210211b7793bef626c085a354aa72ab6a397087b Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Mon, 18 Jul 2011 07:08:12 -0500 Subject: Close filehandle when done Also add a fixme, since the version headers are currently being created in the source directory. Change-Id: If6e9eeba854a1f35561b69518eb8739dc28a58be Reviewed-on: http://codereview.qt.nokia.com/1763 Reviewed-by: Qt Sanity Bot Reviewed-by: Joerg Bornemann --- bin/syncqt | 3 +++ 1 file changed, 3 insertions(+) (limited to 'bin') diff --git a/bin/syncqt b/bin/syncqt index 776ee9c257..afa323869a 100755 --- a/bin/syncqt +++ b/bin/syncqt @@ -870,6 +870,7 @@ foreach my $lib (@modules_to_sync) { my $modulepri = $modulepris{$lib}; if (-e $modulepri) { my $modulepriname = basename($modulepri); + # FIXME: this creates a file in the source location for shadow-builds my $moduleversionheader = "$modules{$lib}/" . lc($lib) . "version.h"; my $modulehexstring = sprintf("0x%02X%02X%02X", int($module_major_version), int($module_minor_version), int($module_patch_version)); open MODULE_VERSION_HEADER_FILE, ">$moduleversionheader"; @@ -882,6 +883,8 @@ foreach my $lib (@modules_to_sync) { print MODULE_VERSION_HEADER_FILE "#define " .uc($lib) . "_VERSION $modulehexstring\n", ; print MODULE_VERSION_HEADER_FILE "\n"; print MODULE_VERSION_HEADER_FILE "#endif // QT_". uc($lib) . "_VERSION_H\n"; + close MODULE_VERSION_HEADER_FILE; + print "$moduleversionheader created for $lib\n" if(!$quiet); } elsif ($modulepri) { print "WARNING: Module $lib\'s pri file '$modulepri' not found.\nSkipped creating module version header for $lib.\n"; } -- cgit v1.2.3 From e37376dbb47c01e2a3f96ce9126c441d3aae2724 Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Thu, 7 Jul 2011 18:05:49 +0000 Subject: Make syncqt output more compact by default, and add verbosity level By default, syncqt will now compress the console output of what it's doing. Increasing the verbosity level will make syncqt output the same as before Change-Id: I542072504f022f87997b4036eda5747a5da88839 Reviewed-on: http://codereview.qt.nokia.com/1764 Reviewed-by: Qt Sanity Bot Reviewed-by: Oswald Buddenhagen --- bin/syncqt | 66 ++++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 17 deletions(-) (limited to 'bin') diff --git a/bin/syncqt b/bin/syncqt index afa323869a..405f2757cf 100755 --- a/bin/syncqt +++ b/bin/syncqt @@ -38,7 +38,7 @@ our (%modules, %moduleheaders, %classnames, %mastercontent, %modulepris); my $isunix = 0; my $module = 0; my $showonly = 0; -my $quiet = 0; +my $verbose_level = 1; my $remove_stale = 1; my $force_win = 0; my $force_relative = 0; @@ -75,7 +75,9 @@ sub showUsage print " -showonly Show action but not perform (default: " . ($showonly ? "yes" : "no") . ")\n"; print " -outdir Specify output directory for sync (default: $out_basedir)\n"; print " -qtdir Set the path to QtBase (detected: " . (defined $qtbasedir ? $qtbasedir : "-none-") . ")\n"; - print " -quiet Only report problems, not activity (default: " . ($quiet ? "yes" : "no") . ")\n"; + print " -quiet Only report problems, not activity (same as -verbose 0)\n"; + print " -v, -verbose Sets the verbosity level (max. 4) (default: $verbose_level)\n"; + print " The short form increases the level by +1\n"; print " -separate-module ::\n"; print " Create headers for with original headers in\n"; print " relative to \n"; @@ -479,9 +481,9 @@ sub symlinkFile $t =~ s-^$quoted_basedir/--; $p .= "../" while( ($c = index( $t, "/", $c + 1)) != -1 ); $file =~ s-^$quoted_basedir/-$p-; - print " ($file)\n" unless $quiet; + print " ($file)\n" if($verbose_level); } - print "\n" unless $quiet; + print "\n" if($verbose_level); return symlink($file, $ifile); } return copyFile($file, $ifile); @@ -534,8 +536,10 @@ sub findFiles { ###################################################################### sub loadSyncProfile { my ($srcbase, $outbase) = @_; - print("srcbase = $$srcbase \n"); - print("outbase = $$outbase \n"); + if ($verbose_level) { + print(" = $$srcbase \n"); + print(" = $$outbase \n"); + } my $syncprofile = "$$srcbase/sync.profile"; my $result; @@ -627,8 +631,14 @@ while ( @ARGV ) { $var = "showonly"; $val = "yes"; } elsif($arg eq "-quiet") { - $var = "quiet"; + $var = "verbose"; + $val = "0"; + } elsif($arg eq "-v") { + $var = "verbose"; $val = "yes"; + } elsif($arg eq "-verbose") { + $var = "verbose"; + $val = shift @ARGV; } elsif($arg eq "-private") { $var = "create_private_headers"; $val = "yes"; @@ -667,11 +677,13 @@ while ( @ARGV ) { } elsif($showonly) { $showonly--; } - } elsif ($var eq "quiet") { + } elsif ($var eq "verbose") { if($val eq "yes") { - $quiet++; - } elsif($quiet) { - $quiet--; + $verbose_level++; + } elsif($val eq "no" && $verbose_level) { + $verbose_level--; + } else { + $verbose_level = int($val); } } elsif ($var eq "check-includes") { if($val eq "yes") { @@ -698,7 +710,7 @@ while ( @ARGV ) { $force_relative--; } } elsif ($var eq "module") { - print "module :$val:\n" unless $quiet; + print "module :$val:\n" if($verbose_level); die "No such module: $val" unless(defined $modules{$val}); push @modules_to_sync, $val; } elsif ($var eq "separate-module") { @@ -766,9 +778,7 @@ loadSyncProfile(\$basedir, \$out_basedir); $isunix = checkUnix; #cache checkUnix # create path -mkpath "$out_basedir/include", !$quiet; -mkpath "$out_basedir/include/Qt", !$quiet; - +make_path("$out_basedir/include/Qt", "", $verbose_level); foreach my $lib (@modules_to_sync) { #iteration info @@ -884,7 +894,8 @@ foreach my $lib (@modules_to_sync) { print MODULE_VERSION_HEADER_FILE "\n"; print MODULE_VERSION_HEADER_FILE "#endif // QT_". uc($lib) . "_VERSION_H\n"; close MODULE_VERSION_HEADER_FILE; - print "$moduleversionheader created for $lib\n" if(!$quiet); + $moduleversionheader = "" . substr($moduleversionheader, length($basedir)) if ($verbose_level < 2); + print "$moduleversionheader created for $lib\n" if($verbose_level); } elsif ($modulepri) { print "WARNING: Module $lib\'s pri file '$modulepri' not found.\nSkipped creating module version header for $lib.\n"; } @@ -916,6 +927,7 @@ foreach my $lib (@modules_to_sync) { push @headers, "*".$if; } } + my $header_dirname = ""; foreach my $header (@headers) { my $shadow = ($header =~ s/^\*//); $header = 0 if($header =~ /^ui_.*.h/); @@ -1026,9 +1038,29 @@ foreach my $lib (@modules_to_sync) { $pri_install_pfiles.= "$pri_install_iheader ";; } } - print "header created for $iheader ($header_copies)\n" if($header_copies > 0 && !$quiet); + + if ($verbose_level && $header_copies) { + my $new_header_dirname = dirname($iheader); + $new_header_dirname = "" . substr($new_header_dirname, length($basedir)) if ($new_header_dirname && $verbose_level < 2); + my $header_base = basename($iheader); + if ($verbose_level < 3) { + my $line_prefix = ","; + if ($new_header_dirname ne $header_dirname) { + $line_prefix = "created header(s) for $new_header_dirname/ {"; + $line_prefix = " }\n".$line_prefix if ($header_dirname); + $header_dirname = $new_header_dirname; + } else { + $line_prefix = ","; + } + print "$line_prefix $header_base ($header_copies)"; + } else { # $verbose_level >= 3 + $iheader = "" . substr($iheader, length($basedir)) if ($verbose_level == 3); + print "header created for $iheader ($header_copies)\n"; + } + } } } + print " }\n" if ($header_dirname && $verbose_level > 0 && $verbose_level < 3); } } -- cgit v1.2.3 From d83689ca6d80fb20748ca5507bd223a3c296f768 Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Thu, 7 Jul 2011 18:48:02 +0000 Subject: Prefix each output line with the library being processed Makes it easier to track which library output is coming from, when building Qt with -j > 1. Change-Id: I9acda04e84014dc441e409a0b24b2f78762dcc1c Reviewed-on: http://codereview.qt.nokia.com/1765 Reviewed-by: Qt Sanity Bot Reviewed-by: Joerg Bornemann --- bin/syncqt | 69 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 30 deletions(-) (limited to 'bin') diff --git a/bin/syncqt b/bin/syncqt index 405f2757cf..691f09139c 100755 --- a/bin/syncqt +++ b/bin/syncqt @@ -275,6 +275,15 @@ sub classNames { return @ret; } +sub make_path { + my ($dir, $lib, $be_verbose) = @_; + unless(-e $dir) { + mkpath $dir; + $dir = "" . substr($dir, length($out_basedir)) if ($be_verbose < 3); + print "$lib: mkpath $dir\n" if ($be_verbose > 1); + } +} + ###################################################################### # Syntax: syncHeader(header, iheader, copy, timestamp) # Params: header, string, filename to create "symlink" for @@ -286,14 +295,14 @@ sub classNames { # Returns: 1 if successful, else 0. ###################################################################### sub syncHeader { - my ($header, $iheader, $copy, $ts) = @_; + my ($lib, $header, $iheader, $copy, $ts) = @_; $iheader =~ s=\\=/=g; $header =~ s=\\=/=g; - return copyFile($iheader, $header) if($copy); + return copyFile($lib, $iheader, $header) if($copy); unless(-e $header) { my $header_dir = dirname($header); - mkpath $header_dir, !$quiet; + make_path($header_dir, $lib, $verbose_level); #write it my $iheader_out = fixPaths($iheader, $header_dir); @@ -414,7 +423,7 @@ sub fileCompare { ###################################################################### sub copyFile { - my ($file,$ifile, $copy,$knowdiff,$filecontents,$ifilecontents) = @_; + my ($lib, $file,$ifile, $copy,$knowdiff,$filecontents,$ifilecontents) = @_; # Bi-directional synchronization open( I, "< " . $file ) || die "Could not open $file for reading"; local $/; @@ -436,7 +445,7 @@ sub copyFile if ( $knowdiff || ($filecontents ne $ifilecontents) ) { if ( $copy > 0 ) { my $file_dir = dirname($file); - mkpath $file_dir, !$quiet unless(-e $file_dir); + make_path($file_dir, $lib, $verbose_level); open(O, "> " . $file) || die "Could not open $file for writing (no write permission?)"; local $/; binmode O; @@ -446,7 +455,7 @@ sub copyFile return 1; } elsif ( $copy < 0 ) { my $ifile_dir = dirname($ifile); - mkpath $ifile_dir, !$quiet unless(-e $ifile_dir); + make_path($ifile_dir, $lib, $verbose_level); open(O, "> " . $ifile) || die "Could not open $ifile for writing (no write permission?)"; local $/; binmode O; @@ -470,10 +479,10 @@ sub copyFile ###################################################################### sub symlinkFile { - my ($file,$ifile) = @_; + my ($lib, $file, $ifile) = @_; if ($isunix) { - print "symlink created for $file " unless $quiet; + print "$lib: symlink created for $file " if ($verbose_level); if ( $force_relative && ($ifile =~ /^$quoted_basedir/)) { my $t = getcwd(); my $c = -1; @@ -486,7 +495,7 @@ sub symlinkFile print "\n" if($verbose_level); return symlink($file, $ifile); } - return copyFile($file, $ifile); + return copyFile($lib, $file, $ifile); } ###################################################################### @@ -806,7 +815,7 @@ foreach my $lib (@modules_to_sync) { chomp $module_patch_version; } } - print "WARNING: Module $lib\'s pri missing QT..VERSION variable! Private headers not versioned!\n" if (!$module_version); + print "$lib: WARNING: Module\'s pri missing QT..VERSION variable! Private headers not versioned!\n" if (!$module_version); my $pathtoheaders = ""; $pathtoheaders = $moduleheaders{$lib} if ($moduleheaders{$lib}); @@ -895,9 +904,9 @@ foreach my $lib (@modules_to_sync) { print MODULE_VERSION_HEADER_FILE "#endif // QT_". uc($lib) . "_VERSION_H\n"; close MODULE_VERSION_HEADER_FILE; $moduleversionheader = "" . substr($moduleversionheader, length($basedir)) if ($verbose_level < 2); - print "$moduleversionheader created for $lib\n" if($verbose_level); + print "$lib: created version header $moduleversionheader\n" if($verbose_level); } elsif ($modulepri) { - print "WARNING: Module $lib\'s pri file '$modulepri' not found.\nSkipped creating module version header for $lib.\n"; + print "$lib: WARNING: Module\'s pri file '$modulepri' not found.\n$lib: Skipped creating module version header.\n"; } } @@ -994,11 +1003,11 @@ foreach my $lib (@modules_to_sync) { # class =~ s,::,/,g; # } $class_lib_map_contents .= "QT_CLASS_LIB($full_class, $lib, $header_base)\n"; - $header_copies++ if(syncHeader("$out_basedir/include/$lib/$class", "$out_basedir/include/$lib/$header", 0, $ts)); + $header_copies++ if(syncHeader($lib, "$out_basedir/include/$lib/$class", "$out_basedir/include/$lib/$header", 0, $ts)); # KDE-Compat headers for Phonon if ($lib eq "phonon") { - $header_copies++ if (syncHeader("$out_basedir/include/phonon_compat/Phonon/$class", "$out_basedir/include/$lib/$header", 0, $ts)); + $header_copies++ if (syncHeader($lib, "$out_basedir/include/phonon_compat/Phonon/$class", "$out_basedir/include/$lib/$header", 0, $ts)); } } } elsif ($create_private_headers) { @@ -1009,7 +1018,7 @@ foreach my $lib (@modules_to_sync) { } } foreach(@headers) { #sync them - $header_copies++ if(syncHeader($_, $iheader, $copy_headers && !$shadow, $ts)); + $header_copies++ if(syncHeader($lib, $_, $iheader, $copy_headers && !$shadow, $ts)); } if($public_header) { @@ -1046,7 +1055,7 @@ foreach my $lib (@modules_to_sync) { if ($verbose_level < 3) { my $line_prefix = ","; if ($new_header_dirname ne $header_dirname) { - $line_prefix = "created header(s) for $new_header_dirname/ {"; + $line_prefix = "$lib: created fwd-include header(s) for $new_header_dirname/ {"; $line_prefix = " }\n".$line_prefix if ($header_dirname); $header_dirname = $new_header_dirname; } else { @@ -1055,7 +1064,7 @@ foreach my $lib (@modules_to_sync) { print "$line_prefix $header_base ($header_copies)"; } else { # $verbose_level >= 3 $iheader = "" . substr($iheader, length($basedir)) if ($verbose_level == 3); - print "header created for $iheader ($header_copies)\n"; + print "$lib: created $header_copies fwd-include headers for $iheader\n"; } } } @@ -1086,11 +1095,11 @@ foreach my $lib (@modules_to_sync) { } if($master_include && $master_contents) { my $master_dir = dirname($master_include); - mkpath $master_dir, !$quiet; - print "header (master) created for $lib\n" unless $quiet; + make_path($master_dir, $lib, $verbose_level); open MASTERINCLUDE, ">$master_include"; print MASTERINCLUDE $master_contents; close MASTERINCLUDE; + print "$lib: created header (master) file\n" if($verbose_level); } } @@ -1111,11 +1120,11 @@ foreach my $lib (@modules_to_sync) { } if($headers_pri_file && $master_contents) { my $headers_pri_dir = dirname($headers_pri_file); - mkpath $headers_pri_dir, !$quiet; - print "headers.pri file created for $lib\n" unless $quiet; + make_path($headers_pri_dir, $lib, $verbose_level); open HEADERS_PRI_FILE, ">$headers_pri_file"; print HEADERS_PRI_FILE $headers_pri_contents; close HEADERS_PRI_FILE; + print "$lib: created headers.pri file\n" if($verbose_level); } # create forwarding module pri in qtbase/mkspecs/modules @@ -1123,7 +1132,7 @@ foreach my $lib (@modules_to_sync) { my $modulepri = $modulepris{$lib}; if (-e $modulepri) { my $modulepriname = basename($modulepri); - mkpath($module_fwd); + make_path($module_fwd, $lib, $verbose_level); my $moduleprifwd = "$module_fwd/$modulepriname"; my $mod_base = $developer_build ? $basedir : $out_basedir; my $mod_component_base = $developer_build ? $qtbasedir : $out_basedir; @@ -1149,7 +1158,7 @@ foreach my $lib (@modules_to_sync) { } } } elsif ($modulepri) { - print "WARNING: Module $lib\'s pri file '$modulepri' not found.\nSkipped creating forwarding pri for $lib.\n"; + print "$lib: WARNING: Module\'s pri file '$modulepri' not found.\n$lib: Skipped creating forwarding pri.\n"; } } } @@ -1167,7 +1176,7 @@ unless($showonly || !$create_uic_class_map) { } if($class_lib_map) { my $class_lib_map_dir = dirname($class_lib_map); - mkpath $class_lib_map_dir, !$quiet; + make_path($class_lib_map_dir, "", $verbose_level); open CLASS_LIB_MAP, ">$class_lib_map"; print CLASS_LIB_MAP $class_lib_map_contents; close CLASS_LIB_MAP; @@ -1251,7 +1260,7 @@ if($check_includes) { if($include) { for my $trylib (keys(%modules)) { if(-e "$out_basedir/include/$trylib/$include") { - print "WARNING: $iheader includes $include when it should include $trylib/$include\n"; + print "$lib: WARNING: $iheader includes $include when it should include $trylib/$include\n"; } } } @@ -1269,27 +1278,27 @@ if($check_includes) { } if ($header_skip_qt_begin_header_test == 0) { if ($qt_begin_header_found == 0) { - print "WARNING: $iheader does not include QT_BEGIN_HEADER\n"; + print "$lib: WARNING: $iheader does not include QT_BEGIN_HEADER\n"; } if ($qt_begin_header_found && $qt_end_header_found == 0) { - print "WARNING: $iheader has QT_BEGIN_HEADER but no QT_END_HEADER\n"; + print "$lib: WARNING: $iheader has QT_BEGIN_HEADER but no QT_END_HEADER\n"; } } if ($header_skip_qt_begin_namespace_test == 0) { if ($qt_begin_namespace_found == 0) { - print "WARNING: $iheader does not include QT_BEGIN_NAMESPACE\n"; + print "$lib: WARNING: $iheader does not include QT_BEGIN_NAMESPACE\n"; } if ($qt_begin_namespace_found && $qt_end_namespace_found == 0) { - print "WARNING: $iheader has QT_BEGIN_NAMESPACE but no QT_END_NAMESPACE\n"; + print "$lib: WARNING: $iheader has QT_BEGIN_NAMESPACE but no QT_END_NAMESPACE\n"; } } if ($header_skip_qt_module_test == 0) { if ($qt_module_found == 0) { - print "WARNING: $iheader does not include QT_MODULE\n"; + print "$lib: WARNING: $iheader does not include QT_MODULE\n"; } } close(F); -- cgit v1.2.3 From 997b2a96c1aec1c7f35cd2228eba907f29a28f25 Mon Sep 17 00:00:00 2001 From: Michael Goddard Date: Thu, 30 Jun 2011 14:51:16 +1000 Subject: Add rudimentary config.test support when configuring modules. An extra script is added (qtmodule-configtests) which is currently invoked from syncqt (with some derived parameters passed to it). The module can optionally have an entry in the module's sync.profile file in the form of a perl map of "test name" => parameters. Tests can print an advisory message if they fail (e.g. "Install this SDK/dev package"), or abort the syncqt process (e.g. mandatory prereq missing). Also, if the test has a "requires(foo)" line that results in it being skipped, this is also supported. Change-Id: Ic3c820a488a0992c944994d4d7dc283da36742d6 Reviewed-on: http://codereview.qt.nokia.com/928 Reviewed-by: Qt Sanity Bot Reviewed-by: Sarah Jane Smith Reviewed-by: Marius Storm-Olsen --- bin/qtmodule-configtests | 337 +++++++++++++++++++++++++++++++++++++++++++++++ bin/syncqt | 17 +++ 2 files changed, 354 insertions(+) create mode 100755 bin/qtmodule-configtests (limited to 'bin') diff --git a/bin/qtmodule-configtests b/bin/qtmodule-configtests new file mode 100755 index 0000000000..a5c5899cc5 --- /dev/null +++ b/bin/qtmodule-configtests @@ -0,0 +1,337 @@ +#!/usr/bin/perl +###################################################################### +# +# Runs any module configuration tests +# +# Called (currently) from syncqt, and expects a few arguments +# +# configtests $basedir $out_basedir $qtbasedir $quietmode +# +# Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +# Contact: Nokia Corporation (qt-info@nokia.com) +# +###################################################################### + +use strict; +use warnings; + +# use packages ------------------------------------------------------- +use File::Basename; +use File::Path 'mkpath'; +use File::Spec::Functions; +use Cwd; +use Cwd 'abs_path'; +use Config; + +# Which file to look for the %configtests variable in +my $configTestSource = "sync.profile"; + +if ($#ARGV < 3) { + warn "Usage:\n"; + warn " $0 \n"; + exit 1; +} + +# These might be needed in sync.profile +our $basedir = $ARGV[0]; +our $out_basedir = $ARGV[1]; +our $qtbasedir = $ARGV[2]; +my $generator = $ARGV[3]; + +our %configtests; + +my $qmakeCachePath = catfile($out_basedir, ".qmake.cache"); + +my $QMAKE = catfile($qtbasedir, "bin", ($^O =~ /win32/i) ? 'qmake.exe' : 'qmake'); +if (!-x $QMAKE) { + # try the qmake from the path (e.g. this is a shadow build) + $QMAKE = 'qmake'; +} + +# Need to use the right make +# SYMBIAN_UNIX/MINGW should fall back to the non SYMBIAN ones +my $MAKE = 'make'; # default, only works on unix +if ($generator =~ /UNIX|XCODE/i) { # XCODE = make? + $MAKE = 'make'; +} elsif ($generator =~ /MINGW/i) { + $MAKE = 'mingw32-make'; +} elsif ($generator =~ /MSVC.NET|MSBUILD/i) { + $MAKE = 'nmake'; +} else { + # Unhandled (at least): BMAKE, GBUILD, SYMBIAN_ABLD, SYMBIAN_SBSV2 + warn "Unrecognized generator spec ($generator) - assuming '$MAKE'\n"; +} + +###################################################################### +# Syntax: fileContents(filename) +# Params: filename, string, filename of file to return contents +# +# Purpose: Get the contents of a file. +# Returns: String with contents of the file, or empty string if file +# doens't exist. +# Warning: Dies if it does exist but script cannot get read access. +###################################################################### +sub fileContents { + my ($filename) = @_; + my $filecontents = ""; + if (-e $filename) { + open(I, "< $filename") || die "Could not open $filename for reading, read block?"; + local $/; + binmode I; + $filecontents = ; + close I; + } + return $filecontents; +} + +###################################################################### +# Syntax: loadConfigTests() +# +# Purpose: Loads the config tests from the source basedir into %configtests. +# Returns: Nothing +###################################################################### +sub loadConfigTests { + my $configprofile = catfile($basedir, $configTestSource); + my $result; + unless ($result = do $configprofile) { + die "configtests couldn't parse $configprofile: $@\n" if $@; + # We don't check for non null output, since that is valid + } +} + +###################################################################### +# Syntax: hashesAreDifferent +# +# Purpose: Compares two hashes. (must have same key=value for everything) +# Returns: 0 if they are the same, 1 otherwise +###################################################################### +sub hashesAreDifferent { + my %a = %{$_[0]}; + my %b = %{$_[1]}; + + if (keys %a != keys %b) { + return 1; + } + + my %cmp = map { $_ => 1 } keys %a; + for my $key (keys %b) { + last unless exists $cmp{$key}; + last unless $a{$key} eq $b{$key}; + delete $cmp{$key}; + } + if (%cmp) { + return 1; + } else { + return 0; + } +} + +###################################################################### +# Syntax: executeSomething +# Params: A list of things. +# +# Purpose: Executes the first arg, passing the list. +# stderr is redirected to stdout, and the output is captured. +# Returns: The output. +###################################################################### +sub executeSomething { + my @args = @_; + my $program = $args[0]; + + my $pid = open(KID_TO_READ, "-|"); + + my $output; + + if ($pid) { # parent + while () { + $output = $output . $_; + } + close(KID_TO_READ) || $! == 0 || warn "\nFailed to execute $program: exited $?"; + } else { + # redirect STDERR to STDOUT + open STDERR, ">&STDOUT"; + + # Exec something + exec ($program, @args) || die "\nCan't exec $program: $!\n"; + # NOTREACHED + } + + return $output; +} + +###################################################################### +# Syntax: executeTest() +# Params: testName +# +# The testName variable controls the actual config test run - the +# source is assumed to be in $basedir/config.tests/$testName, and +# when 'qmake; make clean; make' is run, is expected to produce a file +# $out_basedir/config.tests/$testName/$testName. If this test passes, +# then 'config_test_$testName = yes' will be written to $out_basedir/.qmake.cache +# +# Purpose: Runs a configuration time test. +# Returns: 0 if the test fails, 1 if it passes, 2 if the test is skipped +# (e.g. .pro file has requires(x) and x is not satisfied) +###################################################################### +sub executeTest { + my ($testName) = @_; + + my $oldWorkingDir = getcwd(); + my $ret = 0; + + my @QMAKEARGS = ('CONFIG-=debug_and_release'); + + my $testOutDir = catdir($out_basedir, 'config.tests', $testName); + + if (abs_path($basedir) eq abs_path($out_basedir)) { + chdir $testOutDir or die "\nUnable to change to config test directory ($testOutDir): $!\n"; + } else { # shadow build + if (! -e $testOutDir) { + mkpath $testOutDir or die "\nUnable to create shadow build config test directory ($testOutDir): $!\n"; + } + chdir $testOutDir or die "\nUnable to change to config test directory ($testOutDir): $!\n"; + + push (@QMAKEARGS, catdir($basedir, 'config.tests', $testName)); + } + + # Throw it all away + executeSomething($QMAKE, @QMAKEARGS); + executeSomething($MAKE, 'clean'); + my $makeOutput = executeSomething(($MAKE)); + + # If make prints "blah blah blah\nSkipped." we consider this a skipped test + if ($makeOutput !~ qr(^Skipped\.$)ms) { + + # Check the test exists (can't reliably execute, especially for cross compilation) + if ($^O =~ /win32/i) { + # On windows look for $testName.exe + if (-e catfile($testOutDir, "$testName.exe")) { + $ret = 1; + } + } else { + if (-e catfile($testOutDir, $testName)) { + $ret = 1; + } + } + } else { + $ret = 2; + } + + chdir $oldWorkingDir or die "\nUnable to restore working directory: $!\n"; + return $ret; +} + +# Now run configuration tests +# %configtests is a map from config test name to a map of parameters +# e.g: +# +# %configtests = ( +# "simple" => {fatal => 1, message => "Missing required 'simple' component\n"}, +# "failed" => {message => "You need to install the FAILED sdk for this to work\n"} +# ); +# +# Parameters and their defaults: +# - fatal [false] - whether failing this test should abort everything +# - message [""] - A special message to display if this test fails +# +loadConfigTests(); + +# Only do this step for modules that have config tests +# (qtbase doesn't). We try to preserve existing contents (and furthermore +# only write to .qmake.cache if the tests change) +if (abs_path($out_basedir) ne abs_path($qtbasedir)) { + # Read any existing content + my $existingContents = fileContents($qmakeCachePath); + my %oldTestResults; + my %newTestResults; + my @fatalTestsEncountered; + + # Parse the existing results so we can check if we change them + while ($existingContents =~ /^config_test_(.*) = (yes|no)$/gm) { + $oldTestResults{$1} = $2; + } + + # Get the longest length test name so we can pretty print + use List::Util qw(max); + my $maxNameLength = max map { length $_ } keys %configtests; + + # Turn off buffering + $| = 1; + + # Now run the configuration tests + print "Configuration tests:\n"; + + while ((my $testName, my $testParameters) = each %configtests) { + printf " % *s: ", $maxNameLength, $testName; # right aligned, yes/no lines up + + my $fatalTest = $testParameters->{"fatal"} // 0; + my $message = $testParameters->{"message"}; + + my $testResult = executeTest($testName); + my @testResultStrings = ("no\n","yes\n","skipped\n"); + + $newTestResults{$testName} = (($testResult == 1) ? "yes" : "no"); # skipped = no + + if ($testResult == 0) { + # Failed test + if ($fatalTest) { + print "no (fatal)\n"; + # Report the fatality at the end, too + push (@fatalTestsEncountered, $testName); + } else { + print "no\n"; + } + if (defined($message)) { + print $message; + print "\n" unless chop $message eq "\n"; + } + } else { + # yes or skipped + print $testResultStrings[$testResult]; + } + } + + # Check if the test results are different + if (hashesAreDifferent(\%oldTestResults, \%newTestResults)) { + # Generate the new contents + my $newContents = $existingContents; + + # Strip out any existing config test results + $newContents =~ s/^config_test_.*$//gms; + $newContents =~ s/^# Compile time test results.*$//gms; + + # Add any remaining content and make sure we start on a new line + if ($newContents and chop $newContents ne '\n') { + $newContents = $newContents . "\n"; + } + + # Results and header + if (%newTestResults) { + $newContents = $newContents . '# Compile time test results ('.(localtime).")\n"; + + # Results + while ((my $testName, my $testResult) = each %newTestResults) { + $newContents = $newContents . "config_test_$testName = $testResult\n"; + } + } + + # and open the file + open my $cacheFileHandle, ">$qmakeCachePath" or die "Unable to open $qmakeCachePath for writing: $!\n"; + + print $cacheFileHandle $newContents; + + close $cacheFileHandle or die "Unable to close $qmakeCachePath: $!\n"; + } + + # Now see if we have to die + if (@fatalTestsEncountered) { + if ($#fatalTestsEncountered == 0) { + warn "Mandatory configuration test (".$fatalTestsEncountered[0].") failed.\n\n"; + } else { + warn "Mandatory configuration tests (". join (", ", @fatalTestsEncountered) . ") failed.\n\n"; + } + exit -1; + } +} + +exit 0; diff --git a/bin/syncqt b/bin/syncqt index 691f09139c..0c22cf8a6f 100755 --- a/bin/syncqt +++ b/bin/syncqt @@ -15,6 +15,7 @@ use Cwd; use Cwd 'abs_path'; use Config; use strict; +use English qw(-no_match_vars ); # set output basedir to be where ever syncqt is run from our $out_basedir = getcwd(); @@ -50,6 +51,7 @@ my $module_fwd = ""; my $cache_module_fwd = 0; my $developer_build = 0; my $no_module_version_header = 0; +my $makefile_generator = ""; my @modules_to_sync ; $force_relative = 1 if ( -d "/System/Library/Frameworks" ); @@ -90,6 +92,7 @@ sub showUsage print " easy development\n"; print " -no-module-version-header\n"; print " Don't create module version header file\n"; + print " -generator Specify the makefile generator setting (e.g. 'UNIX')\n"; print " -help This help\n"; exit 0; } @@ -658,6 +661,9 @@ while ( @ARGV ) { # skip, it's been dealt with at the top of the file shift @ARGV; next; + } elsif($arg eq "-generator") { + $var = "makefile_generator"; + $val = shift @ARGV; } elsif($arg =~/^-/) { print "Unknown option: $arg\n\n" if(!$var); showUsage(); @@ -741,6 +747,8 @@ while ( @ARGV ) { $cache_module_fwd = 1; } elsif ($var eq "developer_build") { $developer_build = 1; + } elsif ($var eq "makefile_generator") { + $makefile_generator = $val; } elsif ($var eq "no_module_version_header") { $no_module_version_header = 1; } elsif ($var eq "output") { @@ -1310,4 +1318,13 @@ if($check_includes) { } } +# Do configure tests now (pass some things along) +# fatal tests have a non zero return +unless ($showonly) { + my $configtests = dirname($0)."/qtmodule-configtests"; + if (system($EXECUTABLE_NAME, $configtests, $basedir, $out_basedir, $qtbasedir, $makefile_generator)) { + die "$configtests exited with status $?"; + } +} + exit 0; -- cgit v1.2.3 From d55aa1ad2aa2391eb6b32fa696867fd8b20e570b Mon Sep 17 00:00:00 2001 From: Michael Goddard Date: Mon, 25 Jul 2011 10:10:54 +1000 Subject: Tighten up the config test success checking. Try a lot harder to remove the old $TARGET output, since make clean isn't sufficient. Also fix a bug in program invocation that was hidden because of the stale files. Change-Id: I0a365409d81efb74c5836eaf9f129fd9b2cca77e Reviewed-on: http://codereview.qt.nokia.com/2052 Reviewed-by: Qt Sanity Bot Reviewed-by: Rohan McGovern --- bin/qtmodule-configtests | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'bin') diff --git a/bin/qtmodule-configtests b/bin/qtmodule-configtests index a5c5899cc5..f6cc2052da 100755 --- a/bin/qtmodule-configtests +++ b/bin/qtmodule-configtests @@ -135,8 +135,7 @@ sub hashesAreDifferent { # Returns: The output. ###################################################################### sub executeSomething { - my @args = @_; - my $program = $args[0]; + my ($program, @args) = @_; my $pid = open(KID_TO_READ, "-|"); @@ -183,6 +182,10 @@ sub executeTest { my $testOutDir = catdir($out_basedir, 'config.tests', $testName); + # Since we might be cross compiling, look for barename (Linux) and .exe (Win32/Symbian) + my $testOutFile1 = catfile($testOutDir, "$testName.exe"); + my $testOutFile2 = catfile($testOutDir, $testName); + if (abs_path($basedir) eq abs_path($out_basedir)) { chdir $testOutDir or die "\nUnable to change to config test directory ($testOutDir): $!\n"; } else { # shadow build @@ -194,24 +197,24 @@ sub executeTest { push (@QMAKEARGS, catdir($basedir, 'config.tests', $testName)); } - # Throw it all away + # First remove existing stuff (XXX this probably needs generator specific code, but hopefully + # the target removal below will suffice) + if (-e "Makefile") { + executeSomething($MAKE, 'distclean'); + } + + # and any targets that we might find that weren't distcleaned + unlink $testOutFile1, $testOutFile2; + + # Run qmake && make executeSomething($QMAKE, @QMAKEARGS); - executeSomething($MAKE, 'clean'); my $makeOutput = executeSomething(($MAKE)); # If make prints "blah blah blah\nSkipped." we consider this a skipped test if ($makeOutput !~ qr(^Skipped\.$)ms) { - # Check the test exists (can't reliably execute, especially for cross compilation) - if ($^O =~ /win32/i) { - # On windows look for $testName.exe - if (-e catfile($testOutDir, "$testName.exe")) { - $ret = 1; - } - } else { - if (-e catfile($testOutDir, $testName)) { - $ret = 1; - } + if (-e $testOutFile1 or -e $testOutFile2) { + $ret = 1; } } else { $ret = 2; -- cgit v1.2.3 From 2dc77d9264f3a5b713c1742515d627c92a1b61b6 Mon Sep 17 00:00:00 2001 From: Michael Goddard Date: Mon, 25 Jul 2011 22:07:54 +1000 Subject: Try to make sure the config test script is installed. And try to fail a bit more gracefully if it isn't. Change-Id: I62e01c0536aa0a032940d6a9a5ccf5edcfeef221 Reviewed-on: http://codereview.qt.nokia.com/2109 Reviewed-by: Qt Sanity Bot Reviewed-by: Rohan McGovern Reviewed-by: Michael Goddard --- bin/syncqt | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'bin') diff --git a/bin/syncqt b/bin/syncqt index 0c22cf8a6f..0dcbc4d58e 100755 --- a/bin/syncqt +++ b/bin/syncqt @@ -1320,10 +1320,18 @@ if($check_includes) { # Do configure tests now (pass some things along) # fatal tests have a non zero return -unless ($showonly) { +# If the generator is not set (e.g. someone invoking syncqt as part of configure etc, then don't run tests either) +unless ($showonly || $makefile_generator eq '') { my $configtests = dirname($0)."/qtmodule-configtests"; - if (system($EXECUTABLE_NAME, $configtests, $basedir, $out_basedir, $qtbasedir, $makefile_generator)) { - die "$configtests exited with status $?"; + if (! -f $configtests) { + $configtests = $qtbasedir."/bin/qtmodule-configtests"; + } + if (! -f $configtests) { + warn "Unable to locate qtmodule-configtests script - config tests disabled.\n"; + } else { + if (system($EXECUTABLE_NAME, $configtests, $basedir, $out_basedir, $qtbasedir, $makefile_generator)) { + die "$configtests exited with status $?"; + } } } -- cgit v1.2.3