Changeset 846 for trunk/bin


Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
7 edited
3 copied

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/bin/createpackage.bat

    r651 r846  
    11:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    22::
    3 :: Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3:: Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44:: All rights reserved.
    55:: Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/bin/createpackage.pl

    r769 r846  
    22#############################################################################
    33##
    4 ## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    55## All rights reserved.
    66## Contact: Nokia Corporation (qt-info@nokia.com)
     
    6969Usage: createpackage.pl [options] templatepkg [target]-[platform] [certificate key [passphrase]]
    7070
    71 Where supported optiobns are as follows:
    72      [-i|install]            = Install the package right away using PC suite
     71Where supported options are as follows:
     72     [-i|install]            = Install the package right away using PC suite.
    7373     [-p|preprocess]         = Only preprocess the template .pkg file.
    74      [-c|certfile=<file>]    = The file containing certificate information for signing.
     74     [-c|certfile <file>]    = The file containing certificate information for signing.
    7575                               The file can have several certificates, each specified in
    7676                               separate line. The certificate, key and passphrase in line
     
    7878                               as a comments. Also empty lines are ignored. The paths in
    7979                               <file> can be absolute or relative to <file>.
    80      [-u|unsigned]           = Preserves the unsigned package
     80     [-u|unsigned]           = Preserves the unsigned package.
     81     [-o|only-unsigned]      = Creates only unsigned package.
     82     [-s|stub]               = Generates stub sis for ROM.
     83     [-n|sisname <name>]     = Specifies the final sis name.
     84     [-g|gcce-is-armv5]      = Convert gcce platform to armv5.
     85     [-d|dont-patch]         = Skip automatic patching of capabilities and pkg file if default certificate
     86                               is used. Instead non-self-signable capabilities just cause warnings.
    8187Where parameters are as follows:
    8288     templatepkg             = Name of .pkg file template
     
    8490     platform                = One of the supported platform
    8591                               winscw | gcce | armv5 | armv6 | armv7
     92                               Note that when packaging binaries built using gcce and symbian-sbsv2
     93                               mkspec, armv5 must be used for platform instead of gcce.
    8694     certificate             = The certificate file used for signing
    8795     key                     = The certificate's private key file
    88      passphrase              = The certificate's private key file's passphrase
     96     passphrase              = The passphrase of the certificate's private key file
    8997
    9098Example:
     
    102110If no certificate and key files are provided, either a RnD certificate or
    103111a self-signed certificate from QtDir\\src\\s60installs directory is used.
     112In the latter case the resulting package will also be automatically patched
     113using patch_capabilities.pl script, which makes it unsuitable for distribution.
     114Always specify certificates explicitly if you wish to distribute your package.
     115
    104116==============================================================================================
    105117
     
    115127my $preserveUnsigned = "";
    116128my $stub = "";
     129my $signed_sis_name = "";
     130my $onlyUnsigned = "";
     131my $convertGcce = "";
     132my $dontPatchCaps = "";
    117133
    118134unless (GetOptions('i|install' => \$install,
     
    120136                   'c|certfile=s' => \$certfile,
    121137                   'u|unsigned' => \$preserveUnsigned,
    122                    's|stub' => \$stub,)){
     138                   'o|only-unsigned' => \$onlyUnsigned,
     139                   's|stub' => \$stub,
     140                   'n|sisname=s' => \$signed_sis_name,
     141                   'g|gcce-is-armv5' => \$convertGcce,
     142                   'd|dont-patch' => \$dontPatchCaps,)) {
    123143    Usage();
     144}
     145
     146my $epocroot = $ENV{EPOCROOT};
     147my $epocToolsDir = "";
     148if ($epocroot ne "") {
     149    $epocroot =~ s,\\,/,g;
     150    if ($epocroot =~ m,[^/]$,) {
     151        $epocroot = $epocroot."/";
     152    }
     153    $epocToolsDir = "${epocroot}epoc32/tools/";
    124154}
    125155
     
    130160my $targetplatform = lc $ARGV[1];
    131161
     162if ($targetplatform eq "") {
     163    $targetplatform = "-";
     164}
     165
    132166my @tmpvalues = split('-', $targetplatform);
    133 my $target = $tmpvalues[0];
    134 my $platform = $tmpvalues[1];;
     167my $target;
     168$target = $tmpvalues[0] or $target = "";
     169my $platform;
     170$platform = $tmpvalues[1] or $platform = "";
     171
     172if ($platform =~ m/^gcce$/i) {
     173    if (($convertGcce ne "")) {
     174        $platform = "armv5";
     175    } elsif ($ENV{SBS_HOME}) {
     176        # Print a informative note in case suspected misuse is detected.
     177        print "\nNote: You should use armv5 as platform or specify -g parameter to convert platform\n";
     178        print "      when packaging gcce binaries built using symbian-sbsv2 mkspec.\n\n";
     179    }
     180}
    135181
    136182# Convert visual target to real target (debug->udeb and release->urel)
     
    138184$target =~ s/release/urel/i;
    139185
    140 my $certificate = $ARGV[2];
    141 my $key = $ARGV[3];
    142 my $passphrase = $ARGV[4];
     186my $certificate;
     187$certificate = $ARGV[2] or $certificate = "";
     188my $key;
     189$key = $ARGV[3] or $key = "";
     190my $passphrase;
     191$passphrase = $ARGV[4] or $passphrase = "";
    143192
    144193# Generate output pkg basename (i.e. file name without extension)
     
    146195my $preservePkgOutput = "";
    147196$pkgoutputbasename =~ s/_template/_$targetplatform/g;
     197$pkgoutputbasename =~ s/_installer\.pkg/_installer___temp\.pkg/g;
    148198if ($pkgoutputbasename eq $templatepkg) {
    149199    $preservePkgOutput = "1";
    150200}
    151201$pkgoutputbasename =~ s/\.pkg//g;
    152 $pkgoutputbasename = lc($pkgoutputbasename);
    153202
    154203# Store output file names to variables
    155 my $pkgoutput = lc($pkgoutputbasename.".pkg");
    156 my $sisoutputbasename = lc($pkgoutputbasename);
    157 $sisoutputbasename =~ s/_$targetplatform//g;
     204my $pkgoutput = $pkgoutputbasename.".pkg";
     205my $sisoutputbasename;
     206if ($signed_sis_name eq "") {
     207    $sisoutputbasename = $pkgoutputbasename;
     208    $sisoutputbasename =~ s/_$targetplatform//g;
     209    $sisoutputbasename =~ s/_installer___temp/_installer/g;
     210    $signed_sis_name = $sisoutputbasename.".sis";
     211} else {
     212    $sisoutputbasename = $signed_sis_name;
     213    if ($sisoutputbasename =~ m/(\.sis$|\.sisx$)/i) {
     214        $sisoutputbasename =~ s/$1//i;
     215    } else {
     216        $signed_sis_name = $signed_sis_name.".sis";
     217    }
     218}
     219
     220my $installer_unsigned_app_sis_name = "";
     221my $installer_app_sis_name = "";
     222
     223if ($templatepkg =~ m/_installer\.pkg$/i && $onlyUnsigned) {
     224    $installer_unsigned_app_sis_name = $templatepkg;
     225    $installer_unsigned_app_sis_name =~ s/_installer.pkg$/_unsigned.sis/i;
     226    $installer_app_sis_name = $installer_unsigned_app_sis_name;
     227    $installer_app_sis_name =~ s/_unsigned.sis$/.sis/;
     228}
     229
    158230my $unsigned_sis_name = $sisoutputbasename."_unsigned.sis";
    159 my $signed_sis_name = $sisoutputbasename.".sis";
    160 my $stub_sis_name = $sisoutputbasename."_stub.sis";
     231my $stub_sis_name = $sisoutputbasename.".sis";
    161232
    162233# Store some utility variables
    163234my $scriptpath = dirname(__FILE__);
    164235my $certtext = $certificate;
    165 my $certpath = $scriptpath;
    166 $certpath =~ s-^(.*[^\\])$-$1\\-o;          # ensure path ends with a backslash
    167 $certpath =~ s-/-\\-go;                     # for those working with UNIX shells
    168 $certpath =~ s-bin\\$-src\\s60installs\\-;  # certificates are one step up in hierarcy
     236# certificates are one step up in hierarchy
     237my $certpath = File::Spec->catdir($scriptpath, File::Spec->updir(), "src/s60installs/");
    169238
    170239# Check some pre-conditions and print error messages if needed.
    171240unless (length($templatepkg)) {
    172     print "\nError: Template PKG filename is not defined!\n";
     241    print "\nERROR: Template PKG filename is not defined!\n";
    173242    Usage();
    174 }
    175 
    176 # If the pkg file is not actually a template, there is no need for plaform or target.
    177 if ($templatepkg =~ m/_template\.pkg/i) {
    178     unless (length($platform) && length($target)) {
    179         print "\nError: Platform or target is not defined!\n";
    180         Usage();
    181     }
    182243}
    183244
     
    185246stat($templatepkg);
    186247unless( -e _ ) {
    187     print "\nError: Package description file '$templatepkg' does not exist!\n";
     248    print "\nERROR: Package description file '$templatepkg' does not exist!\n";
    188249    Usage();
    189250}
     
    192253if (length($certificate)) {
    193254    unless(length($key)) {
    194         print "\nError: Custom certificate key file parameter missing.!\n";
     255        print "\nERROR: Custom certificate key file parameter missing.!\n";
    195256        Usage();
    196257    }
     
    198259    #If no certificate is given, check default options
    199260    $certtext = "RnD";
    200     $certificate = $certpath."rd.cer";
    201     $key = $certpath."rd-key.pem";
     261    $certificate = File::Spec->catfile($certpath, "rd.cer");
     262    $key = File::Spec->catfile($certpath, "rd-key.pem");
    202263
    203264    stat($certificate);
    204265    unless( -e _ ) {
    205266        $certtext = "Self Signed";
    206         $certificate = $certpath."selfsigned.cer";
    207         $key = $certpath."selfsigned.key";
     267        $certificate = File::Spec->catfile($certpath, "selfsigned.cer");
     268        $key = File::Spec->catfile($certpath, "selfsigned.key");
    208269    }
    209270}
     
    227288        # Do some validation
    228289        unless(scalar(@certinfo) >= 2 && scalar(@certinfo) <= 3 && length($certinfo[0]) && length($certinfo[1]) ) {
    229             print "\nError: $certfile line '$_' does not contain valid information!\n";
     290            print "\nERROR: $certfile line '$_' does not contain valid information!\n";
    230291            Usage();
    231292        }
     
    237298# Remove any existing .sis packages
    238299unlink $unsigned_sis_name;
    239 unlink $signed_sis_name;
     300if (!$onlyUnsigned) {
     301    unlink $signed_sis_name;
     302}
    240303if (!$preservePkgOutput) {
    241304    unlink $pkgoutput;
     
    243306
    244307# Preprocess PKG
     308
    245309local $/;
    246310# read template file
    247 open( TEMPLATE, $templatepkg) or die "Error '$templatepkg': $!\n";
     311open( TEMPLATE, $templatepkg) or die "ERROR: '$templatepkg': $!";
    248312$_=<TEMPLATE>;
    249313close (TEMPLATE);
     314
     315# If the pkg file does not contain macros, there is no need for platform or target.
     316if (m/\$\(PLATFORM\)/) {
     317    unless (length($platform) && length($target)) {
     318        print "\nERROR: Platform or target is not defined!\n";
     319        Usage();
     320    }
     321}
    250322
    251323# replace the PKG variables
     
    253325s/\$\(TARGET\)/$target/gm;
    254326
     327if ($installer_unsigned_app_sis_name ne "") {
     328    s/$installer_app_sis_name\"/$installer_unsigned_app_sis_name\"/;
     329}
     330
    255331#write the output
    256 open( OUTPUT, ">$pkgoutput" ) or die "Error '$pkgoutput' $!\n";
     332open( OUTPUT, ">$pkgoutput" ) or die "ERROR: '$pkgoutput' $!";
    257333print OUTPUT $_;
    258334close OUTPUT;
     
    263339
    264340if($stub) {
    265     if(!($ENV{EPOCROOT})) { die("EPOCROOT must be set to create stub sis files"); }
    266     my $systeminstall = "$ENV{EPOCROOT}epoc32/data/z/system/install";
     341    if(!($epocroot)) { die("ERROR: EPOCROOT must be set to create stub sis files"); }
     342    my $systeminstall = "${epocroot}epoc32/data/z/system/install";
    267343    mkpath($systeminstall);
    268344    my $stub_sis_name = $systeminstall."/".$stub_sis_name;
    269345    # Create stub SIS.
    270     system ("makesis -s $pkgoutput $stub_sis_name");
     346    system ("${epocToolsDir}makesis -s $pkgoutput $stub_sis_name");
    271347} else {
     348    if ($certtext eq "Self Signed"
     349        && !@certificates
     350        && $templatepkg !~ m/_installer\.pkg$/i
     351        && !$onlyUnsigned) {
     352        my $patch_capabilities = File::Spec->catfile(dirname($0), "patch_capabilities");
     353        if ($dontPatchCaps) {
     354            system ("$patch_capabilities -c $pkgoutput") and print ("Warning: Package check for self-signing viability failed. Installing the package on a device will most likely fail!\n\n");
     355        } else {
     356            print("Auto-patching self-signed package.\n");
     357            system ("$patch_capabilities $pkgoutput") and die ("ERROR: Automatic patching failed");
     358        }
     359    }
     360
    272361    # Create SIS.
    273     system ("makesis $pkgoutput $unsigned_sis_name");
     362    # The 'and' is because system uses 0 to indicate success.
     363    system ("${epocToolsDir}makesis $pkgoutput $unsigned_sis_name") and die ("ERROR: makesis failed");
     364
    274365    print("\n");
    275366
     367    my $targetInsert = "";
     368    if ($targetplatform ne "-") {
     369        $targetInsert = " for $targetplatform";
     370    }
     371
     372    if ($onlyUnsigned) {
     373        stat($unsigned_sis_name);
     374        if( -e _ ) {
     375            print ("Successfully created unsigned package ${unsigned_sis_name}${targetInsert}!\n");
     376        } else {
     377            print ("\nUnsigned package creation failed!\n");
     378        }
     379
     380        if (!$preservePkgOutput) {
     381            unlink $pkgoutput;
     382        }
     383        print ("\n");
     384        exit;
     385    }
     386
    276387    # Sign SIS with certificate info given as an argument.
    277     system ("signsis $unsigned_sis_name $signed_sis_name $certificate $key $passphrase");
     388    my $relcert = File::Spec->abs2rel($certificate);
     389    my $relkey = File::Spec->abs2rel($key);
     390    # The 'and' is because system uses 0 to indicate success.
     391    system ("${epocToolsDir}signsis $unsigned_sis_name $signed_sis_name $relcert $relkey $passphrase") and die ("ERROR: signsis failed");
    278392
    279393    # Check if creating signed SIS Succeeded
    280394    stat($signed_sis_name);
    281395    if( -e _ ) {
    282         my $targetInsert = "";
    283         if ($targetplatform ne "-") {
    284             $targetInsert = "for $targetplatform ";
    285         }
    286         print ("Successfully created $signed_sis_name ${targetInsert}using certificate: $certtext!\n");
     396        print ("Successfully created signed package ${signed_sis_name}${targetInsert} using certificate: $certtext!\n");
    287397
    288398        # Sign with additional certificates & keys
    289399        for my $row ( @certificates ) {
    290400            # Get certificate absolute file names, relative paths are relative to certfilepath
    291             my $abscert = File::Spec->rel2abs( $row->[0], $certfilepath);
    292             my $abskey = File::Spec->rel2abs( $row->[1], $certfilepath);
    293 
    294             system ("signsis $signed_sis_name $signed_sis_name $abscert $abskey $row->[2]");
     401            my $relcert = File::Spec->abs2rel(File::Spec->rel2abs( $row->[0], $certfilepath));
     402            my $relkey = File::Spec->abs2rel(File::Spec->rel2abs( $row->[1], $certfilepath));
     403
     404            system ("${epocToolsDir}signsis $signed_sis_name $signed_sis_name $relcert $relkey $row->[2]");
    295405            print ("\tAdditionally signed the SIS with certificate: $row->[0]!\n");
    296406        }
     
    313423        print ("\nSIS creation failed!\n");
    314424    }
     425    print ("\n");
    315426}
    316427
  • trunk/bin/patch_capabilities.pl

    r651 r846  
    22#############################################################################
    33##
    4 ## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    55## All rights reserved.
    66## Contact: Nokia Corporation (qt-info@nokia.com)
     
    4747#######################################################################
    4848
     49#
     50# Note: Please make sure to output all changes done to the pkg file in a print statements
     51#       starting with "Patching: " to ease integration into IDEs!
     52#
     53
     54use File::Copy;
     55use File::Spec;
     56
    4957sub Usage() {
    5058    print("This script can be used to set capabilities of all binaries\n");
    5159    print("specified for deployment in a .pkg file.\n");
    5260    print("If no capabilities are given, the binaries will be given the\n");
    53     print("capabilities supported by self-signed certificates.\n");
    54     print("\n *** NOTE: If *_template.pkg file is given, 'target-platform' is REQUIRED. ***\n");
    55     print("\nUsage: patch_capabilities.pl pkg_filename <target-platform> [capability list]\n");
     61    print("capabilities supported by self-signed certificates.\n\n");
     62    print(" *** NOTE: If *_template.pkg file is given and one is using symbian-abld or\n");
     63    print(" symbian-sbsv2 platform, 'target-platform' is REQUIRED. ***\n\n");
     64    print(" *** NOTE2: When patching gcce binaries built with symbian-sbsv2 toolchain,\n");
     65    print(" armv5 must be specified as platform.\n");
     66    print("\nUsage: patch_capabilities.pl [-c] pkg_filename [target-platform [capability list]]\n");
    5667    print("\nE.g. patch_capabilities.pl myapp_template.pkg release-armv5 \"All -TCB\"\n");
     68    print("\nThe parameter -c can be used to just check if package is compatible with self-signing\n");
     69    print("without actually doing any patching.\n");
     70    print("Explicit capability list cannot be used with -c parameter.\n");
    5771    exit();
    5872}
    5973
    60 my @capabilitiesToSet = ("LocalServices", "NetworkServices", "ReadUserData", "UserEnvironment", "WriteUserData");
     74sub trim($) {
     75    my $string = shift;
     76    $string =~ s/^\s+//;
     77    $string =~ s/\s+$//;
     78    return $string;
     79}
     80
     81my $epocroot = $ENV{EPOCROOT};
     82my $epocToolsDir = "";
     83if ($epocroot ne "") {
     84    $epocroot =~ s,\\,/,g;
     85    if ($epocroot =~ m,[^/]$,) {
     86        $epocroot = $epocroot."/";
     87    }
     88    $epocToolsDir = "${epocroot}epoc32/tools/";
     89}
     90
     91my $nullDevice = "/dev/null";
     92$nullDevice = "NUL" if ($^O =~ /MSWin/);
     93
     94my @capabilitiesToAllow = ("LocalServices", "NetworkServices", "ReadUserData", "UserEnvironment", "WriteUserData", "Location");
     95my @capabilitiesSpecified = ();
    6196
    6297# If arguments were given to the script,
     
    65100    # Parse the first given script argument as a ".pkg" file name.
    66101    my $pkgFileName = shift(@ARGV);
     102    my $justCheck = "";
     103    my $msgPrefix = "Patching:";
     104
     105    if ($pkgFileName eq "-c") {
     106        $pkgFileName = shift(@ARGV);
     107        $justCheck = true;
     108        $msgPrefix = "Warning:";
     109    }
    67110
    68111    # These variables will only be set for template .pkg files.
     
    74117    {
    75118        my $targetplatform;
    76         unless ($targetplatform = shift(@ARGV))
     119        my $templateFile;
     120        my $templateContents;
     121        open($templateFile, "< $pkgFileName") or die ("Could not open $pkgFileName");
     122        $templateContents = <$templateFile>;
     123        close($templateFile);
     124        unless (($targetplatform = shift(@ARGV)) || $templateContents !~ /\$\(PLATFORM\)/)
    77125        {
    78126            Usage();
    79127        }
    80 
     128        $targetplatform = "-" if (!$targetplatform);
    81129        my @tmpvalues = split('-', $targetplatform);
    82130        $target = $tmpvalues[0];
     
    86134        $target =~ s/debug/udeb/i;
    87135        $target =~ s/release/urel/i;
     136
     137        if (($platform =~ m/^gcce$/i) && ($ENV{SBS_HOME})) {
     138            # Print a informative note in case suspected misuse is detected.
     139            print "\nNote: You must use armv5 as platform when packaging gcce binaries built using symbian-sbsv2 mkspec.\n";
     140        }
    88141    }
    89142
     
    91144    if (($pkgFileName =~ m|\.pkg$|i) && -r($pkgFileName))
    92145    {
    93         # If there are more arguments given, parse them as capabilities.
    94         if (@ARGV)
    95         {
    96             @capabilitiesToSet = ();
    97             while (@ARGV)
     146        print ("\n");
     147        if ($justCheck) {
     148            print ("Checking");
     149        } else {
     150            print ("Patching");
     151        }
     152        print (" package file and relevant binaries...\n");
     153
     154        if (!$justCheck) {
     155            # If there are more arguments given, parse them as capabilities.
     156            if (@ARGV)
    98157            {
    99                 push (@capabilitiesToSet, pop(@ARGV));
     158                @capabilitiesSpecified = ();
     159                while (@ARGV)
     160                {
     161                    push (@capabilitiesSpecified, pop(@ARGV));
     162                }
    100163            }
    101164        }
     
    105168
    106169        my $tempPkgFileName = $pkgFileName."_@@TEMP@@";
    107         unlink($tempPkgFileName);
    108         open (NEW_PKG, ">>".$tempPkgFileName);
     170
     171        if (!$justCheck) {
     172            unlink($tempPkgFileName);
     173            open (NEW_PKG, ">>".$tempPkgFileName);
     174        }
    109175        open (PKG, "<".$pkgFileName);
    110176
    111         my $manufacturerElseBlock = 0;
     177        my $checkFailed = "";
     178        my $somethingPatched = "";
    112179
    113180        # Parse each line.
    114181        while (<PKG>)
    115182        {
    116             # Patch pkg UID
    117183            my $line = $_;
    118184            my $newLine = $line;
    119             if ($line =~ m/^\#.*\(0x[0-9|a-f|A-F]*\).*$/)
     185
     186            # Patch pkg UID if it's in protected range
     187            if ($line =~ m/^\#.*\((0x[0-7][0-9a-fA-F]*)\).*$/)
    120188            {
    121                 $newLine =~ s/\(0x./\(0xE/;
    122             }
    123 
    124             # Patch embedded sis name and UID
    125             if ($line =~ m/^@.*\.sis.*\(0x[0-9|a-f|A-F]*\).*$/)
    126             {
    127                 $newLine =~ s/\(0x./\(0xE/;
    128                 if ($line !~ m/^.*_selfsigned.sis.*$/)
    129                 {
    130                     $newLine =~ s/\.sis/_selfsigned\.sis/i;
    131                 }
    132             }
    133 
    134             # Remove dependencies to known problem packages (i.e. packages that are likely to be patched, also)
    135             # to reduce unnecessary error messages.
    136             if ($line =~ m/^\(0x2002af5f\).*\{.*\}$/)
    137             {
    138                 $newLine = "\n"
    139             }
    140             if ($line =~ m/^\(0x2001E61C\).*\{.*\}$/)
    141             {
    142                 $newLine = "\n"
    143             }
    144 
    145             # Remove manufacturer ifdef
    146             if ($line =~ m/^.*\(MANUFACTURER\)\=\(.*\).*$/)
    147             {
    148                 $newLine = "\n";
    149             }
    150 
    151             if ($line =~ m/^ELSEIF.*MANUFACTURER$/)
    152             {
    153                 $manufacturerElseBlock = 1;
    154             }
    155 
    156             if ($manufacturerElseBlock eq 1)
    157             {
    158                 $newLine = "\n";
    159             }
    160 
    161             if ($line =~ m/^ENDIF.*MANUFACTURER$/)
    162             {
    163                 $manufacturerElseBlock = 0;
    164             }
    165 
    166             print NEW_PKG $newLine;
    167 
    168             chomp ($line);
     189                my $oldUID = $1;
     190                print ("$msgPrefix UID $oldUID is not compatible with self-signing!\n");
     191
     192                if ($justCheck) {
     193                    $checkFailed = true;
     194                } else {
     195                    my $newUID = $oldUID;
     196                    $newUID =~ s/0x./0xE/i;
     197                    $newLine =~ s/$oldUID/$newUID/;
     198                    print ("$msgPrefix Package UID changed to: $newUID.\n");
     199                    $somethingPatched = true;
     200                }
     201            }
    169202
    170203            # If the line specifies a file, parse the source and destination locations.
    171             if ($line =~ m|\"([^\"]+)\"\s*\-\s*\"([^\"]+)\"|)
     204            if ($line =~ m|^ *\"([^\"]+)\"\s*\-\s*\"([^\"]+)\"|)
    172205            {
    173206                my $sourcePath = $1;
    174                 my $destinationPath = $2;
    175207
    176208                # If the given file is a binary, check the target and binary type (+ the actual filename) from its path.
    177                 if ($sourcePath =~ m:/epoc32/release/([^/]+)/(udeb|urel|\$\(TARGET\))/(\w+(\.dll|\.exe)):i)
     209                if ($sourcePath =~ m:\w+(\.dll|\.exe)$:i)
    178210                {
    179211                    # Do preprocessing for template pkg,
     
    185217                    }
    186218
    187                     push (@binaries, $sourcePath);
    188                 }
    189             }
     219                    if ($justCheck) {
     220                        push (@binaries, $sourcePath);
     221                    } else {
     222                        # Change the source file name (but only if not already patched)
     223                        my $patchedSourcePath = $sourcePath;
     224                        if ($patchedSourcePath !~ m/_patched_caps/)
     225                        {
     226                            $newLine =~ s/(^.*)(\.dll|\.exe)(.*)(\.dll|\.exe)/$1_patched_caps$2$3$4/i;
     227                            $patchedSourcePath =~ s/(^.*)(\.dll|\.exe)/$1_patched_caps$2/i;
     228
     229                            copy($sourcePath, $patchedSourcePath) or die "$sourcePath cannot be copied for patching.";
     230                        }
     231                        push (@binaries, $patchedSourcePath);
     232                    }
     233                }
     234            }
     235
     236            print NEW_PKG $newLine;
     237
     238            chomp ($line);
    190239        }
    191240
    192241        close (PKG);
    193         close (NEW_PKG);
    194 
    195         unlink($pkgFileName);
    196         rename($tempPkgFileName, $pkgFileName);
    197 
     242        if (!$justCheck) {
     243            close (NEW_PKG);
     244
     245            unlink($pkgFileName);
     246            rename($tempPkgFileName, $pkgFileName);
     247        }
    198248        print ("\n");
    199249
    200         my $baseCommandToExecute = "elftran -vid 0x0 -capability \"";
    201         if (@capabilitiesToSet)
    202         {
    203             $baseCommandToExecute .= join(" ", @capabilitiesToSet);
    204         }
    205         $baseCommandToExecute .= "\" ";
     250        my $baseCommandToExecute = "${epocToolsDir}elftran -vid 0x0 -capability \"%s\" ";
    206251
    207252        # Actually set the capabilities of the listed binaries.
     
    209254        {
    210255            # Create the command line for setting the capabilities.
     256            my ($binaryVolume, $binaryDirs, $binaryBaseName) = File::Spec->splitpath($binaryPath);
    211257            my $commandToExecute = $baseCommandToExecute;
     258            my $executeNeeded = "";
     259            if (@capabilitiesSpecified)
     260            {
     261                $commandToExecute = sprintf($baseCommandToExecute, join(" ", @capabilitiesSpecified));
     262                $executeNeeded = true;
     263                my $capString = join(" ", @capabilitiesSpecified);
     264                print ("$msgPrefix Patching the the Vendor ID to 0 and the capabilities used to: \"$capString\" in \"$binaryBaseName\".\n");
     265            } else {
     266                # Test which capabilities are present and then restrict them to the allowed set.
     267                # This avoid raising the capabilities of apps that already have none.
     268                my $dllCaps;
     269                open($dllCaps, "${epocToolsDir}elftran -dump s $binaryPath |") or die ("ERROR: Could not execute elftran");
     270                my $capsFound = 0;
     271                my $originalVid;
     272                my @capabilitiesToSet;
     273                my $capabilitiesToAllow = join(" ", @capabilitiesToAllow);
     274                my @capabilitiesToDrop;
     275                while (<$dllCaps>) {
     276                    if (/^Secure ID: ([0-7][0-9a-fA-F]*)$/) {
     277                        my $exeSid = $1;
     278                        if ($binaryBaseName =~ /\.exe$/) {
     279                            # Installer refuses to install protected executables in a self signed package, so abort if one is detected.
     280                            # We can't simply just patch the executable SID, as any registration resources executable uses will be linked to it via SID.
     281                            print ("$msgPrefix Executable with SID in the protected range (0x$exeSid) detected: \"$binaryBaseName\". A self-signed sis with protected executables is not supported.\n\n");
     282                            $checkFailed = true;
     283                        }
     284                    }
     285                    if (/^Vendor ID: ([0-9a-fA-F]*)$/) {
     286                        $originalVid = "$1";
     287                    }
     288                    if (!$capsFound) {
     289                        $capsFound = 1 if (/Capabilities:/);
     290                    } else {
     291                        $_ = trim($_);
     292                        if ($capabilitiesToAllow =~ /$_/) {
     293                            push(@capabilitiesToSet, $_);
     294                            if (Location =~ /$_/i) {
     295                                print ("$msgPrefix \"Location\" capability detected for binary: \"$binaryBaseName\". This capability is not self-signable for S60 3rd edition feature pack 1 devices, so installing this package on those devices will most likely not work.\n\n");
     296                            }
     297                        } else {
     298                            push(@capabilitiesToDrop, $_);
     299                        }
     300                    }
     301                }
     302                close($dllCaps);
     303                if ($originalVid !~ "00000000") {
     304                    print ("$msgPrefix Non-zero vendor ID (0x$originalVid) is incompatible with self-signed packages in \"$binaryBaseName\"");
     305                    if ($justCheck) {
     306                        print (".\n\n");
     307                        $checkFailed = true;
     308                    } else {
     309                        print (", setting it to zero.\n\n");
     310                        $executeNeeded = true;
     311                    }
     312                }
     313                if ($#capabilitiesToDrop) {
     314                    my $capsToDropStr = join("\", \"", @capabilitiesToDrop);
     315                    $capsToDropStr =~ s/\", \"$//;
     316
     317                    if ($justCheck) {
     318                        print ("$msgPrefix The following capabilities used in \"$binaryBaseName\" are not compatible with a self-signed package: \"$capsToDropStr\".\n\n");
     319                        $checkFailed = true;
     320                    } else {
     321                        if ($binaryBaseName =~ /\.exe$/) {
     322                            # While libraries often have capabilities they do not themselves need just to enable them to be loaded by wider variety of processes,
     323                            # executables are more likely to need every capability they have been assigned or they won't function correctly.
     324                            print ("$msgPrefix Executable with capabilities incompatible with self-signing detected: \"$binaryBaseName\". (Incompatible capabilities: \"$capsToDropStr\".) Reducing capabilities is only supported for libraries.\n");
     325                            $checkFailed = true;
     326                        } else {
     327                            print ("$msgPrefix The following capabilities used in \"$binaryBaseName\" are not compatible with a self-signed package and will be removed: \"$capsToDropStr\".\n");
     328                            $executeNeeded = true;
     329                        }
     330                    }
     331                }
     332                $commandToExecute = sprintf($baseCommandToExecute, join(" ", @capabilitiesToSet));
     333            }
    212334            $commandToExecute .= $binaryPath;
    213335
    214             # Actually execute the elftran command to set the capabilities.
    215             system ($commandToExecute." > NUL");
    216             print ("Executed ".$commandToExecute."\n");
    217 
    218             ## Create another command line to check that the set capabilities are correct.
    219             #$commandToExecute = "elftran -dump s ".$binaryPath;
    220         }
    221 
     336            if ($executeNeeded) {
     337                # Actually execute the elftran command to set the capabilities.
     338                print ("\n");
     339                system ("$commandToExecute > $nullDevice");
     340                $somethingPatched = true;
     341            }
     342        }
     343
     344        if ($checkFailed) {
     345            print ("\n");
     346            if ($justCheck) {
     347                print ("$msgPrefix The package is not compatible with self-signing.\n");
     348            } else {
     349                print ("$msgPrefix Unable to patch the package for self-singing.\n");
     350            }
     351            print ("Use a proper developer certificate for signing this package.\n\n");
     352            exit(1);
     353        }
     354
     355        if ($justCheck) {
     356            print ("Package is compatible with self-signing.\n");
     357        } else {
     358            if ($somethingPatched) {
     359                print ("NOTE: A patched package may not work as expected due to reduced capabilities and other modifications,\n");
     360                print ("      so it should not be used for any kind of Symbian signing or distribution!\n");
     361                print ("      Use a proper certificate to avoid the need to patch the package.\n");
     362            } else {
     363                print ("No patching was required!\n");
     364            }
     365        }
    222366        print ("\n");
     367    } else {
     368        Usage();
    223369    }
    224370}
  • trunk/bin/setcepaths.bat

    r651 r846  
    11:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    22::
    3 :: Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3:: Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44:: All rights reserved.
    55:: Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/bin/syncqt

    r769 r846  
    44# Synchronizes Qt header files - internal development tool.
    55#
    6 # Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     6# Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    77# Contact: Nokia Corporation (qt-info@nokia.com)
    88#
     
    4343        "QtScriptTools" => "$basedir/src/scripttools",
    4444        "Qt3Support" => "$basedir/src/qt3support",
    45         "ActiveQt" => "$basedir/src/activeqt/container;$basedir/src/activeqt/control;$basedir/src/activeqt/shared",
     45        "ActiveQt" => "$basedir/src/activeqt",
    4646        "QtTest" => "$basedir/src/testlib",
    47         "QtAssistant" => "$basedir/tools/assistant/compat/lib",
    4847        "QtHelp" => "$basedir/tools/assistant/lib",
    4948        "QtDesigner" => "$basedir/tools/designer/src/lib",
     
    5352        "phonon" => "$basedir/src/phonon",
    5453        "QtMultimedia" => "$basedir/src/multimedia",
     54        "QtMeeGoGraphicsSystemHelper" => "$basedir/tools/qmeegographicssystemhelper",
    5555);
    5656my %moduleheaders = ( # restrict the module headers to those found in relative path
     
    6464my $module = 0;
    6565my $showonly = 0;
     66my $quiet = 0;
    6667my $remove_stale = 1;
    6768my $force_win = 0;
     
    9495    print "  -showonly             Show action but not perform        (default: " . ($showonly ? "yes" : "no") . ")\n";
    9596    print "  -outdir <PATH>        Specify output directory for sync  (default: $out_basedir)\n";
     97    print "  -quiet                Only report problems, not activity (default: " . ($quiet ? "yes" : "no") . ")\n";
    9698    print "  -separate-module <NAME>:<PROFILEDIR>:<HEADERDIR> Create headers for <NAME> with original headers in <HEADERDIR> relative to <PROFILEDIR> \n";
    9799    print "  -help                 This help\n";
     
    146148    if(open(F, "<$iheader")) {
    147149        while(<F>) {
    148             chomp;
    149             return 0 if(/^\#pragma qt_no_master_include$/);
    150         }
    151         close(F);
     150            chomp;
     151            return 0 if(/^\#pragma qt_no_master_include$/);
     152        }
     153        close(F);
    152154    } else {
    153         return 0;
     155        return 0;
    154156    }
    155157    return 1;
     
    168170    my ($iheader) = @_;
    169171    if(basename($iheader) eq "qglobal.h") {
    170         push @ret, "QtGlobal";
     172        push @ret, "QtGlobal";
    171173    } elsif(basename($iheader) eq "qendian.h") {
    172         push @ret, "QtEndian";
     174        push @ret, "QtEndian";
    173175    } elsif(basename($iheader) eq "qconfig.h") {
    174176        push @ret, "QtConfig";
    175177    } elsif(basename($iheader) eq "qplugin.h") {
    176         push @ret, "QtPlugin";
     178        push @ret, "QtPlugin";
    177179    } elsif(basename($iheader) eq "qalgorithms.h") {
    178         push @ret, "QtAlgorithms";
     180        push @ret, "QtAlgorithms";
    179181    } elsif(basename($iheader) eq "qcontainerfwd.h") {
    180         push @ret, "QtContainerFwd";
     182        push @ret, "QtContainerFwd";
    181183    } elsif(basename($iheader) eq "qdebug.h") {
    182184        push @ret, "QtDebug";
     
    186188        push @ret, "Qt"
    187189    } elsif(basename($iheader) eq "qssl.h") {
    188         push @ret, "QSsl";
     190        push @ret, "QSsl";
    189191    } elsif(basename($iheader) eq "qtest.h") {
    190192        push @ret, "QTest"
     
    204206            my $line = $_;
    205207            chomp $line;
    206                         chop $line if ($line =~ /\r$/);
     208                        chop $line if ($line =~ /\r$/);
    207209            if($line =~ /^\#/) {
    208210                if($line =~ /\\$/) {
     
    212214                    }
    213215                }
    214                 return @ret if($line =~ m/^#pragma qt_sync_stop_processing/);
    215                 push(@ret, "$1") if($line =~ m/^#pragma qt_class\(([^)]*)\)[\r\n]*$/);
    216                 $line = 0;
    217             }
    218             if($line) {
     216                return @ret if($line =~ m/^#pragma qt_sync_stop_processing/);
     217                push(@ret, $1) if($line =~ m/^#pragma qt_class\(([^)]*)\)[\r\n]*$/);
     218                $line = 0;
     219            }
     220            if($line) {
    219221                $line =~ s,//.*$,,; #remove c++ comments
    220                 $line .= ";" if($line =~ m/^Q_[A-Z_]*\(.*\)[\r\n]*$/); #qt macro
    221                 $line .= ";" if($line =~ m/^QT_(BEGIN|END)_HEADER[\r\n]*$/); #qt macro
    222                 $line .= ";" if($line =~ m/^QT_(BEGIN|END)_NAMESPACE[\r\n]*$/); #qt macro
    223                 $line .= ";" if($line =~ m/^QT_MODULE\(.*\)[\r\n]*$/); # QT_MODULE macro
     222                $line .= ";" if($line =~ m/^Q_[A-Z_]*\(.*\)[\r\n]*$/); #qt macro
     223                $line .= ";" if($line =~ m/^QT_(BEGIN|END)_HEADER[\r\n]*$/); #qt macro
     224                $line .= ";" if($line =~ m/^QT_(BEGIN|END)_NAMESPACE[\r\n]*$/); #qt macro
     225                $line .= ";" if($line =~ m/^QT_MODULE\(.*\)[\r\n]*$/); # QT_MODULE macro
    224226                $parsable .= " " . $line;
    225             }
     227            }
    226228        }
    227229        close(F);
     
    259261                              $last_definition = $i + 1;
    260262                              last BLOCK;
    261                           }
     263                          }
    262264                      }
    263265                  }
     
    267269            $definition = substr($parsable, $last_definition, $i - $last_definition + 1);
    268270            $last_definition = $i + 1;
    269         } elsif($character eq "}") {
    270             # a naked } must be a namespace ending
    271             # if it's not a namespace, it's eaten by the loop above
    272             pop @namespaces;
    273             $last_definition = $i + 1;
    274         }
    275 
    276         if (substr($parsable, $last_definition, $i - $last_definition + 1) =~ m/ namespace ([^ ]*) /
    277             && substr($parsable, $i+1, 1) eq "{") {
    278             push @namespaces, $1;
    279 
    280             # Eat the opening { so that the condensing loop above doesn't see it
    281             $i++;
    282             $last_definition = $i + 1;
    283         }
     271        } elsif($character eq "}") {
     272            # a naked } must be a namespace ending
     273            # if it's not a namespace, it's eaten by the loop above
     274            pop @namespaces;
     275            $last_definition = $i + 1;
     276        }
     277
     278        if (substr($parsable, $last_definition, $i - $last_definition + 1) =~ m/ namespace ([^ ]*) /
     279            && substr($parsable, $i+1, 1) eq "{") {
     280            push @namespaces, $1;
     281
     282            # Eat the opening { so that the condensing loop above doesn't see it
     283            $i++;
     284            $last_definition = $i + 1;
     285        }
    284286
    285287        if($definition) {
    286             $definition =~ s=[\n\r]==g;
     288            $definition =~ s=[\n\r]==g;
    287289            my @symbols;
    288290            if($definition =~ m/^ *typedef *.*\(\*([^\)]*)\)\(.*\);$/) {
    289                 push @symbols, $1;
     291                push @symbols, $1;
    290292            } elsif($definition =~ m/^ *typedef +(.*) +([^ ]*);$/) {
    291                 push @symbols, $2;
     293                push @symbols, $2;
    292294            } elsif($definition =~ m/^ *(template *<.*> *)?(class|struct) +([^ ]* +)?([^<\s]+) ?(<[^>]*> ?)?\s*((,|:)\s*(public|protected|private) *.*)? *\{\}$/) {
    293                 push @symbols, $4;
     295                push @symbols, $4;
    294296            } elsif($definition =~ m/^ *Q_DECLARE_.*ITERATOR\((.*)\);$/) {
    295                 push @symbols, "Q" . $1 . "Iterator";
    296                 push @symbols, "QMutable" . $1 . "Iterator";
    297             }
    298 
    299             foreach (@symbols) {
    300                 my $symbol = $_;
    301                 $symbol = (join("::", @namespaces) . "::" . $symbol) if (scalar @namespaces);
    302                 push @ret, $symbol
    303                     if ($symbol =~ /^Q[^:]*$/           # no-namespace, starting with Q
    304                         || $symbol =~ /^Phonon::/);     # or in the Phonon namespace
     297                push @symbols, "Q" . $1 . "Iterator";
     298                push @symbols, "QMutable" . $1 . "Iterator";
     299            }
     300
     301            foreach my $symbol (@symbols) {
     302                $symbol = (join("::", @namespaces) . "::" . $symbol) if (scalar @namespaces);
     303                push @ret, $symbol
     304                    if ($symbol =~ /^Q[^:]*$/           # no-namespace, starting with Q
     305                        || $symbol =~ /^Phonon::/);     # or in the Phonon namespace
    305306            }
    306307        }
     
    310311
    311312######################################################################
    312 # Syntax:  syncHeader(header, iheader, copy)
     313# Syntax:  syncHeader(header, iheader, copy, timestamp)
    313314# Params:  header, string, filename to create "symlink" for
    314315#          iheader, string, destination name of symlink
    315316#          copy, forces header to be a copy of iheader
     317#          timestamp, the requested modification time if copying
    316318#
    317319# Purpose: Syncronizes header to iheader
     
    319321######################################################################
    320322sub syncHeader {
    321     my ($header, $iheader, $copy) = @_;
     323    my ($header, $iheader, $copy, $ts) = @_;
    322324    $iheader =~ s=\\=/=g;
    323325    $header =~ s=\\=/=g;
    324326    return copyFile($iheader, $header) if($copy);
    325327
    326     unless(-e "$header") {
     328    unless(-e $header) {
    327329        my $header_dir = dirname($header);
    328         mkpath $header_dir, 0777;
     330        mkpath $header_dir, !$quiet;
    329331
    330332        #write it
     
    333335        print HEADER "#include \"$iheader_out\"\n";
    334336        close HEADER;
     337        utime(time, $ts, $header) or die "$iheader, $header";
    335338        return 1;
    336339    }
     
    356359    #setup
    357360    my $ret = $file;
     361    $ret =~ s,/cygdrive/([a-zA-Z])/,$1:/,g;
    358362    my $file_dir = dirname($file);
    359363    if($file_dir eq ".") {
     
    361365        $file_dir =~ s=\\=/=g;
    362366    }
    363     $file_dir =~ s,/cygdrive/([a-zA-Z])/,$1:,g;
     367    $file_dir =~ s,/cygdrive/([a-zA-Z])/,$1:/,g;
    364368    if($dir eq ".") {
    365369        $dir = getcwd();
     
    367371    }
    368372    $dir =~ s,/cygdrive/([a-zA-Z])/,$1:/,g;
    369     return basename($file) if("$file_dir" eq "$dir");
     373    return basename($file) if($file_dir eq $dir);
    370374
    371375    #guts
     
    429433    if (! -e $file1) { return 1; }
    430434    if (! -e $file2) { return -1; }
    431     return $file1contents ne $file2contents ? (stat("$file2"))[9] <=> (stat("$file1"))[9] : 0;
     435    return $file1contents ne $file2contents ? (stat($file2))[9] <=> (stat($file1))[9] : 0;
    432436}
    433437
     
    452456    close I;
    453457    if ( open(I, "< " . $ifile) ) {
    454         local $/;
    455         binmode I;
    456         $ifilecontents = <I>;
    457         close I;
    458         $copy = fileCompare($file, $ifile);
    459         $knowdiff = 0,
     458        local $/;
     459        binmode I;
     460        $ifilecontents = <I>;
     461        close I;
     462        $copy = fileCompare($file, $ifile);
     463        $knowdiff = 0,
    460464    } else {
    461         $copy = -1;
    462         $knowdiff = 1;
     465        $copy = -1;
     466        $knowdiff = 1;
    463467    }
    464468
    465469    if ( $knowdiff || ($filecontents ne $ifilecontents) ) {
    466         if ( $copy > 0 ) {
    467             my $file_dir = dirname($file);
    468             mkpath $file_dir, 0777 unless(-e "$file_dir");
    469             open(O, "> " . $file) || die "Could not open $file for writing (no write permission?)";
    470             local $/;
    471             binmode O;
    472             print O $ifilecontents;
    473             close O;
    474             return 1;
    475         } elsif ( $copy < 0 ) {
    476             my $ifile_dir = dirname($ifile);
    477             mkpath $ifile_dir, 0777 unless(-e "$ifile_dir");
    478             open(O, "> " . $ifile) || die "Could not open $ifile for writing (no write permission?)";
    479             local $/;
    480             binmode O;
    481             print O $filecontents;
    482             close O;
    483             return 1;
    484         }
     470        if ( $copy > 0 ) {
     471            my $file_dir = dirname($file);
     472            mkpath $file_dir, !$quiet unless(-e $file_dir);
     473            open(O, "> " . $file) || die "Could not open $file for writing (no write permission?)";
     474            local $/;
     475            binmode O;
     476            print O $ifilecontents;
     477            close O;
     478            utime time, (stat($ifile))[9], $file;
     479            return 1;
     480        } elsif ( $copy < 0 ) {
     481            my $ifile_dir = dirname($ifile);
     482            mkpath $ifile_dir, !$quiet unless(-e $ifile_dir);
     483            open(O, "> " . $ifile) || die "Could not open $ifile for writing (no write permission?)";
     484            local $/;
     485            binmode O;
     486            print O $filecontents;
     487            close O;
     488            utime time, (stat($file))[9], $ifile;
     489            return 1;
     490        }
    485491    }
    486492    return 0;
     
    501507
    502508    if ($isunix) {
    503         print "symlink created for $file ";
     509        print "symlink created for $file " unless $quiet;
    504510        if ( $force_relative && ($ifile =~ /^$basedir/)) {
    505511            my $t = getcwd();
     
    509515            $p .= "../" while( ($c = index( $t, "/", $c + 1)) != -1 );
    510516            $file =~ s-^$basedir/-$p-;
    511             print " ($file)\n";
    512         }
    513         print "\n";
     517            print " ($file)\n" unless $quiet;
     518        }
     519        print "\n" unless $quiet;
    514520        return symlink($file, $ifile);
    515521    }
     
    566572    #parse
    567573    my $arg = shift @ARGV;
    568     if ("$arg" eq "-h" || "$arg" eq "-help" || "$arg" eq "?") {
    569         $var = "show_help";
    570         $val = "yes";
    571     } elsif("$arg" eq "-copy") {
    572         $var = "copy";
    573         $val = "yes";
    574     } elsif("$arg" eq "-o" || "$arg" eq "-outdir") {
    575         $var = "output";
    576         $val = shift @ARGV;
    577     } elsif("$arg" eq "-showonly" || "$arg" eq "-remove-stale" || "$arg" eq "-windows" ||
    578             "$arg" eq "-relative" || "$arg" eq "-check-includes") {
    579         $var = substr($arg, 1);
    580         $val = "yes";
    581     } elsif("$arg" =~ /^-no-(.*)$/) {
    582         $var = $1;
    583         $val = "no";
    584         #these are for commandline compat
    585     } elsif("$arg" eq "-inc") {
    586         $var = "output";
    587         $val = shift @ARGV;
    588     } elsif("$arg" eq "-module") {
    589         $var = "module";
    590         $val = shift @ARGV;
    591     } elsif("$arg" eq "-separate-module") {
    592         $var = "separate-module";
    593         $val = shift @ARGV;
    594     } elsif("$arg" eq "-show") {
    595         $var = "showonly";
    596         $val = "yes";
    597     } elsif("$arg" eq "-base-dir") {
     574    if ($arg eq "-h" || $arg eq "-help" || $arg eq "?") {
     575        $var = "show_help";
     576        $val = "yes";
     577    } elsif($arg eq "-copy") {
     578        $var = "copy";
     579        $val = "yes";
     580    } elsif($arg eq "-o" || $arg eq "-outdir") {
     581        $var = "output";
     582        $val = shift @ARGV;
     583    } elsif($arg eq "-showonly" || $arg eq "-remove-stale" || $arg eq "-windows" ||
     584            $arg eq "-relative" || $arg eq "-check-includes") {
     585        $var = substr($arg, 1);
     586        $val = "yes";
     587    } elsif($arg =~ /^-no-(.*)$/) {
     588        $var = $1;
     589        $val = "no";
     590        #these are for commandline compat
     591    } elsif($arg eq "-inc") {
     592        $var = "output";
     593        $val = shift @ARGV;
     594    } elsif($arg eq "-module") {
     595        $var = "module";
     596        $val = shift @ARGV;
     597    } elsif($arg eq "-separate-module") {
     598        $var = "separate-module";
     599        $val = shift @ARGV;
     600    } elsif($arg eq "-show") {
     601        $var = "showonly";
     602        $val = "yes";
     603    } elsif($arg eq "-quiet") {
     604        $var = "quiet";
     605        $val = "yes";
     606    } elsif($arg eq "-base-dir") {
    598607        # skip, it's been dealt with at the top of the file
    599608        shift @ARGV;
    600609        next;
    601     } elsif("$arg" eq '*') {
    602         # workaround for windows 9x where "%*" expands to "*"
    603         $var = 1;
    604610    }
    605611
    606612    #do something
    607     if(!$var || "$var" eq "show_help") {
    608         print "Unknown option: $arg\n\n" if(!$var);
    609         showUsage();
    610     } elsif ("$var" eq "copy") {
    611         if("$val" eq "yes") {
    612             $copy_headers++;
    613         } elsif($showonly) {
    614             $copy_headers--;
    615         }
    616     } elsif ("$var" eq "showonly") {
    617         if("$val" eq "yes") {
    618             $showonly++;
    619         } elsif($showonly) {
    620             $showonly--;
    621         }
    622     } elsif ("$var" eq "check-includes") {
    623         if("$val" eq "yes") {
    624             $check_includes++;
    625         } elsif($check_includes) {
    626             $check_includes--;
    627         }
    628     } elsif ("$var" eq "remove-stale") {
    629         if("$val" eq "yes") {
    630             $remove_stale++;
    631         } elsif($remove_stale) {
    632             $remove_stale--;
    633         }
    634     } elsif ("$var" eq "windows") {
    635         if("$val" eq "yes") {
    636             $force_win++;
    637         } elsif($force_win) {
    638             $force_win--;
    639         }
    640     } elsif ("$var" eq "relative") {
    641         if("$val" eq "yes") {
    642             $force_relative++;
    643         } elsif($force_relative) {
    644             $force_relative--;
    645         }
    646     } elsif ("$var" eq "module") {
    647         print "module :$val:\n";
    648         die "No such module: $val" unless(defined $modules{$val});
    649         push @modules_to_sync, $val;
    650     } elsif ("$var" eq "separate-module") {
     613    if(!$var || $var eq "show_help") {
     614        print "Unknown option: $arg\n\n" if(!$var);
     615        showUsage();
     616    } elsif ($var eq "copy") {
     617        if($val eq "yes") {
     618            $copy_headers++;
     619        } elsif($showonly) {
     620            $copy_headers--;
     621        }
     622    } elsif ($var eq "showonly") {
     623        if($val eq "yes") {
     624            $showonly++;
     625        } elsif($showonly) {
     626            $showonly--;
     627        }
     628    } elsif ($var eq "quiet") {
     629        if($val eq "yes") {
     630            $quiet++;
     631        } elsif($quiet) {
     632            $quiet--;
     633        }
     634    } elsif ($var eq "check-includes") {
     635        if($val eq "yes") {
     636            $check_includes++;
     637        } elsif($check_includes) {
     638            $check_includes--;
     639        }
     640    } elsif ($var eq "remove-stale") {
     641        if($val eq "yes") {
     642            $remove_stale++;
     643        } elsif($remove_stale) {
     644            $remove_stale--;
     645        }
     646    } elsif ($var eq "windows") {
     647        if($val eq "yes") {
     648            $force_win++;
     649        } elsif($force_win) {
     650            $force_win--;
     651        }
     652    } elsif ($var eq "relative") {
     653        if($val eq "yes") {
     654            $force_relative++;
     655        } elsif($force_relative) {
     656            $force_relative--;
     657        }
     658    } elsif ($var eq "module") {
     659        print "module :$val:\n" unless $quiet;
     660        die "No such module: $val" unless(defined $modules{$val});
     661        push @modules_to_sync, $val;
     662    } elsif ($var eq "separate-module") {
    651663        my ($module, $prodir, $headerdir) = split(/:/, $val);
    652664        $modules{$module} = $prodir;
     
    655667        $create_uic_class_map = 0;
    656668        $create_private_headers = 0;
    657     } elsif ("$var" eq "output") {
    658         my $outdir = $val;
    659         if(checkRelative($outdir)) {
    660             $out_basedir = getcwd();
    661             chomp $out_basedir;
    662             $out_basedir .= "/" . $outdir;
    663         } else {
    664             $out_basedir = $outdir;
    665         }
    666         # \ -> /
    667         $out_basedir =~ s=\\=/=g;
     669    } elsif ($var eq "output") {
     670        my $outdir = $val;
     671        if(checkRelative($outdir)) {
     672            $out_basedir = getcwd();
     673            chomp $out_basedir;
     674            $out_basedir .= "/" . $outdir;
     675        } else {
     676            $out_basedir = $outdir;
     677        }
     678        # \ -> /
     679        $out_basedir =~ s=\\=/=g;
    668680    }
    669681}
     
    673685
    674686# create path
    675 mkpath "$out_basedir/include", 0777;
     687mkpath "$out_basedir/include", !$quiet;
     688mkpath "$out_basedir/include/Qt", !$quiet;
    676689
    677690my @ignore_headers = ();
     
    681694my @ignore_for_qt_begin_header_check = ( "qiconset.h", "qconfig.h", "qconfig-dist.h", "qconfig-large.h", "qconfig-medium.h", "qconfig-minimal.h", "qconfig-small.h", "qfeatures.h", "qt_windows.h" );
    682695my @ignore_for_qt_begin_namespace_check = ( "qconfig.h", "qconfig-dist.h", "qconfig-large.h", "qconfig-medium.h", "qconfig-minimal.h", "qconfig-small.h", "qfeatures.h", "qatomic_arch.h", "qatomic_windowsce.h", "qt_windows.h", "qatomic_macosx.h" );
    683 my @ignore_for_qt_module_check = ( "$modules{QtCore}/arch", "$modules{QtCore}/global", "$modules{QtSql}/drivers", "$modules{QtTest}", "$modules{QtAssistant}", "$modules{QtDesigner}", "$modules{QtUiTools}", "$modules{QtDBus}", "$modules{phonon}" );
    684 
    685 foreach (@modules_to_sync) {
     696my @ignore_for_qt_module_check = ( "$modules{QtCore}/arch", "$modules{QtCore}/global", "$modules{QtSql}/drivers", "$modules{QtTest}", "$modules{QtDesigner}", "$modules{QtUiTools}", "$modules{QtDBus}", "$modules{phonon}" );
     697my %colliding_headers = ();
     698my %inject_headers = ( "$basedir/src/corelib/global" => ( "qconfig.h" ) ); # all from build dir
     699
     700foreach my $lib (@modules_to_sync) {
    686701    #iteration info
    687     my $lib = $_;
    688     my $dir = "$modules{$lib}";
     702    my $dir = $modules{$lib};
    689703    my $pathtoheaders = "";
    690     $pathtoheaders = "$moduleheaders{$lib}" if ($moduleheaders{$lib});
     704    $pathtoheaders = $moduleheaders{$lib} if ($moduleheaders{$lib});
    691705
    692706    #information used after the syncing
     
    701715    #get dependencies
    702716    if(-e "$dir/" . basename($dir) . ".pro") {
    703         if(open(F, "<$dir/" . basename($dir) . ".pro")) {
    704             while(<F>) {
    705                 my $line = $_;
    706                 chomp $line;
    707                 if($line =~ /^ *QT *\+?= *([^\r\n]*)/) {
    708                     foreach(split(/ /, "$1")) {
    709                         $master_contents .= "#include <QtCore/QtCore>\n" if("$_" eq "core");
    710                         $master_contents .= "#include <QtGui/QtGui>\n" if("$_" eq "gui");
    711                         $master_contents .= "#include <QtNetwork/QtNetwork>\n" if("$_" eq "network");
    712                         $master_contents .= "#include <QtSvg/QtSvg>\n" if("$_" eq "svg");
    713                         $master_contents .= "#include <QtDeclarative/QtDeclarative>\n" if("$_" eq "declarative");
    714                         $master_contents .= "#include <QtScript/QtScript>\n" if("$_" eq "script");
    715                         $master_contents .= "#include <QtScriptTools/QtScriptTools>\n" if("$_" eq "scripttools");
    716                         $master_contents .= "#include <Qt3Support/Qt3Support>\n" if("$_" eq "qt3support");
    717                         $master_contents .= "#include <QtSql/QtSql>\n" if("$_" eq "sql");
    718                         $master_contents .= "#include <QtXml/QtXml>\n" if("$_" eq "xml");
    719                         $master_contents .= "#include <QtXmlPatterns/QtXmlPatterns>\n" if("$_" eq "xmlpatterns");
    720                         $master_contents .= "#include <QtOpenGL/QtOpenGL>\n" if("$_" eq "opengl");
    721                         $master_contents .= "#include <QtOpenVG/QtOpenVG>\n" if("$_" eq "openvg");
    722                     }
    723                 }
    724             }
    725             close(F);
    726         }
     717        if(open(F, "<$dir/" . basename($dir) . ".pro")) {
     718            while(my $line = <F>) {
     719                chomp $line;
     720                if($line =~ /^ *QT *\+?= *([^\r\n]*)/) {
     721                    foreach(split(/ /, $1)) {
     722                        $master_contents .= "#include <QtCore/QtCore>\n" if($_ eq "core");
     723                        $master_contents .= "#include <QtGui/QtGui>\n" if($_ eq "gui");
     724                        $master_contents .= "#include <QtNetwork/QtNetwork>\n" if($_ eq "network");
     725                        $master_contents .= "#include <QtSvg/QtSvg>\n" if($_ eq "svg");
     726                        $master_contents .= "#include <QtDeclarative/QtDeclarative>\n" if($_ eq "declarative");
     727                        $master_contents .= "#include <QtScript/QtScript>\n" if($_ eq "script");
     728                        $master_contents .= "#include <QtScriptTools/QtScriptTools>\n" if($_ eq "scripttools");
     729                        $master_contents .= "#include <Qt3Support/Qt3Support>\n" if($_ eq "qt3support");
     730                        $master_contents .= "#include <QtSql/QtSql>\n" if($_ eq "sql");
     731                        $master_contents .= "#include <QtXml/QtXml>\n" if($_ eq "xml");
     732                        $master_contents .= "#include <QtXmlPatterns/QtXmlPatterns>\n" if($_ eq "xmlpatterns");
     733                        $master_contents .= "#include <QtOpenGL/QtOpenGL>\n" if($_ eq "opengl");
     734                        $master_contents .= "#include <QtOpenVG/QtOpenVG>\n" if($_ eq "openvg");
     735                    }
     736                }
     737            }
     738            close(F);
     739        }
    727740    }
    728741
    729742    #remove the old files
    730743    if($remove_stale) {
    731         my @subdirs = ("$out_basedir/include/$lib");
    732         foreach (@subdirs) {
    733             my $subdir = "$_";
    734             if (opendir DIR, "$subdir") {
    735                 while(my $t = readdir(DIR)) {
    736                     my $file = "$subdir/$t";
    737                     if(-d "$file") {
    738                         push @subdirs, "$file" unless($t eq "." || $t eq "..");
    739                     } else {
    740                         my @files = ("$file");
    741                         #push @files, "$out_basedir/include/Qt/$t" if(-e "$out_basedir/include/Qt/$t");
    742                         foreach (@files) {
    743                            my $file = $_;
    744                            my $remove_file = 0;
    745                            if(open(F, "<$file")) {
    746                                 while(<F>) {
    747                                     my $line = $_;
    748                                     chomp $line;
    749                                     if($line =~ /^\#include \"([^\"]*)\"$/) {
    750                                         my $include = $1;
    751                                         $include = $subdir . "/" . $include unless(substr($include, 0, 1) eq "/");
    752                                         $remove_file = 1 unless(-e "$include");
    753                                     } else {
    754                                         $remove_file = 0;
    755                                         last;
    756                                     }
    757                                 }
    758                                 close(F);
    759                                 unlink "$file" if($remove_file);
    760                             }
    761                         }
    762                     }
    763                 }
    764                 closedir DIR;
    765             }
    766 
    767         }
     744        my @subdirs = ("$out_basedir/include/$lib");
     745        foreach my $subdir (@subdirs) {
     746            if (opendir DIR, $subdir) {
     747                while(my $t = readdir(DIR)) {
     748                    my $file = "$subdir/$t";
     749                    if(-d $file) {
     750                        push @subdirs, $file unless($t eq "." || $t eq "..");
     751                    } else {
     752                        my @files = ($file);
     753                        #push @files, "$out_basedir/include/Qt/$t" if(-e "$out_basedir/include/Qt/$t");
     754                        foreach my $file (@files) {
     755                           my $remove_file = 0;
     756                           if(open(F, "<$file")) {
     757                                while(my $line = <F>) {
     758                                    chomp $line;
     759                                    if($line =~ /^\#include \"([^\"]*)\"$/) {
     760                                        my $include = $1;
     761                                        $include = $subdir . "/" . $include unless(substr($include, 0, 1) eq "/");
     762                                        $remove_file = 1 unless(-e $include);
     763                                    } else {
     764                                        $remove_file = 0;
     765                                        last;
     766                                    }
     767                                }
     768                                close(F);
     769                                unlink $file if($remove_file);
     770                            }
     771                        }
     772                    }
     773                }
     774                closedir DIR;
     775            }
     776
     777        }
    768778    }
    769779
    770780    #create the new ones
    771     foreach (split(/;/, $dir)) {
    772         my $current_dir = "$_";
    773         my $headers_dir = $current_dir;
     781    foreach my $current_dir (split(/;/, $dir)) {
     782        my $headers_dir = $current_dir;
    774783        $headers_dir .= "/$pathtoheaders" if ($pathtoheaders);
    775784        #calc subdirs
    776785        my @subdirs = ($headers_dir);
    777         foreach (@subdirs) {
    778             my $subdir = "$_";
    779             opendir DIR, "$subdir" or next;
     786        foreach my $subdir (@subdirs) {
     787            opendir DIR, $subdir or next;
    780788            while(my $t = readdir(DIR)) {
    781789                push @subdirs, "$subdir/$t" if(-d "$subdir/$t" && !($t eq ".") &&
    782                                                !($t eq "..") && !($t eq ".obj") &&
     790                                               !($t eq "..") && !($t eq ".obj") &&
    783791                                               !($t eq ".moc") && !($t eq ".rcc") &&
    784792                                               !($t eq ".uic") && !($t eq "build"));
     
    788796
    789797        #calc files and "copy" them
    790         foreach (@subdirs) {
    791             my $subdir = "$_";
    792             my @headers = findFiles("$subdir", "^[-a-z0-9_]*\\.h\$" , 0);
    793             foreach (@headers) {
    794                 my $header = "$_";
    795                 $header = 0 if("$header" =~ /^ui_.*.h/);
     798        foreach my $subdir (@subdirs) {
     799            my @headers = findFiles($subdir, "^[-a-z0-9_]*\\.h\$" , 0);
     800            if (defined $inject_headers{$subdir}) {
     801                foreach my $if ($inject_headers{$subdir}) {
     802                    @headers = grep(!/^\Q$if\E$/, @headers); #in case we configure'd previously
     803                    push @headers, "*".$if;
     804                }
     805            }
     806            foreach my $header (@headers) {
     807                my $shadow = ($header =~ s/^\*//);
     808                $header = 0 if($header =~ /^ui_.*.h/);
    796809                foreach (@ignore_headers) {
    797                     $header = 0 if("$header" eq "$_");
     810                    $header = 0 if($header eq $_);
    798811                }
    799812                if($header) {
    800                     my $header_copies = 0;
    801                     #figure out if it is a public header
    802                     my $public_header = $header;
    803                     if($public_header =~ /_p.h$/ || $public_header =~ /_pch.h$/) {
    804                         $public_header = 0;
    805                     } else {
    806                         foreach (@ignore_for_master_contents) {
    807                             $public_header = 0 if("$header" eq "$_");
    808                         }
    809                     }
     813                    my $header_copies = 0;
     814                    #figure out if it is a public header
     815                    my $public_header = $header;
     816                    if($public_header =~ /_p.h$/ || $public_header =~ /_pch.h$/) {
     817                        $public_header = 0;
     818                    } else {
     819                        foreach (@ignore_for_master_contents) {
     820                            $public_header = 0 if($header eq $_);
     821                        }
     822                    }
    810823
    811824                    my $iheader = $subdir . "/" . $header;
    812                     my @classes = $public_header ? classNames($iheader) : ();
     825                    $iheader =~ s/^\Q$basedir\E/$out_basedir/ if ($shadow);
     826                    my @classes = $public_header ? classNames($iheader) : ();
    813827                    if($showonly) {
    814828                        print "$header [$lib]\n";
    815                         foreach(@classes) {
    816                             print "SYMBOL: $_\n";
    817                         }
     829                        foreach(@classes) {
     830                            print "SYMBOL: $_\n";
     831                        }
    818832                    } else {
    819                         #find out all the places it goes..
    820                         my @headers;
    821                         if ($public_header) {
    822                             @headers = ( "$out_basedir/include/$lib/$header" );
    823                             push @headers, "$out_basedir/include/Qt/$header"
    824                               if ("$lib" ne "phonon" && "$subdir" =~ /^$basedir\/src/);
    825 
    826                             foreach(@classes) {
    827                                 my $header_base = basename($header);
    828                                 my $class = $_;
    829                                 # Strip namespaces:
    830                                 $class =~ s/^.*:://;
    831 #                               if ($class =~ m/::/) {
    832 #                                  class =~ s,::,/,g;
    833 #                               }
    834                                 $class_lib_map_contents .= "QT_CLASS_LIB($_, $lib, $header_base)\n";
    835                                 $header_copies++ if(syncHeader("$out_basedir/include/$lib/$class", "$out_basedir/include/$lib/$header", 0));
    836 
    837                                 # KDE-Compat headers for Phonon
    838                                 if ($lib eq "phonon") {
    839                                     $header_copies++ if (syncHeader("$out_basedir/include/phonon_compat/Phonon/$class", "$out_basedir/include/$lib/$header", 0));
    840                                 }
    841                             }
    842                         } elsif ($create_private_headers) {
    843                             @headers = ( "$out_basedir/include/$lib/private/$header" );
    844                             push @headers, "$out_basedir/include/Qt/private/$header"
    845                               if ("$lib" ne "phonon");
    846                         }
    847                         foreach(@headers) { #sync them
    848                             $header_copies++ if(syncHeader($_, $iheader, $copy_headers));
    849                         }
    850 
    851                         if($public_header) {
    852                             #put it into the master file
    853                             $master_contents .= "#include \"$public_header\"\n" if(shouldMasterInclude($iheader));
    854 
    855                             #deal with the install directives
    856                             if($public_header) {
    857                                 my $pri_install_iheader = fixPaths($iheader, $current_dir);
    858                                 foreach(@classes) {
    859                                     my $class = $_;
    860                                     # Strip namespaces:
    861                                     $class =~ s/^.*:://;
    862 #                                   if ($class =~ m/::/) {
    863 #                                       $class =~ s,::,/,g;
    864 #                                   }
    865                                     my $class_header = fixPaths("$out_basedir/include/$lib/$class",
    866                                                                 $current_dir) . " ";
    867                                     $pri_install_classes .= $class_header
    868                                                                 unless($pri_install_classes =~ $class_header);
    869                                 }
    870                                 $pri_install_files.= "$pri_install_iheader ";;
    871                             }
    872                         }
    873                         else {
    874                             my $pri_install_iheader = fixPaths($iheader, $current_dir);
    875                             $pri_install_pfiles.= "$pri_install_iheader ";;
    876                         }
     833                        my $ts = (stat($iheader))[9];
     834                        #find out all the places it goes..
     835                        my @headers;
     836                        if ($public_header) {
     837                            @headers = ( "$out_basedir/include/$lib/$header" );
     838
     839                            # write forwarding headers to include/Qt
     840                            if ($lib ne "phonon" && $subdir =~ /^$basedir\/src/) {
     841                                my $file_name = "$out_basedir/include/Qt/$header";
     842                                my $file_op = '>';
     843                                my $header_content = '';
     844                                if (exists $colliding_headers{$file_name}) {
     845                                    $file_op = '>>';
     846                                } else {
     847                                    $colliding_headers{$file_name} = 1;
     848                                    my $warning_msg = 'Inclusion of header files from include/Qt is deprecated.';
     849                                    $header_content = "#ifndef QT_NO_QT_INCLUDE_WARN\n" .
     850                                                      "    #if defined(__GNUC__)\n" .
     851                                                      "        #warning \"$warning_msg\"\n" .
     852                                                      "    #elif defined(_MSC_VER)\n" .
     853                                                      "        #pragma message(\"WARNING: $warning_msg\")\n" .
     854                                                      "    #endif\n".
     855                                                      "#endif\n\n";
     856                                }
     857                                $header_content .= '#include "' . "../$lib/$header" . "\"\n";
     858                                open HEADERFILE, $file_op, $file_name or die "unable to open '$file_name' : $!\n";
     859                                print HEADERFILE $header_content;
     860                                close HEADERFILE;
     861                            }
     862
     863                            foreach my $full_class (@classes) {
     864                                my $header_base = basename($header);
     865                                # Strip namespaces:
     866                                my $class = $full_class;
     867                                $class =~ s/^.*:://;
     868#                               if ($class =~ m/::/) {
     869#                                  class =~ s,::,/,g;
     870#                               }
     871                                $class_lib_map_contents .= "QT_CLASS_LIB($full_class, $lib, $header_base)\n";
     872                                $header_copies++ if(syncHeader("$out_basedir/include/$lib/$class", "$out_basedir/include/$lib/$header", 0, $ts));
     873
     874                                # KDE-Compat headers for Phonon
     875                                if ($lib eq "phonon") {
     876                                    $header_copies++ if (syncHeader("$out_basedir/include/phonon_compat/Phonon/$class", "$out_basedir/include/$lib/$header", 0, $ts));
     877                                }
     878                            }
     879                        } elsif ($create_private_headers) {
     880                            @headers = ( "$out_basedir/include/$lib/private/$header" );
     881                        }
     882                        foreach(@headers) { #sync them
     883                            $header_copies++ if(syncHeader($_, $iheader, $copy_headers && !$shadow, $ts));
     884                        }
     885
     886                        if($public_header) {
     887                            #put it into the master file
     888                            $master_contents .= "#include \"$public_header\"\n" if(shouldMasterInclude($iheader));
     889
     890                            #deal with the install directives
     891                            if($public_header) {
     892                                my $pri_install_iheader = fixPaths($iheader, $current_dir);
     893                                foreach my $class (@classes) {
     894                                    # Strip namespaces:
     895                                    $class =~ s/^.*:://;
     896#                                   if ($class =~ m/::/) {
     897#                                       $class =~ s,::,/,g;
     898#                                   }
     899                                    my $class_header = fixPaths("$out_basedir/include/$lib/$class",
     900                                                                $current_dir) . " ";
     901                                    $pri_install_classes .= $class_header
     902                                                                unless($pri_install_classes =~ $class_header);
     903                                }
     904                                $pri_install_files.= "$pri_install_iheader ";;
     905                            }
     906                        }
     907                        else {
     908                            my $pri_install_iheader = fixPaths($iheader, $current_dir);
     909                            $pri_install_pfiles.= "$pri_install_iheader ";;
     910                        }
    877911                    }
    878                     print "header created for $iheader ($header_copies)\n" if($header_copies > 0);
     912                    print "header created for $iheader ($header_copies)\n" if($header_copies > 0 && !$quiet);
    879913                }
    880914            }
     
    887921    unless($showonly) {
    888922        my @master_includes;
    889         push @master_includes, "$out_basedir/include/$lib/$lib";
    890         push @master_includes, "$out_basedir/include/phonon_compat/Phonon/Phonon" if ($lib eq "phonon");
     923        push @master_includes, "$out_basedir/include/$lib/$lib";
     924        push @master_includes, "$out_basedir/include/phonon_compat/Phonon/Phonon" if ($lib eq "phonon");
    891925        foreach my $master_include (@master_includes) {
    892926            #generate the "master" include file
    893             $pri_install_files .= fixPaths($master_include, "$modules{$lib}") . " "; #get the master file installed too
    894             if($master_include && -e "$master_include") {
     927            my @tmp = split(/;/,$modules{$lib});
     928            $pri_install_files .= fixPaths($master_include, $tmp[0]) . " "; #get the master file installed too
     929            if($master_include && -e $master_include) {
    895930                open MASTERINCLUDE, "<$master_include";
    896931                local $/;
     
    903938            if($master_include && $master_contents) {
    904939                my $master_dir = dirname($master_include);
    905                 mkpath $master_dir, 0777;
    906                 print "header (master) created for $lib\n";
     940                mkpath $master_dir, !$quiet;
     941                print "header (master) created for $lib\n" unless $quiet;
    907942                open MASTERINCLUDE, ">$master_include";
    908                 print MASTERINCLUDE "$master_contents";
     943                print MASTERINCLUDE $master_contents;
    909944                close MASTERINCLUDE;
    910945            }
     
    912947
    913948        #handle the headers.pri for each module
    914         my $headers_pri_contents = "";
    915         $headers_pri_contents .= "SYNCQT.HEADER_FILES = $pri_install_files\n";
    916         $headers_pri_contents .= "SYNCQT.HEADER_CLASSES = $pri_install_classes\n";
    917         $headers_pri_contents .= "SYNCQT.PRIVATE_HEADER_FILES = $pri_install_pfiles\n";
     949        my $headers_pri_contents = "";
     950        $headers_pri_contents .= "SYNCQT.HEADER_FILES = $pri_install_files\n";
     951        $headers_pri_contents .= "SYNCQT.HEADER_CLASSES = $pri_install_classes\n";
     952        $headers_pri_contents .= "SYNCQT.PRIVATE_HEADER_FILES = $pri_install_pfiles\n";
    918953        my $headers_pri_file = "$out_basedir/include/$lib/headers.pri";
    919         if(-e "$headers_pri_file") {
     954        if(-e $headers_pri_file) {
    920955            open HEADERS_PRI_FILE, "<$headers_pri_file";
    921956            local $/;
     
    928963        if($headers_pri_file && $master_contents) {
    929964            my $headers_pri_dir = dirname($headers_pri_file);
    930             mkpath $headers_pri_dir, 0777;
    931             print "headers.pri file created for $lib\n";
     965            mkpath $headers_pri_dir, !$quiet;
     966            print "headers.pri file created for $lib\n" unless $quiet;
    932967            open HEADERS_PRI_FILE, ">$headers_pri_file";
    933             print HEADERS_PRI_FILE "$headers_pri_contents";
     968            print HEADERS_PRI_FILE $headers_pri_contents;
    934969            close HEADERS_PRI_FILE;
    935970        }
     
    938973unless($showonly || !$create_uic_class_map) {
    939974    my $class_lib_map = "$out_basedir/src/tools/uic/qclass_lib_map.h";
    940     if(-e "$class_lib_map") {
    941         open CLASS_LIB_MAP, "<$class_lib_map";
    942         local $/;
    943         binmode CLASS_LIB_MAP;
    944         my $old_class_lib_map_contents = <CLASS_LIB_MAP>;
    945         close CLASS_LIB_MAP;
    946         $old_class_lib_map_contents =~ s/\r//g; # remove \r's , so comparison is ok on all platforms
    947         $class_lib_map = 0 if($old_class_lib_map_contents eq $class_lib_map_contents);
     975    if(-e $class_lib_map) {
     976        open CLASS_LIB_MAP, "<$class_lib_map";
     977        local $/;
     978        binmode CLASS_LIB_MAP;
     979        my $old_class_lib_map_contents = <CLASS_LIB_MAP>;
     980        close CLASS_LIB_MAP;
     981        $old_class_lib_map_contents =~ s/\r//g; # remove \r's , so comparison is ok on all platforms
     982        $class_lib_map = 0 if($old_class_lib_map_contents eq $class_lib_map_contents);
    948983    }
    949984    if($class_lib_map) {
    950         my $class_lib_map_dir = dirname($class_lib_map);
    951         mkpath $class_lib_map_dir, 0777;
    952         open CLASS_LIB_MAP, ">$class_lib_map";
    953         print CLASS_LIB_MAP "$class_lib_map_contents";
    954         close CLASS_LIB_MAP;
     985        my $class_lib_map_dir = dirname($class_lib_map);
     986        mkpath $class_lib_map_dir, !$quiet;
     987        open CLASS_LIB_MAP, ">$class_lib_map";
     988        print CLASS_LIB_MAP $class_lib_map_contents;
     989        close CLASS_LIB_MAP;
    955990    }
    956991}
    957992
    958993if($check_includes) {
    959     for (keys(%modules)) {
    960         #iteration info
    961         my $lib = $_;
    962         my $dir = "$modules{$lib}";
    963         foreach (split(/;/, $dir)) {
    964             my $current_dir = "$_";
    965             #calc subdirs
    966             my @subdirs = ($current_dir);
    967             foreach (@subdirs) {
    968                 my $subdir = "$_";
    969                 opendir DIR, "$subdir";
    970                 while(my $t = readdir(DIR)) {
     994    for my $lib (keys(%modules)) {
     995            #calc subdirs
     996            my @subdirs = ($modules{$lib});
     997            foreach my $subdir (@subdirs) {
     998                opendir DIR, $subdir or die "Huh, directory ".$subdir." cannot be opened.";
     999                while(my $t = readdir(DIR)) {
    9711000                    push @subdirs, "$subdir/$t" if(-d "$subdir/$t" && !($t eq ".") &&
    9721001                                                   !($t eq "..") && !($t eq ".obj") &&
    9731002                                                   !($t eq ".moc") && !($t eq ".rcc") &&
    9741003                                                   !($t eq ".uic") && !($t eq "build"));
    975                 }
    976                 closedir DIR;
    977             }
    978 
    979             foreach (@subdirs) {
    980                 my $subdir = "$_";
     1004                }
     1005                closedir DIR;
     1006            }
     1007
     1008            foreach my $subdir (@subdirs) {
    9811009                my $header_skip_qt_module_test = 0;
    9821010                foreach(@ignore_for_qt_module_check) {
    9831011                    foreach (split(/;/, $_)) {
    984                         $header_skip_qt_module_test = 1 if ("$subdir" =~ /^$_/);
     1012                        $header_skip_qt_module_test = 1 if ($subdir =~ /^$_/);
    9851013                    }
    9861014                }
    987                 my @headers = findFiles("$subdir", "^[-a-z0-9_]*\\.h\$" , 0);
    988                 foreach (@headers) {
    989                     my $header = "$_";
     1015                my @headers = findFiles($subdir, "^[-a-z0-9_]*\\.h\$" , 0);
     1016                foreach my $header (@headers) {
    9901017                    my $header_skip_qt_begin_header_test = 0;
    9911018                    my $header_skip_qt_begin_namespace_test = 0;
    992                     $header = 0 if("$header" =~ /^ui_.*.h/);
    993                     foreach (@ignore_headers) {
    994                         $header = 0 if("$header" eq "$_");
    995                     }
    996                     if($header) {
    997                         my $public_header = $header;
    998                         if($public_header =~ /_p.h$/ || $public_header =~ /_pch.h$/) {
    999                             $public_header = 0;
    1000                         } else {
    1001                             foreach (@ignore_for_master_contents) {
    1002                                 $public_header = 0 if("$header" eq "$_");
    1003                             }
    1004                             if($public_header) {
    1005                                 foreach (@ignore_for_include_check) {
    1006                                     $public_header = 0 if("$header" eq "$_");
    1007                                 }
     1019                    $header = 0 if($header =~ /^ui_.*.h/);
     1020                    foreach (@ignore_headers) {
     1021                        $header = 0 if($header eq $_);
     1022                    }
     1023                    if($header) {
     1024                        my $public_header = $header;
     1025                        if($public_header =~ /_p.h$/ || $public_header =~ /_pch.h$/) {
     1026                            $public_header = 0;
     1027                        } else {
     1028                            foreach (@ignore_for_master_contents) {
     1029                                $public_header = 0 if($header eq $_);
     1030                            }
     1031                            if($public_header) {
     1032                                foreach (@ignore_for_include_check) {
     1033                                    $public_header = 0 if($header eq $_);
     1034                                }
    10081035                                foreach(@ignore_for_qt_begin_header_check) {
    1009                                     $header_skip_qt_begin_header_test = 1 if ("$header" eq "$_");
     1036                                    $header_skip_qt_begin_header_test = 1 if ($header eq $_);
    10101037                                }
    10111038                                foreach(@ignore_for_qt_begin_namespace_check) {
    1012                                     $header_skip_qt_begin_namespace_test = 1 if ("$header" eq "$_");
     1039                                    $header_skip_qt_begin_namespace_test = 1 if ($header eq $_);
    10131040                                }
    1014                             }
    1015                         }
    1016 
    1017                         my $iheader = $subdir . "/" . $header;
    1018                         if($public_header) {
    1019                             if(open(F, "<$iheader")) {
     1041                            }
     1042                        }
     1043
     1044                        my $iheader = $subdir . "/" . $header;
     1045                        if($public_header) {
     1046                            if(open(F, "<$iheader")) {
    10201047                                my $qt_module_found = 0;
    1021                                 my $qt_begin_header_found = 0;
    1022                                 my $qt_end_header_found = 0;
    1023                                 my $qt_begin_namespace_found = 0;
    1024                                 my $qt_end_namespace_found = 0;
    1025                                 my $line;
    1026                                 while($line = <F>) {
    1027                                     chomp $line;
    1028                                     my $output_line = 1;
     1048                                my $qt_begin_header_found = 0;
     1049                                my $qt_end_header_found = 0;
     1050                                my $qt_begin_namespace_found = 0;
     1051                                my $qt_end_namespace_found = 0;
     1052                                my $line;
     1053                                while($line = <F>) {
     1054                                    chomp $line;
     1055                                    my $output_line = 1;
    10291056                                    if($line =~ /^ *\# *pragma (qt_no_included_check|qt_sync_stop_processing)/) {
    1030                                         last;
    1031                                     } elsif($line =~ /^ *\# *include/) {
    1032                                         my $include = $line;
    1033                                         if($line =~ /<.*>/) {
    1034                                             $include =~ s,.*<(.*)>.*,$1,;
    1035                                         } elsif($line =~ /".*"/) {
    1036                                             $include =~ s,.*"(.*)".*,$1,;
    1037                                         } else {
    1038                                             $include = 0;
    1039                                         }
    1040                                         if($include) {
    1041                                             for (keys(%modules)) {
    1042                                                 my $trylib = $_;
    1043                                                 if(-e "$out_basedir/include/$trylib/$include") {
    1044                                                     print "WARNING: $iheader includes $include when it should include $trylib/$include\n";
    1045                                                 }
    1046                                             }
    1047                                         }
    1048                                     } elsif ($header_skip_qt_begin_header_test == 0 and $line =~ /^QT_BEGIN_HEADER\s*$/) {
    1049                                         $qt_begin_header_found = 1;
    1050                                     } elsif ($header_skip_qt_begin_header_test == 0 and $line =~ /^QT_END_HEADER\s*$/) {
    1051                                         $qt_end_header_found = 1;
    1052                                     } elsif ($header_skip_qt_begin_namespace_test == 0 and $line =~ /^QT_BEGIN_NAMESPACE\s*$/) {
    1053                                         $qt_begin_namespace_found = 1;
    1054                                     } elsif ($header_skip_qt_begin_namespace_test == 0 and $line =~ /^QT_END_NAMESPACE\s*$/) {
    1055                                         $qt_end_namespace_found = 1;
     1057                                        last;
     1058                                    } elsif($line =~ /^ *\# *include/) {
     1059                                        my $include = $line;
     1060                                        if($line =~ /<.*>/) {
     1061                                            $include =~ s,.*<(.*)>.*,$1,;
     1062                                        } elsif($line =~ /".*"/) {
     1063                                            $include =~ s,.*"(.*)".*,$1,;
     1064                                        } else {
     1065                                            $include = 0;
     1066                                        }
     1067                                        if($include) {
     1068                                            for my $trylib (keys(%modules)) {
     1069                                                if(-e "$out_basedir/include/$trylib/$include") {
     1070                                                    print "WARNING: $iheader includes $include when it should include $trylib/$include\n";
     1071                                                }
     1072                                            }
     1073                                        }
     1074                                    } elsif ($header_skip_qt_begin_header_test == 0 and $line =~ /^QT_BEGIN_HEADER\s*$/) {
     1075                                        $qt_begin_header_found = 1;
     1076                                    } elsif ($header_skip_qt_begin_header_test == 0 and $line =~ /^QT_END_HEADER\s*$/) {
     1077                                        $qt_end_header_found = 1;
     1078                                    } elsif ($header_skip_qt_begin_namespace_test == 0 and $line =~ /^QT_BEGIN_NAMESPACE\s*$/) {
     1079                                        $qt_begin_namespace_found = 1;
     1080                                    } elsif ($header_skip_qt_begin_namespace_test == 0 and $line =~ /^QT_END_NAMESPACE\s*$/) {
     1081                                        $qt_end_namespace_found = 1;
    10561082                                    } elsif ($header_skip_qt_module_test == 0 and $line =~ /^QT_MODULE\(.*\)\s*$/) {
    10571083                                        $qt_module_found = 1;
    10581084                                    }
    1059                                 }
     1085                                }
    10601086                                if ($header_skip_qt_begin_header_test == 0) {
    10611087                                    if ($qt_begin_header_found == 0) {
     
    10831109                                    }
    10841110                                }
    1085                                 close(F);
    1086                             }
    1087                         }
    1088                     }
    1089                 }
    1090             }
    1091         }
     1111                                close(F);
     1112                            }
     1113                        }
     1114                    }
     1115                }
     1116            }
    10921117    }
    10931118}
  • trunk/bin/syncqt.bat

    r651 r846  
    11:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    22::
    3 :: Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3:: Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44:: All rights reserved.
    55:: Contact: Nokia Corporation (qt-info@nokia.com)
Note: See TracChangeset for help on using the changeset viewer.