qt5base-lts/config.profiles/symbian/headerexport
Qt by Nokia 38be0d1383 Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you
want to look at revision history older than this, please refer to the
Qt Git wiki for how to use Git history grafting. At the time of
writing, this wiki is located here:

http://qt.gitorious.org/qt/pages/GitIntroductionWithQt

If you have already performed the grafting and you don't see any
history beyond this commit, try running "git log" with the "--follow"
argument.

Branched from the monolithic repo, Qt master branch, at commit
896db169ea224deb96c59ce8af800d019de63f12
2011-04-27 12:05:43 +02:00

978 lines
40 KiB
Perl

#!/usr/bin/perl -w
######################################################################
#
# Synchronizes Qt header files - internal development tool.
#
# Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
# Contact: Nokia Corporation (qt-info@nokia.com)
#
######################################################################
# use packages -------------------------------------------------------
use File::Basename;
use File::Path;
use Cwd;
use Config;
use strict;
for (my $i = 0; $i < $#ARGV; $i++) {
if ($ARGV[$i] eq "-base-dir" && $i < $#ARGV - 1) {
$ENV{"QTDIR"} = $ARGV[$i + 1];
last;
}
}
die "syncqt: QTDIR not defined" if ! $ENV{"QTDIR"}; # sanity check
# global variables
my $isunix = 0;
my $basedir = $ENV{"QTDIR"};
$basedir =~ s=\\=/=g;
my %modules = ( # path to module name map
"QtGui" => "$basedir/src/gui",
"QtOpenGL" => "$basedir/src/opengl",
"QtOpenVG" => "$basedir/src/openvg",
"QtCore" => "$basedir/src/corelib",
"QtXml" => "$basedir/src/xml",
"QtXmlPatterns" => "$basedir/src/xmlpatterns",
"QtSql" => "$basedir/src/sql",
"QtNetwork" => "$basedir/src/network",
"QtSvg" => "$basedir/src/svg",
"QtDeclarative" => "$basedir/src/declarative",
"QtScript" => "$basedir/src/script",
"QtScriptTools" => "$basedir/src/scripttools",
"Qt3Support" => "$basedir/src/qt3support",
"ActiveQt" => "$basedir/src/activeqt",
"QtTest" => "$basedir/src/testlib",
"QtHelp" => "$basedir/tools/assistant/lib",
"QtDesigner" => "$basedir/tools/designer/src/lib",
"QtUiTools" => "$basedir/tools/designer/src/uitools",
"QtDBus" => "$basedir/src/dbus",
"phonon" => "$basedir/src/phonon",
"QtMultimedia" => "$basedir/src/multimedia",
"QtMeeGoGraphicsSystemHelper" => "$basedir/tools/qmeegographicssystemhelper",
);
my %moduleheaders = ( # restrict the module headers to those found in relative path
"QtWebKit" => "../WebKit/qt/Api",
"phonon" => "../3rdparty/phonon/phonon",
);
#$modules{"QtCore"} .= ";$basedir/mkspecs/" . $ENV{"MKSPEC"} if defined $ENV{"MKSPEC"};
# global variables (modified by options)
my $force_win = 0;
my $check_includes = 0;
my $create_uic_class_map = 1;
my @modules_to_sync ;
my $out_basedir = $basedir;
$out_basedir =~ s=\\=/=g;
# functions ----------------------------------------------------------
######################################################################
# Syntax: showUsage()
# Params: -none-
#
# Purpose: Show the usage of the script.
# Returns: -none-
######################################################################
sub showUsage
{
print "$0 usage:\n";
print " -windows Force platform to Windows (default: " . ($force_win ? "yes" : "no") . ")\n";
print " -outdir <PATH> Specify output directory for sync (default: $out_basedir)\n";
print " -help This help\n";
exit 0;
}
######################################################################
# Syntax: checkUnix()
# Params: -none-
#
# Purpose: Check if script runs on a Unix system or not. Cygwin
# systems are _not_ detected as Unix systems.
# Returns: 1 if a unix system, else 0.
######################################################################
sub checkUnix {
my ($r) = 0;
if ( $force_win != 0) {
return 0;
} elsif ( -f "/bin/uname" ) {
$r = 1;
(-f "\\bin\\uname") && ($r = 0);
} elsif ( -f "/usr/bin/uname" ) {
$r = 1;
(-f "\\usr\\bin\\uname") && ($r = 0);
}
if($r) {
$_ = $Config{'osname'};
$r = 0 if( /(ms)|(cyg)win/i );
}
return $r;
}
sub checkRelative {
my ($dir) = @_;
return 0 if($dir =~ /^\//);
return 0 if(!checkUnix() && $dir =~ /[a-zA-Z]:[\/\\]/);
return 1;
}
######################################################################
# Syntax: shouldMasterInclude(iheader)
# Params: iheader, string, filename to verify inclusion
#
# Purpose: Determines if header should be in the master include file.
# Returns: 0 if file contains "#pragma qt_no_master_include" or not
# able to open, else 1.
######################################################################
sub shouldMasterInclude {
my ($iheader) = @_;
return 0 if(basename($iheader) =~ /_/);
return 0 if(basename($iheader) =~ /qconfig/);
if(open(F, "<$iheader")) {
while(<F>) {
chomp;
return 0 if(/^\#pragma qt_no_master_include$/);
}
close(F);
} else {
return 0;
}
return 1;
}
######################################################################
# Syntax: classNames(iheader)
# Params: iheader, string, filename to parse for classname "symlinks"
#
# Purpose: Scans through iheader to find all classnames that should be
# synced into library's include structure.
# Returns: List of all class names in a file.
######################################################################
sub classNames {
my @ret;
my ($iheader) = @_;
if(basename($iheader) eq "qglobal.h") {
push @ret, "QtGlobal";
} elsif(basename($iheader) eq "qendian.h") {
push @ret, "QtEndian";
} elsif(basename($iheader) eq "qconfig.h") {
push @ret, "QtConfig";
} elsif(basename($iheader) eq "qplugin.h") {
push @ret, "QtPlugin";
} elsif(basename($iheader) eq "qalgorithms.h") {
push @ret, "QtAlgorithms";
} elsif(basename($iheader) eq "qcontainerfwd.h") {
push @ret, "QtContainerFwd";
} elsif(basename($iheader) eq "qdebug.h") {
push @ret, "QtDebug";
} elsif(basename($iheader) eq "qevent.h") {
push @ret, "QtEvents";
} elsif(basename($iheader) eq "qnamespace.h") {
push @ret, "Qt"
} elsif(basename($iheader) eq "qssl.h") {
push @ret, "QSsl";
} elsif(basename($iheader) eq "qtest.h") {
push @ret, "QTest"
} elsif(basename($iheader) eq "qtconcurrentmap.h") {
push @ret, "QtConcurrentMap"
} elsif(basename($iheader) eq "qtconcurrentfilter.h") {
push @ret, "QtConcurrentFilter"
} elsif(basename($iheader) eq "qtconcurrentrun.h") {
push @ret, "QtConcurrentRun"
} elsif(basename($iheader) eq "qaudio.h") {
push @ret, "QAudio"
}
my $parsable = "";
if(open(F, "<$iheader")) {
while(<F>) {
my $line = $_;
chomp $line;
chop $line if ($line =~ /\r$/);
if($line =~ /^\#/) {
if($line =~ /\\$/) {
while($line = <F>) {
chomp $line;
last unless($line =~ /\\$/);
}
}
return @ret if($line =~ m/^#pragma qt_sync_stop_processing/);
push(@ret, $1) if($line =~ m/^#pragma qt_class\(([^)]*)\)[\r\n]*$/);
$line = 0;
}
if($line) {
$line =~ s,//.*$,,; #remove c++ comments
$line .= ";" if($line =~ m/^Q_[A-Z_]*\(.*\)[\r\n]*$/); #qt macro
$line .= ";" if($line =~ m/^QT_(BEGIN|END)_HEADER[\r\n]*$/); #qt macro
$line .= ";" if($line =~ m/^QT_(BEGIN|END)_NAMESPACE[\r\n]*$/); #qt macro
$line .= ";" if($line =~ m/^QT_MODULE\(.*\)[\r\n]*$/); # QT_MODULE macro
$parsable .= " " . $line;
}
}
close(F);
}
my $last_definition = 0;
my @namespaces;
for(my $i = 0; $i < length($parsable); $i++) {
my $definition = 0;
my $character = substr($parsable, $i, 1);
if($character eq "/" && substr($parsable, $i+1, 1) eq "*") { #I parse like this for greedy reasons
for($i+=2; $i < length($parsable); $i++) {
my $end = substr($parsable, $i, 2);
if($end eq "*/") {
$last_definition = $i+2;
$i++;
last;
}
}
} elsif($character eq "{") {
my $brace_depth = 1;
my $block_start = $i + 1;
BLOCK: for($i+=1; $i < length($parsable); $i++) {
my $ignore = substr($parsable, $i, 1);
if($ignore eq "{") {
$brace_depth++;
} elsif($ignore eq "}") {
$brace_depth--;
unless($brace_depth) {
for(my $i2 = $i+1; $i2 < length($parsable); $i2++) {
my $end = substr($parsable, $i2, 1);
if($end eq ";" || $end ne " ") {
$definition = substr($parsable, $last_definition, $block_start - $last_definition) . "}";
$i = $i2 if($end eq ";");
$last_definition = $i + 1;
last BLOCK;
}
}
}
}
}
} elsif($character eq ";") {
$definition = substr($parsable, $last_definition, $i - $last_definition + 1);
$last_definition = $i + 1;
} elsif($character eq "}") {
# a naked } must be a namespace ending
# if it's not a namespace, it's eaten by the loop above
pop @namespaces;
$last_definition = $i + 1;
}
if (substr($parsable, $last_definition, $i - $last_definition + 1) =~ m/ namespace ([^ ]*) /
&& substr($parsable, $i+1, 1) eq "{") {
push @namespaces, $1;
# Eat the opening { so that the condensing loop above doesn't see it
$i++;
$last_definition = $i + 1;
}
if($definition) {
$definition =~ s=[\n\r]==g;
my @symbols;
if($definition =~ m/^ *typedef *.*\(\*([^\)]*)\)\(.*\);$/) {
push @symbols, $1;
} elsif($definition =~ m/^ *typedef +(.*) +([^ ]*);$/) {
push @symbols, $2;
} elsif($definition =~ m/^ *(template *<.*> *)?(class|struct) +([^ ]* +)?([^<\s]+) ?(<[^>]*> ?)?\s*((,|:)\s*(public|protected|private) *.*)? *\{\}$/) {
push @symbols, $4;
} elsif($definition =~ m/^ *Q_DECLARE_.*ITERATOR\((.*)\);$/) {
push @symbols, "Q" . $1 . "Iterator";
push @symbols, "QMutable" . $1 . "Iterator";
}
foreach my $symbol (@symbols) {
$symbol = (join("::", @namespaces) . "::" . $symbol) if (scalar @namespaces);
push @ret, $symbol
if ($symbol =~ /^Q[^:]*$/ # no-namespace, starting with Q
|| $symbol =~ /^Phonon::/); # or in the Phonon namespace
}
}
}
return @ret;
}
######################################################################
# Syntax: syncHeader(header, iheader, copy)
# Params: header, string, filename to create "symlink" for
# iheader, string, destination name of symlink
# copy, forces header to be a copy of iheader
#
# Purpose: Syncronizes header to iheader
# Returns: 1 if successful, else 0.
######################################################################
sub syncHeader {
my ($header, $iheader, $copy) = @_;
$iheader =~ s=\\=/=g;
$header =~ s=\\=/=g;
return copyFile($iheader, $header) if($copy);
unless(-e $header) {
my $header_dir = dirname($header);
mkpath $header_dir;
#write it
my $iheader_out = fixPaths($iheader, $header_dir);
open HEADER, ">$header" || die "Could not open $header for writing!\n";
print HEADER "#include \"$iheader_out\"\n";
close HEADER;
return 1;
}
return 0;
}
######################################################################
# Syntax: fixPaths(file, dir)
# Params: file, string, filepath to be made relative to dir
# dir, string, dirpath for point of origin
#
# Purpose: file is made relative (if possible) of dir.
# Returns: String with the above applied conversion.
######################################################################
sub fixPaths {
my ($file, $dir) = @_;
$dir =~ s=^$basedir/=$out_basedir/= if(!($basedir eq $out_basedir));
$file =~ s=\\=/=g;
$file =~ s/\+/\\+/g;
$dir =~ s=\\=/=g;
$dir =~ s/\+/\\+/g;
#setup
my $ret = $file;
$ret =~ s,/cygdrive/([a-zA-Z])/,$1:/,g;
my $file_dir = dirname($file);
if($file_dir eq ".") {
$file_dir = getcwd();
$file_dir =~ s=\\=/=g;
}
$file_dir =~ s,/cygdrive/([a-zA-Z])/,$1:/,g;
if($dir eq ".") {
$dir = getcwd();
$dir =~ s=\\=/=g;
}
$dir =~ s,/cygdrive/([a-zA-Z])/,$1:/,g;
return basename($file) if($file_dir eq $dir);
#guts
my $match_dir = 0;
for(my $i = 1; $i < length($file_dir); $i++) {
my $slash = index($file_dir, "/", $i);
last if($slash == -1);
my $tmp = substr($file_dir, 0, $slash);
last unless($dir =~ m,^$tmp/,);
$match_dir = $tmp;
$i = $slash;
}
if($match_dir) {
my $after = substr($dir, length($match_dir));
my $count = ($after =~ tr,/,,);
my $dots = "";
for(my $i = 0; $i < $count; $i++) {
$dots .= "../";
}
$ret =~ s,^$match_dir,$dots,;
}
$ret =~ s,/+,/,g;
return $ret;
}
######################################################################
# Syntax: fileContents(filename)
# Params: filename, string, filename of file to return contents
#
# Purpose: Get the contents of a file.
# Returns: String with contents of the file, or empty string if file
# doens't exist.
# Warning: Dies if it does exist but script cannot get read access.
######################################################################
sub fileContents {
my ($filename) = @_;
my $filecontents = "";
if (-e $filename) {
open(I, "< $filename") || die "Could not open $filename for reading, read block?";
local $/;
binmode I;
$filecontents = <I>;
close I;
}
return $filecontents;
}
######################################################################
# Syntax: fileCompare(file1, file2)
# Params: file1, string, filename of first file
# file2, string, filename of second file
#
# Purpose: Determines if files are equal, and which one is newer.
# Returns: 0 if files are equal no matter the timestamp, -1 if file1
# is newer, 1 if file2 is newer.
######################################################################
sub fileCompare {
my ($file1, $file2) = @_;
my $file1contents = fileContents($file1);
my $file2contents = fileContents($file2);
if (! -e $file1) { return 1; }
if (! -e $file2) { return -1; }
return $file1contents ne $file2contents ? (stat($file2))[9] <=> (stat($file1))[9] : 0;
}
######################################################################
# Syntax: copyFile(file, ifile)
# Params: file, string, filename to create duplicate for
# ifile, string, destination name of duplicate
#
# Purpose: Keeps files in sync so changes in the newer file will be
# written to the other.
# Returns: 1 if files were synced, else 0.
# Warning: Dies if script cannot get write access.
######################################################################
sub copyFile
{
my ($file,$ifile, $copy,$knowdiff,$filecontents,$ifilecontents) = @_;
open( I, "< " . $file ) || die "Could not open $file for reading";
local $/;
binmode I;
$filecontents = <I>;
close I;
my $ifile_dir = dirname($ifile);
mkpath $ifile_dir unless(-e $ifile_dir);
open(O, "> " . $ifile) || die "Could not open $ifile for writing (no write permission?)";
local $/;
binmode O;
print O $filecontents;
close O;
return 1;
}
######################################################################
# Syntax: findFiles(dir, match, descend)
# Params: dir, string, directory to search for name
# match, string, regular expression to match in dir
# descend, integer, 0 = non-recursive search
# 1 = recurse search into subdirectories
#
# Purpose: Finds files matching a regular expression.
# Returns: List of matching files.
#
# Examples:
# findFiles("/usr","\.cpp$",1) - finds .cpp files in /usr and below
# findFiles("/tmp","^#",0) - finds #* files in /tmp
######################################################################
sub findFiles {
my ($dir,$match,$descend) = @_;
my ($file,$p,@files);
local(*D);
$dir =~ s=\\=/=g;
($dir eq "") && ($dir = ".");
if ( opendir(D,$dir) ) {
if ( $dir eq "." ) {
$dir = "";
} else {
($dir =~ /\/$/) || ($dir .= "/");
}
foreach $file ( sort readdir(D) ) {
next if ( $file =~ /^\.\.?$/ );
$p = $file;
($file =~ /$match/) && (push @files, $p);
if ( $descend && -d $p && ! -l $p ) {
push @files, &findFiles($p,$match,$descend);
}
}
closedir(D);
}
return @files;
}
# --------------------------------------------------------------------
# "main" function
# --------------------------------------------------------------------
while ( @ARGV ) {
my $var = 0;
my $val = 0;
#parse
my $arg = shift @ARGV;
if ($arg eq "-h" || $arg eq "-help" || $arg eq "?") {
$var = "show_help";
$val = "yes";
} elsif($arg eq "-o" || $arg eq "-outdir") {
$var = "output";
$val = shift @ARGV;
} elsif($arg eq "-showonly" || $arg eq "-remove-stale" || $arg eq "-windows" ||
$arg eq "-relative" || $arg eq "-check-includes") {
$var = substr($arg, 1);
$val = "yes";
} elsif($arg =~ /^-no-(.*)$/) {
$var = $1;
$val = "no";
#these are for commandline compat
} elsif($arg eq "-inc") {
$var = "output";
$val = shift @ARGV;
} elsif($arg eq "-base-dir") {
# skip, it's been dealt with at the top of the file
shift @ARGV;
next;
}
#do something
if(!$var || $var eq "show_help") {
print "Unknown option: $arg\n\n" if(!$var);
showUsage();
} elsif ($var eq "check-includes") {
if($val eq "yes") {
$check_includes++;
} elsif($check_includes) {
$check_includes--;
}
} elsif ($var eq "windows") {
if($val eq "yes") {
$force_win++;
} elsif($force_win) {
$force_win--;
}
} elsif ($var eq "output") {
my $outdir = $val;
if(checkRelative($outdir)) {
$out_basedir = getcwd();
chomp $out_basedir;
$out_basedir .= "/" . $outdir;
} else {
$out_basedir = $outdir;
}
# \ -> /
$out_basedir =~ s=\\=/=g;
}
}
@modules_to_sync = keys(%modules) if($#modules_to_sync == -1);
$isunix = checkUnix; #cache checkUnix
# create path
mkpath "$out_basedir/include";
mkpath "$out_basedir/mw/Qt";
my @ignore_headers = ();
my $class_lib_map_contents = "";
my @ignore_for_master_contents = ( "qt.h", "qpaintdevicedefs.h" );
my @ignore_for_include_check = ( "qatomic.h" );
my @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" );
my @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" );
my @ignore_for_qt_module_check = ( "$modules{QtCore}/arch", "$modules{QtCore}/global", "$modules{QtSql}/drivers", "$modules{QtTest}", "$modules{QtDesigner}", "$modules{QtUiTools}", "$modules{QtDBus}", "$modules{phonon}" );
my %colliding_headers = ();
my %inject_headers;
# Force generation of forwarding header for qconfig.h if (and only if) we can't
# find the header by normal means.
%inject_headers = ( "$basedir/src/corelib/global" => ( "*qconfig.h" ) ) unless (-e "$basedir/src/corelib/global/qconfig.h");
foreach my $lib (@modules_to_sync) {
#iteration info
my $dir = $modules{$lib};
my $pathtoheaders = "";
$pathtoheaders = $moduleheaders{$lib} if ($moduleheaders{$lib});
#information used after the syncing
my $pri_install_classes = "";
my $pri_install_files = "";
my $pri_install_pfiles = "";
my $libcapitals = $lib;
$libcapitals =~ y/a-z/A-Z/;
my $master_contents = "#ifndef QT_".$libcapitals."_MODULE_H\n#define QT_".$libcapitals."_MODULE_H\n";
#get dependencies
if(-e "$dir/" . basename($dir) . ".pro") {
if(open(F, "<$dir/" . basename($dir) . ".pro")) {
while(my $line = <F>) {
chomp $line;
if($line =~ /^ *QT *\+?= *([^\r\n]*)/) {
foreach(split(/ /, $1)) {
$master_contents .= "#include <QtCore/QtCore>\n" if($_ eq "core");
$master_contents .= "#include <QtGui/QtGui>\n" if($_ eq "gui");
$master_contents .= "#include <QtNetwork/QtNetwork>\n" if($_ eq "network");
$master_contents .= "#include <QtSvg/QtSvg>\n" if($_ eq "svg");
$master_contents .= "#include <QtDeclarative/QtDeclarative>\n" if($_ eq "declarative");
$master_contents .= "#include <QtScript/QtScript>\n" if($_ eq "script");
$master_contents .= "#include <QtScriptTools/QtScriptTools>\n" if($_ eq "scripttools");
$master_contents .= "#include <Qt3Support/Qt3Support>\n" if($_ eq "qt3support");
$master_contents .= "#include <QtSql/QtSql>\n" if($_ eq "sql");
$master_contents .= "#include <QtXml/QtXml>\n" if($_ eq "xml");
$master_contents .= "#include <QtXmlPatterns/QtXmlPatterns>\n" if($_ eq "xmlpatterns");
$master_contents .= "#include <QtOpenGL/QtOpenGL>\n" if($_ eq "opengl");
$master_contents .= "#include <QtOpenVG/QtOpenVG>\n" if($_ eq "openvg");
}
}
}
close(F);
}
}
#remove the old files
my @subdirs = ("$out_basedir/mw/$lib");
foreach my $subdir (@subdirs) {
if (opendir DIR, $subdir) {
while(my $t = readdir(DIR)) {
my $file = "$subdir/$t";
if(-d $file) {
push @subdirs, $file unless($t eq "." || $t eq "..");
} else {
my @files = ($file);
#push @files, "$out_basedir/mw/Qt/$t" if(-e "$out_basedir/mw/Qt/$t");
foreach my $file (@files) {
my $remove_file = 0;
if(open(F, "<$file")) {
while(my $line = <F>) {
chomp $line;
if($line =~ /^\#include \"([^\"]*)\"$/) {
my $include = $1;
$include = $subdir . "/" . $include unless(substr($include, 0, 1) eq "/");
$remove_file = 1 unless(-e $include);
} else {
$remove_file = 0;
last;
}
}
close(F);
unlink $file if($remove_file);
}
}
}
}
closedir DIR;
}
}
#create the new ones
foreach my $current_dir (split(/;/, $dir)) {
my $headers_dir = $current_dir;
$headers_dir .= "/$pathtoheaders" if ($pathtoheaders);
#calc subdirs
my @subdirs = ($headers_dir);
foreach my $subdir (@subdirs) {
opendir DIR, $subdir or next;
while(my $t = readdir(DIR)) {
push @subdirs, "$subdir/$t" if(-d "$subdir/$t" && !($t eq ".") &&
!($t eq "..") && !($t eq ".obj") &&
!($t eq ".moc") && !($t eq ".rcc") &&
!($t eq ".uic") && !($t eq "build"));
}
closedir DIR;
}
#calc files and "copy" them
foreach my $subdir (@subdirs) {
my @headers = findFiles($subdir, "^[-a-z0-9_]*\\.h\$" , 0);
push @headers, $inject_headers{$subdir} if (defined $inject_headers{$subdir});
foreach my $header (@headers) {
my $shadow = ($header =~ s/^\*//);
$header = 0 if($header =~ /^ui_.*.h/);
foreach (@ignore_headers) {
$header = 0 if($header eq $_);
}
if($header) {
my $header_copies = 0;
#figure out if it is a public header
my $public_header = $header;
if($public_header =~ /_p.h$/ || $public_header =~ /_pch.h$/) {
$public_header = 0;
} else {
foreach (@ignore_for_master_contents) {
$public_header = 0 if($header eq $_);
}
}
my $iheader = $subdir . "/" . $header;
$iheader =~ s/^\Q$basedir\E/$out_basedir/ if ($shadow);
my @classes = $public_header ? classNames($iheader) : ();
#find out all the places it goes..
my @headers;
if ($public_header) {
@headers = ( "$out_basedir/mw/$lib/$header" );
# write forwarding headers to include/Qt
if ($lib ne "phonon" && $subdir =~ /^$basedir\/src/) {
my $file_name = "$out_basedir/mw/Qt/$header";
my $file_op = '>';
my $header_content = '';
if (exists $colliding_headers{$file_name}) {
$file_op = '>>';
} else {
$colliding_headers{$file_name} = 1;
my $warning_msg = 'Inclusion of header files from include/Qt is deprecated.';
$header_content = "#ifndef QT_NO_QT_INCLUDE_WARN\n" .
" #if defined(__GNUC__)\n" .
" #warning \"$warning_msg\"\n" .
" #elif defined(_MSC_VER)\n" .
" #pragma message(\"WARNING: $warning_msg\")\n" .
" #endif\n".
"#endif\n\n";
}
$header_content .= '#include "' . "../$lib/$header" . "\"\n";
open HEADERFILE, $file_op, $file_name or die "unable to open '$file_name' : $!\n";
print HEADERFILE $header_content;
close HEADERFILE;
}
foreach my $full_class (@classes) {
my $header_base = basename($header);
# Strip namespaces:
my $class = $full_class;
$class =~ s/^.*:://;
# if ($class =~ m/::/) {
# class =~ s,::,/,g;
# }
$class_lib_map_contents .= "QT_CLASS_LIB($full_class, $lib, $header_base)\n";
$header_copies++ if(syncHeader("$out_basedir/mw/$lib/$class", "$out_basedir/mw/$lib/$header", 0));
# KDE-Compat headers for Phonon
if ($lib eq "phonon") {
$header_copies++ if (syncHeader("$out_basedir/mw/phonon_compat/Phonon/$class", "$out_basedir/mw/$lib/$header", 0));
}
}
} else {
@headers = ( "$out_basedir/mw/$lib/private/$header" );
}
foreach(@headers) { #sync them
$header_copies++ if(syncHeader($_, $iheader, 1));
}
if($public_header) {
#put it into the master file
$master_contents .= "#include \"$public_header\"\n" if(shouldMasterInclude($iheader));
#deal with the install directives
if($public_header) {
my $pri_install_iheader = fixPaths($iheader, $current_dir);
foreach my $class (@classes) {
# Strip namespaces:
$class =~ s/^.*:://;
# if ($class =~ m/::/) {
# $class =~ s,::,/,g;
# }
my $class_header = fixPaths("$out_basedir/mw/$lib/$class",
$current_dir) . " ";
$pri_install_classes .= $class_header
unless($pri_install_classes =~ $class_header);
}
$pri_install_files.= "$pri_install_iheader ";;
}
}
else {
my $pri_install_iheader = fixPaths($iheader, $current_dir);
$pri_install_pfiles.= "$pri_install_iheader ";;
}
print "header created for $iheader ($header_copies)\n" if($header_copies > 0);
}
}
}
}
# close the master include:
$master_contents .= "#endif\n";
my @master_includes;
push @master_includes, "$out_basedir/mw/$lib/$lib";
push @master_includes, "$out_basedir/mw/phonon_compat/Phonon/Phonon" if ($lib eq "phonon");
foreach my $master_include (@master_includes) {
#generate the "master" include file
my @tmp = split(/;/,$modules{$lib});
$pri_install_files .= fixPaths($master_include, $tmp[0]) . " "; #get the master file installed too
if($master_include && -e $master_include) {
open MASTERINCLUDE, "<$master_include";
local $/;
binmode MASTERINCLUDE;
my $oldmaster = <MASTERINCLUDE>;
close MASTERINCLUDE;
$oldmaster =~ s/\r//g; # remove \r's , so comparison is ok on all platforms
$master_include = 0 if($oldmaster eq $master_contents);
}
if($master_include && $master_contents) {
my $master_dir = dirname($master_include);
mkpath $master_dir;
print "header (master) created for $lib\n";
open MASTERINCLUDE, ">$master_include";
print MASTERINCLUDE $master_contents;
close MASTERINCLUDE;
}
}
#handle the headers.pri for each module
my $headers_pri_contents = "";
$headers_pri_contents .= "SYNCQT.HEADER_FILES = $pri_install_files\n";
$headers_pri_contents .= "SYNCQT.HEADER_CLASSES = $pri_install_classes\n";
$headers_pri_contents .= "SYNCQT.PRIVATE_HEADER_FILES = $pri_install_pfiles\n";
my $headers_pri_file = "$out_basedir/mw/$lib/headers.pri";
if(-e $headers_pri_file) {
open HEADERS_PRI_FILE, "<$headers_pri_file";
local $/;
binmode HEADERS_PRI_FILE;
my $old_headers_pri_contents = <HEADERS_PRI_FILE>;
close HEADERS_PRI_FILE;
$old_headers_pri_contents =~ s/\r//g; # remove \r's , so comparison is ok on all platforms
$headers_pri_file = 0 if($old_headers_pri_contents eq $headers_pri_contents);
}
if($headers_pri_file && $master_contents) {
my $headers_pri_dir = dirname($headers_pri_file);
mkpath $headers_pri_dir;
print "headers.pri file created for $lib\n";
open HEADERS_PRI_FILE, ">$headers_pri_file";
print HEADERS_PRI_FILE $headers_pri_contents;
close HEADERS_PRI_FILE;
}
}
unless(!$create_uic_class_map) {
my $class_lib_map = "$out_basedir/src/tools/uic/qclass_lib_map.h";
if(-e $class_lib_map) {
open CLASS_LIB_MAP, "<$class_lib_map";
local $/;
binmode CLASS_LIB_MAP;
my $old_class_lib_map_contents = <CLASS_LIB_MAP>;
close CLASS_LIB_MAP;
$old_class_lib_map_contents =~ s/\r//g; # remove \r's , so comparison is ok on all platforms
$class_lib_map = 0 if($old_class_lib_map_contents eq $class_lib_map_contents);
}
if($class_lib_map) {
my $class_lib_map_dir = dirname($class_lib_map);
mkpath $class_lib_map_dir;
open CLASS_LIB_MAP, ">$class_lib_map";
print CLASS_LIB_MAP $class_lib_map_contents;
close CLASS_LIB_MAP;
}
}
if($check_includes) {
for my $lib (keys(%modules)) {
#calc subdirs
my @subdirs = ($modules{$lib});
foreach my $subdir (@subdirs) {
opendir DIR, $subdir or die "Huh, directory ".$subdir." cannot be opened.";
while(my $t = readdir(DIR)) {
push @subdirs, "$subdir/$t" if(-d "$subdir/$t" && !($t eq ".") &&
!($t eq "..") && !($t eq ".obj") &&
!($t eq ".moc") && !($t eq ".rcc") &&
!($t eq ".uic") && !($t eq "build"));
}
closedir DIR;
}
foreach my $subdir (@subdirs) {
my $header_skip_qt_module_test = 0;
foreach(@ignore_for_qt_module_check) {
foreach (split(/;/, $_)) {
$header_skip_qt_module_test = 1 if ($subdir =~ /^$_/);
}
}
my @headers = findFiles($subdir, "^[-a-z0-9_]*\\.h\$" , 0);
foreach my $header (@headers) {
my $header_skip_qt_begin_header_test = 0;
my $header_skip_qt_begin_namespace_test = 0;
$header = 0 if($header =~ /^ui_.*.h/);
foreach (@ignore_headers) {
$header = 0 if($header eq $_);
}
if($header) {
my $public_header = $header;
if($public_header =~ /_p.h$/ || $public_header =~ /_pch.h$/) {
$public_header = 0;
} else {
foreach (@ignore_for_master_contents) {
$public_header = 0 if($header eq $_);
}
if($public_header) {
foreach (@ignore_for_include_check) {
$public_header = 0 if($header eq $_);
}
foreach(@ignore_for_qt_begin_header_check) {
$header_skip_qt_begin_header_test = 1 if ($header eq $_);
}
foreach(@ignore_for_qt_begin_namespace_check) {
$header_skip_qt_begin_namespace_test = 1 if ($header eq $_);
}
}
}
my $iheader = $subdir . "/" . $header;
if($public_header) {
if(open(F, "<$iheader")) {
my $qt_module_found = 0;
my $qt_begin_header_found = 0;
my $qt_end_header_found = 0;
my $qt_begin_namespace_found = 0;
my $qt_end_namespace_found = 0;
my $line;
while($line = <F>) {
chomp $line;
my $output_line = 1;
if($line =~ /^ *\# *pragma (qt_no_included_check|qt_sync_stop_processing)/) {
last;
} elsif($line =~ /^ *\# *include/) {
my $include = $line;
if($line =~ /<.*>/) {
$include =~ s,.*<(.*)>.*,$1,;
} elsif($line =~ /".*"/) {
$include =~ s,.*"(.*)".*,$1,;
} else {
$include = 0;
}
if($include) {
for my $trylib (keys(%modules)) {
if(-e "$out_basedir/mw/$trylib/$include") {
print "WARNING: $iheader includes $include when it should include $trylib/$include\n";
}
}
}
} elsif ($header_skip_qt_begin_header_test == 0 and $line =~ /^QT_BEGIN_HEADER\s*$/) {
$qt_begin_header_found = 1;
} elsif ($header_skip_qt_begin_header_test == 0 and $line =~ /^QT_END_HEADER\s*$/) {
$qt_end_header_found = 1;
} elsif ($header_skip_qt_begin_namespace_test == 0 and $line =~ /^QT_BEGIN_NAMESPACE\s*$/) {
$qt_begin_namespace_found = 1;
} elsif ($header_skip_qt_begin_namespace_test == 0 and $line =~ /^QT_END_NAMESPACE\s*$/) {
$qt_end_namespace_found = 1;
} elsif ($header_skip_qt_module_test == 0 and $line =~ /^QT_MODULE\(.*\)\s*$/) {
$qt_module_found = 1;
}
}
if ($header_skip_qt_begin_header_test == 0) {
if ($qt_begin_header_found == 0) {
print "WARNING: $iheader does not include QT_BEGIN_HEADER\n";
}
if ($qt_begin_header_found && $qt_end_header_found == 0) {
print "WARNING: $iheader has QT_BEGIN_HEADER but no QT_END_HEADER\n";
}
}
if ($header_skip_qt_begin_namespace_test == 0) {
if ($qt_begin_namespace_found == 0) {
print "WARNING: $iheader does not include QT_BEGIN_NAMESPACE\n";
}
if ($qt_begin_namespace_found && $qt_end_namespace_found == 0) {
print "WARNING: $iheader has QT_BEGIN_NAMESPACE but no QT_END_NAMESPACE\n";
}
}
if ($header_skip_qt_module_test == 0) {
if ($qt_module_found == 0) {
print "WARNING: $iheader does not include QT_MODULE\n";
}
}
close(F);
}
}
}
}
}
}
}
exit 0;