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; |