bin/syncqt
changeset 7 f7bc934e204c
parent 3 41300fa6a67c
child 30 5dc02b23752f
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
     1 #!/usr/bin/perl -w
     1 #!/usr/bin/perl -w
     2 ######################################################################
     2 ######################################################################
     3 #
     3 #
     4 # Synchronizes Qt header files - internal development tool.
     4 # Synchronizes Qt header files - internal development tool.
     5 #
     5 #
     6 # Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     6 # Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     7 # Contact: Nokia Corporation (qt-info@nokia.com)
     7 # Contact: Nokia Corporation (qt-info@nokia.com)
     8 #
     8 #
     9 ######################################################################
     9 ######################################################################
    10 
    10 
    11 # use packages -------------------------------------------------------
    11 # use packages -------------------------------------------------------
    12 use File::Basename;
    12 use File::Basename;
    13 use File::Path;
    13 use File::Path;
    14 use Cwd;
    14 use Cwd;
    15 use Config;
    15 use Config;
    16 use strict;
    16 use strict;
       
    17 
       
    18 for (my $i = 0; $i < $#ARGV; $i++) {
       
    19     if ($ARGV[$i] eq "-base-dir" && $i < $#ARGV - 1) {
       
    20         $ENV{"QTDIR"} = $ARGV[$i + 1];
       
    21         last;
       
    22     }
       
    23 }
    17 
    24 
    18 die "syncqt: QTDIR not defined" if ! $ENV{"QTDIR"}; # sanity check
    25 die "syncqt: QTDIR not defined" if ! $ENV{"QTDIR"}; # sanity check
    19 
    26 
    20 # global variables
    27 # global variables
    21 my $isunix = 0;
    28 my $isunix = 0;
    59 my $remove_stale = 1;
    66 my $remove_stale = 1;
    60 my $force_win = 0;
    67 my $force_win = 0;
    61 my $force_relative = 0;
    68 my $force_relative = 0;
    62 my $check_includes = 0;
    69 my $check_includes = 0;
    63 my $copy_headers = 0;
    70 my $copy_headers = 0;
       
    71 my $create_uic_class_map = 1;
       
    72 my $create_private_headers = 1;
       
    73 my $oneway = 0;
    64 my @modules_to_sync ;
    74 my @modules_to_sync ;
    65 $force_relative = 1 if ( -d "/System/Library/Frameworks" );
    75 $force_relative = 1 if ( -d "/System/Library/Frameworks" );
    66 my $out_basedir = $basedir;
    76 my $out_basedir = $basedir;
    67 $out_basedir =~ s=\\=/=g;
    77 $out_basedir =~ s=\\=/=g;
       
    78 my $out_subdir = 'include';
    68 
    79 
    69 # functions ----------------------------------------------------------
    80 # functions ----------------------------------------------------------
    70 
    81 
    71 ######################################################################
    82 ######################################################################
    72 # Syntax:  showUsage()
    83 # Syntax:  showUsage()
    82     print "  -remove-stale         Removes stale headers              (default: " . ($remove_stale ? "yes" : "no") . ")\n";
    93     print "  -remove-stale         Removes stale headers              (default: " . ($remove_stale ? "yes" : "no") . ")\n";
    83     print "  -relative             Force relative symlinks            (default: " . ($force_relative ? "yes" : "no") . ")\n";
    94     print "  -relative             Force relative symlinks            (default: " . ($force_relative ? "yes" : "no") . ")\n";
    84     print "  -windows              Force platform to Windows          (default: " . ($force_win ? "yes" : "no") . ")\n";
    95     print "  -windows              Force platform to Windows          (default: " . ($force_win ? "yes" : "no") . ")\n";
    85     print "  -showonly             Show action but not perform        (default: " . ($showonly ? "yes" : "no") . ")\n";
    96     print "  -showonly             Show action but not perform        (default: " . ($showonly ? "yes" : "no") . ")\n";
    86     print "  -outdir <PATH>        Specify output directory for sync  (default: $out_basedir)\n";
    97     print "  -outdir <PATH>        Specify output directory for sync  (default: $out_basedir)\n";
       
    98     print "  -outsubdir <DIR>      Target subdir under outdir         (default: $out_subdir)\n";
       
    99     print "  -public               Create only public headers         (default: " . ($create_private_headers ? "no" : "yes") . ")\n";
       
   100     print "  -oneway               Don't sync back from outdir        (default: " . ($oneway ? "yes" : "no") . ")\n";
       
   101     print "  -separate-module <NAME>:<PROFILEDIR>:<HEADERDIR> Create headers for <NAME> with original headers in <HEADERDIR> relative to <PROFILEDIR> \n";
    87     print "  -help                 This help\n";
   102     print "  -help                 This help\n";
    88     exit 0;
   103     exit 0;
    89 }
   104 }
    90 
   105 
    91 ######################################################################
   106 ######################################################################
   182         push @ret, "QtConcurrentMap"
   197         push @ret, "QtConcurrentMap"
   183     } elsif(basename($iheader) eq "qtconcurrentfilter.h") {
   198     } elsif(basename($iheader) eq "qtconcurrentfilter.h") {
   184         push @ret, "QtConcurrentFilter"
   199         push @ret, "QtConcurrentFilter"
   185     } elsif(basename($iheader) eq "qtconcurrentrun.h") {
   200     } elsif(basename($iheader) eq "qtconcurrentrun.h") {
   186         push @ret, "QtConcurrentRun"
   201         push @ret, "QtConcurrentRun"
       
   202     } elsif(basename($iheader) eq "qaudio.h") {
       
   203         push @ret, "QAudio"
   187     }
   204     }
   188 
   205 
   189     my $parsable = "";
   206     my $parsable = "";
   190     if(open(F, "<$iheader")) {
   207     if(open(F, "<$iheader")) {
   191         while(<F>) {
   208         while(<F>) {
   423 # Syntax:  copyFile(file, ifile)
   440 # Syntax:  copyFile(file, ifile)
   424 # Params:  file, string, filename to create duplicate for
   441 # Params:  file, string, filename to create duplicate for
   425 #          ifile, string, destination name of duplicate
   442 #          ifile, string, destination name of duplicate
   426 #
   443 #
   427 # Purpose: Keeps files in sync so changes in the newer file will be
   444 # Purpose: Keeps files in sync so changes in the newer file will be
   428 #          written to the other.
   445 #          written to the other. Don't sync back if $oneway is set.
   429 # Returns: 1 if files were synced, else 0.
   446 # Returns: 1 if files were synced, else 0.
   430 # Warning: Dies if script cannot get write access.
   447 # Warning: Dies if script cannot get write access.
   431 ######################################################################
   448 ######################################################################
   432 sub copyFile
   449 sub copyFile
   433 {
   450 {
   449 	$copy = -1;
   466 	$copy = -1;
   450 	$knowdiff = 1;
   467 	$knowdiff = 1;
   451     }
   468     }
   452 
   469 
   453     if ( $knowdiff || ($filecontents ne $ifilecontents) ) {
   470     if ( $knowdiff || ($filecontents ne $ifilecontents) ) {
   454 	if ( $copy > 0 ) {
   471 	if ( $copy > 0 && !$oneway) {
   455 	    my $file_dir = dirname($file);
   472 	    my $file_dir = dirname($file);
   456 	    mkpath $file_dir, 0777 unless(-e "$file_dir");
   473 	    mkpath $file_dir, 0777 unless(-e "$file_dir");
       
   474 	    print "$file $ifile $copy\n";
   457 	    open(O, "> " . $file) || die "Could not open $file for writing (no write permission?)";
   475 	    open(O, "> " . $file) || die "Could not open $file for writing (no write permission?)";
   458 	    local $/;
   476 	    local $/;
   459 	    binmode O;
   477 	    binmode O;
   460 	    print O $ifilecontents;
   478 	    print O $ifilecontents;
   461 	    close O;
   479 	    close O;
   574 	$var = "output";
   592 	$var = "output";
   575 	$val = shift @ARGV;
   593 	$val = shift @ARGV;
   576     } elsif("$arg" eq "-module") {
   594     } elsif("$arg" eq "-module") {
   577 	$var = "module";
   595 	$var = "module";
   578 	$val = shift @ARGV;
   596 	$val = shift @ARGV;
       
   597     } elsif("$arg" eq "-separate-module") {
       
   598 	$var = "separate-module";
       
   599 	$val = shift @ARGV;
   579     } elsif("$arg" eq "-show") {
   600     } elsif("$arg" eq "-show") {
   580 	$var = "showonly";
   601 	$var = "showonly";
   581 	$val = "yes";
   602 	$val = "yes";
       
   603     } elsif("$arg" eq "-base-dir") {
       
   604         # skip, it's been dealt with at the top of the file
       
   605         shift @ARGV;
       
   606         next;
   582     } elsif("$arg" eq '*') {
   607     } elsif("$arg" eq '*') {
   583         # workaround for windows 9x where "%*" expands to "*"
   608         # workaround for windows 9x where "%*" expands to "*"
   584         $var = 1;
   609         $var = 1;
       
   610     } elsif("$arg" eq "-outsubdir") {
       
   611 	$var = "outsubdir";
       
   612 	$val = shift @ARGV;
       
   613     } elsif("$arg" eq "-public") {
       
   614 	$var = "public";
       
   615 	$val = "yes";
       
   616     } elsif("$arg" eq "-oneway") {
       
   617 	$var = "oneway";
       
   618 	$val = "yes";
   585     }
   619     }
   586 
   620 
   587     #do something
   621     #do something
   588     if(!$var || "$var" eq "show_help") {
   622     if(!$var || "$var" eq "show_help") {
   589 	print "Unknown option: $arg\n\n" if(!$var);
   623 	print "Unknown option: $arg\n\n" if(!$var);
   622 	if("$val" eq "yes") {
   656 	if("$val" eq "yes") {
   623 	    $force_relative++;
   657 	    $force_relative++;
   624 	} elsif($force_relative) {
   658 	} elsif($force_relative) {
   625 	    $force_relative--;
   659 	    $force_relative--;
   626 	}
   660 	}
       
   661     } elsif ("$var" eq "public") {
       
   662 	$create_private_headers = ("$val" eq "yes" ? 0 : 1);
       
   663     } elsif ("$var" eq "oneway") {
       
   664 	$oneway = ("$val" eq "yes" ? 1 : 0);
       
   665     } elsif ("$var" eq "outsubdir") {
       
   666 	$out_subdir = $val;
   627     } elsif ("$var" eq "module") {
   667     } elsif ("$var" eq "module") {
   628 	print "module :$val:\n";
   668 	print "module :$val:\n";
   629 	die "No such module: $val" unless(defined $modules{$val});
   669 	die "No such module: $val" unless(defined $modules{$val});
   630 	push @modules_to_sync, $val;
   670 	push @modules_to_sync, $val;
       
   671     } elsif ("$var" eq "separate-module") {
       
   672         my ($module, $prodir, $headerdir) = split(/:/, $val);
       
   673         $modules{$module} = $prodir;
       
   674         push @modules_to_sync, $module;
       
   675         $moduleheaders{$module} = $headerdir;
       
   676         $create_uic_class_map = 0;
       
   677         $create_private_headers = 0;
   631     } elsif ("$var" eq "output") {
   678     } elsif ("$var" eq "output") {
   632 	my $outdir = $val;
   679 	my $outdir = $val;
   633 	if(checkRelative($outdir)) {
   680 	if(checkRelative($outdir)) {
   634 	    $out_basedir = getcwd();
   681 	    $out_basedir = getcwd();
   635 	    chomp $out_basedir;
   682 	    chomp $out_basedir;
   644 @modules_to_sync = keys(%modules) if($#modules_to_sync == -1);
   691 @modules_to_sync = keys(%modules) if($#modules_to_sync == -1);
   645 
   692 
   646 $isunix = checkUnix; #cache checkUnix
   693 $isunix = checkUnix; #cache checkUnix
   647 
   694 
   648 # create path
   695 # create path
   649 mkpath "$out_basedir/include", 0777;
   696 mkpath "$out_basedir/$out_subdir", 0777;
   650 
   697 
   651 my @ignore_headers = ();
   698 my @ignore_headers = ();
   652 my $class_lib_map_contents = "";
   699 my $class_lib_map_contents = "";
   653 my @ignore_for_master_contents = ( "qt.h", "qpaintdevicedefs.h" );
   700 my @ignore_for_master_contents = ( "qt.h", "qpaintdevicedefs.h" );
   654 my @ignore_for_include_check = ( "qatomic.h" );
   701 my @ignore_for_include_check = ( "qatomic.h" );
   700 	}
   747 	}
   701     }
   748     }
   702 
   749 
   703     #remove the old files
   750     #remove the old files
   704     if($remove_stale) {
   751     if($remove_stale) {
   705 	my @subdirs = ("$out_basedir/include/$lib");
   752 	my @subdirs = ("$out_basedir/$out_subdir/$lib");
   706 	foreach (@subdirs) {
   753 	foreach (@subdirs) {
   707 	    my $subdir = "$_";
   754 	    my $subdir = "$_";
   708 	    if (opendir DIR, "$subdir") {
   755 	    if (opendir DIR, "$subdir") {
   709 		while(my $t = readdir(DIR)) {
   756 		while(my $t = readdir(DIR)) {
   710 		    my $file = "$subdir/$t";
   757 		    my $file = "$subdir/$t";
   711 		    if(-d "$file") {
   758 		    if(-d "$file") {
   712 			push @subdirs, "$file" unless($t eq "." || $t eq "..");
   759 			push @subdirs, "$file" unless($t eq "." || $t eq "..");
   713 		    } else {
   760 		    } else {
   714 			my @files = ("$file");
   761 			my @files = ("$file");
   715 			#push @files, "$out_basedir/include/Qt/$t" if(-e "$out_basedir/include/Qt/$t");
   762 			#push @files, "$out_basedir/$out_subdir/Qt/$t" if(-e "$out_basedir/$out_subdir/Qt/$t");
   716 			foreach (@files) {
   763 			foreach (@files) {
   717 			   my $file = $_;
   764 			   my $file = $_;
   718 			   my $remove_file = 0;
   765 			   my $remove_file = 0;
   719 			   if(open(F, "<$file")) {
   766 			   if(open(F, "<$file")) {
   720 				while(<F>) {
   767 				while(<F>) {
   791 			}
   838 			}
   792                     } else {
   839                     } else {
   793 			#find out all the places it goes..
   840 			#find out all the places it goes..
   794 			my @headers;
   841 			my @headers;
   795 			if ($public_header) {
   842 			if ($public_header) {
   796 			    @headers = ( "$out_basedir/include/$lib/$header" );
   843 			    @headers = ( "$out_basedir/$out_subdir/$lib/$header" );
   797 			    push @headers, "$out_basedir/include/Qt/$header"
   844 			    push @headers, "$out_basedir/$out_subdir/Qt/$header"
   798 			      if ("$lib" ne "phonon" && "$subdir" =~ /^$basedir\/src/);
   845 			      if ("$lib" ne "phonon" && "$subdir" =~ /^$basedir\/src/);
   799 
   846 
   800 			    foreach(@classes) {
   847 			    foreach(@classes) {
   801 				my $header_base = basename($header);
   848 				my $header_base = basename($header);
   802 				my $class = $_;
   849 				my $class = $_;
   803 				if ($class =~ m/::/) {
   850 				# Strip namespaces:
   804 				    $class =~ s,::,/,g;
   851 				$class =~ s/^.*:://;
       
   852 #				if ($class =~ m/::/) {
       
   853 #				   class =~ s,::,/,g;
       
   854 #				}
       
   855 				$class_lib_map_contents .= "QT_CLASS_LIB($_, $lib, $header_base)\n";
       
   856 				$header_copies++ if(syncHeader("$out_basedir/$out_subdir/$lib/$class", "$out_basedir/$out_subdir/$lib/$header", 0));
       
   857 
       
   858 				# KDE-Compat headers for Phonon
       
   859 				if ($lib eq "phonon") {
       
   860 				    $header_copies++ if (syncHeader("$out_basedir/$out_subdir/phonon_compat/Phonon/$class", "$out_basedir/$out_subdir/$lib/$header", 0));
   805 				}
   861 				}
   806 				$class_lib_map_contents .= "QT_CLASS_LIB($_, $lib, $header_base)\n";
       
   807 				$header_copies++ if(syncHeader("$out_basedir/include/$lib/$class", "$out_basedir/include/$lib/$header", 0));
       
   808 			    }
   862 			    }
   809 			} else {
   863 			} elsif ($create_private_headers) {
   810 			    @headers = ( "$out_basedir/include/$lib/private/$header" );
   864 			    @headers = ( "$out_basedir/$out_subdir/$lib/private/$header" );
   811 			    push @headers, "$out_basedir/include/Qt/private/$header"
   865 			    push @headers, "$out_basedir/$out_subdir/Qt/private/$header"
   812                               if ("$lib" ne "phonon");
   866                               if ("$lib" ne "phonon");
   813 			}
   867 			}
   814 			foreach(@headers) { #sync them
   868 			foreach(@headers) { #sync them
   815 			    $header_copies++ if(syncHeader($_, $iheader, $copy_headers));
   869 			    $header_copies++ if(syncHeader($_, $iheader, $copy_headers));
   816 			}
   870 			}
   822 			    #deal with the install directives
   876 			    #deal with the install directives
   823 			    if($public_header) {
   877 			    if($public_header) {
   824 				my $pri_install_iheader = fixPaths($iheader, $current_dir);
   878 				my $pri_install_iheader = fixPaths($iheader, $current_dir);
   825 				foreach(@classes) {
   879 				foreach(@classes) {
   826 				    my $class = $_;
   880 				    my $class = $_;
   827 				    if ($class =~ m/::/) {
   881 				    # Strip namespaces:
   828 					$class =~ s,::,/,g;
   882 				    $class =~ s/^.*:://;
   829 				    }
   883 #				    if ($class =~ m/::/) {
   830 				    my $class_header = fixPaths("$out_basedir/include/$lib/$class",
   884 #					$class =~ s,::,/,g;
       
   885 #				    }
       
   886 				    my $class_header = fixPaths("$out_basedir/$out_subdir/$lib/$class",
   831 								$current_dir) . " ";
   887 								$current_dir) . " ";
   832 				    $pri_install_classes .= $class_header
   888 				    $pri_install_classes .= $class_header
   833 								unless($pri_install_classes =~ $class_header);
   889 								unless($pri_install_classes =~ $class_header);
   834 				}
   890 				}
   835 				$pri_install_files.= "$pri_install_iheader ";;
   891 				$pri_install_files.= "$pri_install_iheader ";;
   849     # close the master include:
   905     # close the master include:
   850     $master_contents .= "#endif\n";
   906     $master_contents .= "#endif\n";
   851 
   907 
   852     unless($showonly) {
   908     unless($showonly) {
   853         my @master_includes;
   909         my @master_includes;
   854         if ($lib eq "phonon") {
   910 	push @master_includes, "$out_basedir/$out_subdir/$lib/$lib";
   855             push @master_includes, "$out_basedir/include/phonon_compat/phonon/phonon";
   911 	push @master_includes, "$out_basedir/$out_subdir/phonon_compat/Phonon/Phonon" if ($lib eq "phonon");
   856             push @master_includes, "$out_basedir/include/phonon/Phonon/Phonon";
       
   857         } else {
       
   858             push @master_includes, "$out_basedir/include/$lib/$lib";
       
   859         }
       
   860         foreach my $master_include (@master_includes) {
   912         foreach my $master_include (@master_includes) {
   861             #generate the "master" include file
   913             #generate the "master" include file
   862             $pri_install_files .= fixPaths($master_include, "$modules{$lib}") . " "; #get the master file installed too
   914             $pri_install_files .= fixPaths($master_include, "$modules{$lib}") . " "; #get the master file installed too
   863             if($master_include && -e "$master_include") {
   915             if($master_include && -e "$master_include") {
   864                 open MASTERINCLUDE, "<$master_include";
   916                 open MASTERINCLUDE, "<$master_include";
   882         #handle the headers.pri for each module
   934         #handle the headers.pri for each module
   883 	my $headers_pri_contents = "";
   935 	my $headers_pri_contents = "";
   884 	$headers_pri_contents .= "SYNCQT.HEADER_FILES = $pri_install_files\n";
   936 	$headers_pri_contents .= "SYNCQT.HEADER_FILES = $pri_install_files\n";
   885 	$headers_pri_contents .= "SYNCQT.HEADER_CLASSES = $pri_install_classes\n";
   937 	$headers_pri_contents .= "SYNCQT.HEADER_CLASSES = $pri_install_classes\n";
   886 	$headers_pri_contents .= "SYNCQT.PRIVATE_HEADER_FILES = $pri_install_pfiles\n";
   938 	$headers_pri_contents .= "SYNCQT.PRIVATE_HEADER_FILES = $pri_install_pfiles\n";
   887         my $headers_pri_file = "$out_basedir/include/$lib/headers.pri";
   939         my $headers_pri_file = "$out_basedir/$out_subdir/$lib/headers.pri";
   888         if(-e "$headers_pri_file") {
   940         if(-e "$headers_pri_file") {
   889             open HEADERS_PRI_FILE, "<$headers_pri_file";
   941             open HEADERS_PRI_FILE, "<$headers_pri_file";
   890             local $/;
   942             local $/;
   891             binmode HEADERS_PRI_FILE;
   943             binmode HEADERS_PRI_FILE;
   892             my $old_headers_pri_contents = <HEADERS_PRI_FILE>;
   944             my $old_headers_pri_contents = <HEADERS_PRI_FILE>;
   902             print HEADERS_PRI_FILE "$headers_pri_contents";
   954             print HEADERS_PRI_FILE "$headers_pri_contents";
   903             close HEADERS_PRI_FILE;
   955             close HEADERS_PRI_FILE;
   904         }
   956         }
   905     }
   957     }
   906 }
   958 }
   907 unless($showonly) {
   959 unless($showonly || !$create_uic_class_map) {
   908     my $class_lib_map = "$out_basedir/src/tools/uic/qclass_lib_map.h";
   960     my $class_lib_map = "$out_basedir/src/tools/uic/qclass_lib_map.h";
   909     if(-e "$class_lib_map") {
   961     if(-e "$class_lib_map") {
   910 	open CLASS_LIB_MAP, "<$class_lib_map";
   962 	open CLASS_LIB_MAP, "<$class_lib_map";
   911 	local $/;
   963 	local $/;
   912 	binmode CLASS_LIB_MAP;
   964 	binmode CLASS_LIB_MAP;
  1007 					    $include = 0;
  1059 					    $include = 0;
  1008 					}
  1060 					}
  1009 					if($include) {
  1061 					if($include) {
  1010 					    for (keys(%modules)) {
  1062 					    for (keys(%modules)) {
  1011 						my $trylib = $_;
  1063 						my $trylib = $_;
  1012 						if(-e "$out_basedir/include/$trylib/$include") {
  1064 						if(-e "$out_basedir/$out_subdir/$trylib/$include") {
  1013 						    print "WARNING: $iheader includes $include when it should include $trylib/$include\n";
  1065 						    print "WARNING: $iheader includes $include when it should include $trylib/$include\n";
  1014 						}
  1066 						}
  1015 					    }
  1067 					    }
  1016 					}
  1068 					}
  1017 				    } elsif ($header_skip_qt_begin_header_test == 0 and $line =~ /^QT_BEGIN_HEADER\s*$/) {
  1069 				    } elsif ($header_skip_qt_begin_header_test == 0 and $line =~ /^QT_BEGIN_HEADER\s*$/) {