diff options
Diffstat (limited to 'modules/Internals/.svn/text-base/SysCheck.pm.svn-base')
-rw-r--r-- | modules/Internals/.svn/text-base/SysCheck.pm.svn-base | 1730 |
1 files changed, 0 insertions, 1730 deletions
diff --git a/modules/Internals/.svn/text-base/SysCheck.pm.svn-base b/modules/Internals/.svn/text-base/SysCheck.pm.svn-base deleted file mode 100644 index c4871bc..0000000 --- a/modules/Internals/.svn/text-base/SysCheck.pm.svn-base +++ /dev/null @@ -1,1730 +0,0 @@ -########################################################################### -# Module for ABI Compliance Checker to compare Operating Systems -# -# Copyright (C) 2009-2010 The Linux Foundation. -# Copyright (C) 2009-2011 Institute for System Programming, RAS. -# Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -# Copyright (C) 2011 ROSA Laboratory. -# -# Written by Andrey Ponomarenko -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License or the GNU Lesser -# General Public License as published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# and the GNU Lesser General Public License along with this program. -# If not, see <http://www.gnu.org/licenses/>. -########################################################################### -use strict; -use File::Temp qw(tempdir); -use Cwd qw(abs_path cwd); - -my ($Debug, $Quiet, $LogMode, $CheckHeadersOnly, $SystemRoot, $MODULES_DIR, $GCC_PATH, -$CrossPrefix, $TargetSysInfo, $TargetLibraryName, $CrossGcc, $UseStaticLibs, $NoStdInc, $OStarget); -my $OSgroup = get_OSgroup(); -my $TMP_DIR = tempdir(CLEANUP=>1); -my $ORIG_DIR = cwd(); -my $LIB_EXT = getLIB_EXT($OSgroup); - -my %SysDescriptor; -my %Cache; - -sub cmpSystems($$$) -{ # -cmp-systems option handler - # should be used with -d1 and -d2 options - my ($SPath1, $SPath2, $Opts) = @_; - readOpts($Opts); - if(not $SPath1) { - exitStatus("Error", "the option -d1 should be specified"); - } - elsif(not -d $SPath1) { - exitStatus("Access_Error", "can't access directory \'".$SPath1."\'"); - } - elsif(not -d $SPath1."/abi_dumps") { - exitStatus("Access_Error", "can't access directory \'".$SPath1."/abi_dumps\'"); - } - if(not $SPath2) { - exitStatus("Error", "the option -d2 should be specified"); - } - elsif(not -d $SPath2) { - exitStatus("Access_Error", "can't access directory \'".$SPath2."\'"); - } - elsif(not -d $SPath2."/abi_dumps") { - exitStatus("Access_Error", "can't access directory \'".$SPath2."/abi_dumps\'"); - } - # sys_dumps/<System>/<Arch>/... - my $SystemName1 = get_filename(get_dirname($SPath1)); - my $SystemName2 = get_filename(get_dirname($SPath2)); - # sys_dumps/<System>/<Arch>/... - my $ArchName = get_filename($SPath1); - if($ArchName ne get_filename($SPath2)) { - exitStatus("Error", "can't compare systems of different CPU architecture"); - } - if(my $OStarget_Dump = readFile($SPath1."/target.txt")) - { # change target - $OStarget = $OStarget_Dump; - $LIB_EXT = getLIB_EXT($OStarget); - } - my $GroupByHeaders = 0; - if(my $Mode = readFile($SPath1."/mode.txt")) - { # change mode - if($Mode eq "headers-only") - { # -headers-only mode - $CheckHeadersOnly = 1; - $GroupByHeaders = 1; - } - if($Mode eq "group-by-headers") { - $GroupByHeaders = 1; - } - } - my $SYS_REPORT_PATH = "sys_compat_reports/".$SystemName1."_to_".$SystemName2."/$ArchName"; - rmtree($SYS_REPORT_PATH); - my (%LibSoname1, %LibSoname2) = (); - foreach (split(/\n/, readFile($SPath1."/sonames.txt"))) { - if(my ($LFName, $Soname) = split(/;/, $_)) - { - if($OStarget eq "symbian") { - $Soname=~s/\{.+\}//; - } - $LibSoname1{$LFName} = $Soname; - } - } - foreach (split(/\n/, readFile($SPath2."/sonames.txt"))) { - if(my ($LFName, $Soname) = split(/;/, $_)) - { - if($OStarget eq "symbian") { - $Soname=~s/\{.+\}//; - } - $LibSoname2{$LFName} = $Soname; - } - } - my (%LibV1, %LibV2) = (); - foreach (split(/\n/, readFile($SPath1."/versions.txt"))) { - if(my ($LFName, $V) = split(/;/, $_)) { - $LibV1{$LFName} = $V; - } - } - foreach (split(/\n/, readFile($SPath2."/versions.txt"))) { - if(my ($LFName, $V) = split(/;/, $_)) { - $LibV2{$LFName} = $V; - } - } - my @Dumps1 = cmd_find($SPath1."/abi_dumps","f","*.tar.gz",1); - if(not @Dumps1) - { # zip-based dump - @Dumps1 = cmd_find($SPath1."/abi_dumps","f","*.zip",1); - } - my @Dumps2 = cmd_find($SPath2."/abi_dumps","f","*.tar.gz",1); - if(not @Dumps2) - { # zip-based dump - @Dumps2 = cmd_find($SPath2."/abi_dumps","f","*.zip",1); - } - my (%LibVers1, %LibVers2) = (); - foreach my $DPath (@Dumps1) - { - if(my $Name = isDump($DPath)) - { - my ($Soname, $V) = ($LibSoname1{$Name}, $LibV1{$Name}); - if(not $V) { - $V = parse_libname($Name, "version", $OStarget); - } - if($GroupByHeaders) { - $Soname = $Name; - } - $LibVers1{$Soname}{$V} = $DPath; - } - } - foreach my $DPath (@Dumps2) - { - if(my $Name = isDump($DPath)) - { - my ($Soname, $V) = ($LibSoname2{$Name}, $LibV2{$Name}); - if(not $V) { - $V = parse_libname($Name, "version", $OStarget); - } - if($GroupByHeaders) { - $Soname = $Name; - } - $LibVers2{$Soname}{$V} = $DPath; - } - } - my (%Added, %Removed) = (); - my (%ChangedSoname, %TestResults, %SONAME_Changed); - if(not $GroupByHeaders) - { - my %ChangedSoname_Safe = (); - foreach my $LName (sort keys(%LibSoname2)) - { # libcurl.so.3 -> libcurl.so.4 (search for SONAME by the file name) - # OS #1 => OS #2 - if(defined $LibVers2{$LName}) - { # already registered - next; - } - my $Soname = $LibSoname2{$LName}; - if(defined $LibVers2{$Soname} - and defined $LibVers1{$LName}) - { - $LibVers2{$LName} = $LibVers2{$Soname}; - $ChangedSoname_Safe{$Soname}=$LName; - } - } - foreach my $LName (sort keys(%LibSoname1)) - { # libcurl.so.3 -> libcurl.so.4 (search for SONAME by the file name) - # OS #1 <= OS #2 - if(defined $LibVers1{$LName}) - { # already registered - next; - } - my $Soname = $LibSoname1{$LName}; - if(defined $LibVers1{$Soname} - and defined $LibVers2{$LName}) { - $LibVers1{$LName} = $LibVers1{$Soname}; - } - } - my (%AddedShort, %RemovedShort) = (); - if(not $GroupByHeaders) { - printMsg("INFO", "Checking added/removed libs"); - } - foreach my $LName (sort {lc($a) cmp lc($b)} keys(%LibVers1)) - { # removed libs - if(not is_target_lib($LName)) { - next; - } - if(not defined $LibVers1{$LName}) { - next; - } - my @Versions1 = keys(%{$LibVers1{$LName}}); - if($#Versions1>=1) - { # should be only one version - next; - } - if(not defined $LibVers2{$LName} - or not keys(%{$LibVers2{$LName}})) - { # removed library - if(not $LibSoname2{$LName}) - { - $RemovedShort{parse_libname($LName, "name+ext", $OStarget)}{$LName}=1; - $Removed{$LName}{"version"}=$Versions1[0]; - my $ListPath = "info/$LName/symbols.html"; - createSymbolsList($LibVers1{$LName}{$Versions1[0]}, - $SYS_REPORT_PATH."/".$ListPath, $LName, $Versions1[0]."-".$SystemName1, $ArchName); - $Removed{$LName}{"list"} = $ListPath; - } - } - } - foreach my $LName (sort {lc($a) cmp lc($b)} keys(%LibVers2)) - { # added libs - if(not is_target_lib($LName)) { - next; - } - if(not defined $LibVers2{$LName}) { - next; - } - my @Versions2 = keys(%{$LibVers2{$LName}}); - if($#Versions2>=1) - { # should be only one version - next; - } - if($ChangedSoname_Safe{$LName}) - { # changed soname but added the symbolic link for old-version library - next; - } - if(not defined $LibVers1{$LName} - or not keys(%{$LibVers1{$LName}})) - { # added library - if(not $LibSoname1{$LName}) - { - $AddedShort{parse_libname($LName, "name+ext", $OStarget)}{$LName}=1; - $Added{$LName}{"version"}=$Versions2[0]; - my $ListPath = "info/$LName/symbols.html"; - createSymbolsList($LibVers2{$LName}{$Versions2[0]}, - $SYS_REPORT_PATH."/".$ListPath, $LName, $Versions2[0]."-".$SystemName2, $ArchName); - $Added{$LName}{"list"} = $ListPath; - } - } - } - foreach my $LSName (keys(%AddedShort)) - { # changed SONAME - my @AddedSonames = keys(%{$AddedShort{$LSName}}); - next if(length(@AddedSonames)!=1); - my @RemovedSonames = keys(%{$RemovedShort{$LSName}}); - next if(length(@RemovedSonames)!=1); - $ChangedSoname{$AddedSonames[0]}=$RemovedSonames[0]; - $ChangedSoname{$RemovedSonames[0]}=$AddedSonames[0]; - } - } - foreach my $LName (sort {lc($a) cmp lc($b)} keys(%LibVers1)) - { - if(not is_target_lib($LName)) { - next; - } - my @Versions1 = keys(%{$LibVers1{$LName}}); - if(not @Versions1 or $#Versions1>=1) - { # should be only one version - next; - } - my $LV1 = $Versions1[0]; - my $DPath1 = $LibVers1{$LName}{$LV1}; - my @Versions2 = keys(%{$LibVers2{$LName}}); - if($#Versions2>=1) - { # should be only one version - next; - } - my ($LV2, $LName2, $DPath2) = (); - if(@Versions2) - { - $LV2 = $Versions2[0]; - $DPath2 = $LibVers2{$LName}{$LV2}; - } - elsif($LName2 = $ChangedSoname{$LName}) - { # changed SONAME - @Versions2 = keys(%{$LibVers2{$LName2}}); - if(not @Versions2 or $#Versions2>=1) { - next; - } - $LV2 = $Versions2[0]; - $DPath2 = $LibVers2{$LName2}{$LV2}; - $LName = parse_libname($LName, "name+ext", $OStarget); - $SONAME_Changed{$LName} = 1; - } - else - { # removed - next; - } - my ($FV1, $FV2) = ($LV1."-".$SystemName1, $LV2."-".$SystemName2); - my $ACC_compare = "perl $0 -l $LName -d1 \"$DPath1\" -d2 \"$DPath2\""; - my $LReportPath = "compat_reports/$LName/abi_compat_report.html"; - my $LReportPath_Full = $SYS_REPORT_PATH."/".$LReportPath; - $ACC_compare .= " -report-path \"$LReportPath_Full\""; - if($CheckHeadersOnly) { - $ACC_compare .= " -headers-only"; - } - if($GroupByHeaders) { - $ACC_compare .= " -component header"; - } - if($Quiet) - { # quiet mode - $ACC_compare .= " -quiet"; - } - if($LogMode eq "n") { - $ACC_compare .= " -logging-mode n"; - } - elsif($Quiet) { - $ACC_compare .= " -logging-mode a"; - } - if($Debug) - { # debug mode - $ACC_compare .= " -debug"; - printMsg("INFO", "$ACC_compare"); - } - printMsg("INFO_C", "Checking $LName: "); - system($ACC_compare." 1>$TMP_DIR/null 2>$TMP_DIR/$LName.stderr"); - if(-s "$TMP_DIR/$LName.stderr") - { - my $ErrorLog = readFile("$TMP_DIR/$LName.stderr"); - chomp($ErrorLog); - printMsg("INFO", "Failed ($ErrorLog)"); - } - else - { - printMsg("INFO", "Ok"); - $TestResults{$LName} = readAttributes($LReportPath_Full); - $TestResults{$LName}{"v1"} = $LV1; - $TestResults{$LName}{"v2"} = $LV2; - $TestResults{$LName}{"path"} = $LReportPath; - } - } - my $SONAME_Title = "SONAME"; - if($OStarget eq "windows") { - $SONAME_Title = "DLL"; - } - elsif($OStarget eq "symbian") { - $SONAME_Title = "DSO"; - } - if($GroupByHeaders) - { # show the list of headers - $SONAME_Title = "Header File"; - } - my $SYS_REPORT = "<h1>Binary compatibility between <span style='color:Blue;'>$SystemName1</span> and <span style='color:Blue;'>$SystemName2</span> on <span style='color:Blue;'>".showArch($ArchName)."</span></h1>\n"; - # legend - $SYS_REPORT .= "<table> - <tr><td class='new' width='80px'>Added</td><td class='passed' width='80px'>Compatible</td></tr> - <tr><td class='warning'>Warning</td><td class='failed'>Incompatible</td></tr> - </table>"; - $SYS_REPORT .= "<table class='wikitable'> - <tr><th rowspan='2'>$SONAME_Title<sup>".(keys(%TestResults) + keys(%Added) + keys(%Removed) - keys(%SONAME_Changed))."</sup></th>"; - if(not $GroupByHeaders) { - $SYS_REPORT .= "<th colspan='2'>VERSION</th>"; - } - $SYS_REPORT .= "<th rowspan='2'>Compatibility</th> - <th rowspan='2'>Added<br/>Symbols</th> - <th rowspan='2'>Removed<br/>Symbols</th> - <th colspan='3' style='white-space:nowrap;'>API Changes / Compatibility Problems</th></tr>"; - if(not $GroupByHeaders) { - $SYS_REPORT .= "<tr><th>$SystemName1</th><th>$SystemName2</th>"; - } - $SYS_REPORT .= "<th class='severity'>High</th><th class='severity'>Medium</th><th class='severity'>Low</th></tr>\n"; - my %RegisteredPairs = (); - foreach my $LName (sort {lc($a) cmp lc($b)} (keys(%TestResults), keys(%Added), keys(%Removed))) - { - next if($SONAME_Changed{$LName}); - my $CompatReport = $TestResults{$LName}{"path"}; - my $Anchor = $LName; - $Anchor=~s/\+/p/g;# anchors to libFLAC++ is libFLACpp - $Anchor=~s/\~//g;# libqttracker.so.1~6 - $SYS_REPORT .= "<tr>\n<td class='left'>$LName<a name=\'$Anchor\'></a></td>\n"; - if(defined $Removed{$LName}) { - $SYS_REPORT .= "<td class='failed'>".$Removed{$LName}{"version"}."</td>\n"; - } - elsif(defined $Added{$LName}) { - $SYS_REPORT .= "<td class='new'><a href='".$Added{$LName}{"list"}."'>added</a></td>\n"; - } - elsif(not $GroupByHeaders) { - $SYS_REPORT .= "<td>".$TestResults{$LName}{"v1"}."</td>\n"; - } - if(defined $Added{$LName}) - { # added library - $SYS_REPORT .= "<td class='new'>".$Added{$LName}{"version"}."</td>\n"; - $SYS_REPORT .= "<td class='passed'>100%</td>\n"; - if($RegisteredPairs{$LName}) { - # do nothing - } - elsif(my $To = $ChangedSoname{$LName}) - { - $RegisteredPairs{$To}=1; - $SYS_REPORT .= "<td colspan='5' rowspan='2'>SONAME has <a href='".$TestResults{parse_libname($LName, "name+ext", $OStarget)}{"path"}."'>changed</a></td>\n"; - } - else { - foreach (1 .. 5) { - $SYS_REPORT .= "<td>n/a</td>\n"; # colspan='5' - } - } - $SYS_REPORT .= "</tr>\n"; - next; - } - elsif(defined $Removed{$LName}) - { # removed library - $SYS_REPORT .= "<td class='failed'><a href='".$Removed{$LName}{"list"}."'>removed</a></td>\n"; - $SYS_REPORT .= "<td class='failed'>0%</td>\n"; - if($RegisteredPairs{$LName}) { - # do nothing - } - elsif(my $To = $ChangedSoname{$LName}) - { - $RegisteredPairs{$To}=1; - $SYS_REPORT .= "<td colspan='5' rowspan='2'>SONAME has <a href='".$TestResults{parse_libname($LName, "name+ext", $OStarget)}{"path"}."'>changed</a></td>\n"; - } - else { - foreach (1 .. 5) { - $SYS_REPORT .= "<td>n/a</td>\n"; # colspan='5' - } - } - $SYS_REPORT .= "</tr>\n"; - next; - } - elsif(not $GroupByHeaders) { - $SYS_REPORT .= "<td>".$TestResults{$LName}{"v2"}."</td>\n"; - } - if($TestResults{$LName}{"verdict"} eq "compatible") { - $SYS_REPORT .= "<td class='passed'><a href=\'$CompatReport\'>100%</a></td>\n"; - } - else - { - my $Compatible = 100 - $TestResults{$LName}{"affected"}; - $SYS_REPORT .= "<td class='failed'><a href=\'$CompatReport\'>$Compatible%</a></td>\n"; - } - my $AddedSym=""; - if(my $Count = $TestResults{$LName}{"added"}) { - $AddedSym="<a href='$CompatReport\#Added'>$Count new</a>"; - } - if($AddedSym) { - $SYS_REPORT.="<td class='new'>$AddedSym</td>"; - } - else { - $SYS_REPORT.="<td class='passed'>0</td>"; - } - my $RemovedSym=""; - if(my $Count = $TestResults{$LName}{"removed"}) { - $RemovedSym="<a href='$CompatReport\#Removed'>$Count removed</a>"; - } - if($RemovedSym) { - $SYS_REPORT.="<td class='failed'>$RemovedSym</td>"; - } - else { - $SYS_REPORT.="<td class='passed'>0</td>"; - } - my $High=""; - if(my $Count = $TestResults{$LName}{"type_problems_high"}+$TestResults{$LName}{"interface_problems_high"}) { - $High="<a href='$CompatReport\#High_Risk_Problems'>".problem_title($Count)."</a>"; - } - if($High) { - $SYS_REPORT.="<td class='failed'>$High</td>"; - } - else { - $SYS_REPORT.="<td class='passed'>0</td>"; - } - my $Medium=""; - if(my $Count = $TestResults{$LName}{"type_problems_medium"}+$TestResults{$LName}{"interface_problems_medium"}) { - $Medium="<a href='$CompatReport\#Medium_Risk_Problems'>".problem_title($Count)."</a>"; - } - if($Medium) { - $SYS_REPORT.="<td class='failed'>$Medium</td>"; - } - else { - $SYS_REPORT.="<td class='passed'>0</td>"; - } - my $Low=""; - if(my $Count = $TestResults{$LName}{"type_problems_low"}+$TestResults{$LName}{"interface_problems_low"}+$TestResults{$LName}{"changed_constants"}) { - $Low="<a href='$CompatReport\#Low_Risk_Problems'>".warning_title($Count)."</a>"; - } - if($Low) { - $SYS_REPORT.="<td class='warning'>$Low</td>"; - } - else { - $SYS_REPORT.="<td class='passed'>0</td>"; - } - $SYS_REPORT .= "</tr>\n"; - } - my @META_DATA = (); - my %Stat = ( - "total"=>int(keys(%TestResults)), - "added"=>int(keys(%Added)), - "removed"=>int(keys(%Removed)) - ); - foreach ("added", "removed") - { - my $Kind = $_."_interfaces"; - foreach my $LName (keys(%TestResults)) { - $Stat{$Kind} += $TestResults{$LName}{$_}; - } - push(@META_DATA, $Kind.":".$Stat{$Kind}); - } - foreach my $T ("type", "interface") - { - foreach my $S ("high", "medium", "low") - { - my $Kind = $T."_problems_".$S; - foreach my $LName (keys(%TestResults)) { - $Stat{$Kind} += $TestResults{$LName}{$Kind}; - } - push(@META_DATA, $Kind.":".$Stat{$Kind}); - } - } - foreach my $LName (keys(%TestResults)) - { - foreach ("affected", "changed_constants") { - $Stat{$_} += $TestResults{$LName}{$_}; - } - if(not defined $Stat{"verdict"} - and $TestResults{$LName}{"verdict"} eq "incompatible") { - $Stat{"verdict"} = "incompatible"; - } - } - if(not defined $Stat{"verdict"}) { - $Stat{"verdict"} = "compatible"; - } - if($Stat{"total"}) { - $Stat{"affected"} /= $Stat{"total"}; - } - else { - $Stat{"affected"} = 0; - } - $Stat{"affected"} = show_number($Stat{"affected"}); - if($Stat{"verdict"}>1) { - $Stat{"verdict"} = 1; - } - push(@META_DATA, "changed_constants:".$Stat{"changed_constants"}); - push(@META_DATA, "tool_version:".get_dumpversion("perl $0")); - foreach ("removed", "added", "total", "affected", "verdict") { - @META_DATA = ($_.":".$Stat{$_}, @META_DATA); - } - - # bottom header - $SYS_REPORT .= "<tr><th rowspan='2'>$SONAME_Title</th>"; - if(not $GroupByHeaders) { - $SYS_REPORT .= "<th>$SystemName1</th><th>$SystemName2</th>"; - } - $SYS_REPORT .= "<th rowspan='2'>Compatibility</th> - <th rowspan='2'>Added<br/>Symbols</th> - <th rowspan='2'>Removed<br/>Symbols</th> - <th class='severity'>High</th><th class='severity'>Medium</th><th class='severity'>Low</th></tr>"; - if(not $GroupByHeaders) { - $SYS_REPORT .= "<tr><th colspan='2'>VERSION</th>"; - } - $SYS_REPORT .= "<th colspan='3' style='white-space:nowrap;'>API Changes / Compatibility Problems</th></tr>\n"; - $SYS_REPORT .= "</table>"; - my $Title = "$SystemName1 to $SystemName2 binary compatibility report"; - my $Keywords = "compatibility, $SystemName1, $SystemName2, API, changes"; - my $Description = "Binary compatibility between $SystemName1 and $SystemName2 on ".showArch($ArchName); - my $Styles = readStyles("CmpSystems.css"); - writeFile($SYS_REPORT_PATH."/abi_compat_report.html", "<!-\- ".join(";", @META_DATA)." -\->\n".composeHTML_Head($Title, $Keywords, $Description, $Styles)."\n<body> - <div>$SYS_REPORT</div> - <br/><br/><br/><hr/> - ".getReportFooter($SystemName2)." - <div style='height:999px;'></div>\n</body></html>"); - printMsg("INFO", "see detailed report:\n $SYS_REPORT_PATH/abi_compat_report.html"); -} - -sub readSystemDescriptor($) -{ - my $Content = $_[0]; - $Content=~s/\/\*(.|\n)+?\*\///g; - $Content=~s/<\!--(.|\n)+?-->//g; - $SysDescriptor{"Name"} = parseTag(\$Content, "name"); - my @Tools = (); - if(not $SysDescriptor{"Name"}) { - exitStatus("Error", "system name is not specified (<name> section)"); - } - foreach my $Path (split(/\s*\n\s*/, parseTag(\$Content, "libs"))) - { # target libs - if(not -e $Path) { - exitStatus("Access_Error", "can't access \'$Path\'"); - } - $Path = get_abs_path($Path); - $SysDescriptor{"Libs"}{clean_path($Path)} = 1; - } - foreach my $Path (split(/\s*\n\s*/, parseTag(\$Content, "search_libs"))) - { # target libs - if(not -d $Path) { - exitStatus("Access_Error", "can't access directory \'$Path\'"); - } - $Path = get_abs_path($Path); - $SysDescriptor{"SearchLibs"}{clean_path($Path)} = 1; - } - foreach my $Path (split(/\s*\n\s*/, parseTag(\$Content, "headers"))) - { - if(not -e $Path) { - exitStatus("Access_Error", "can't access \'$Path\'"); - } - $Path = get_abs_path($Path); - $SysDescriptor{"Headers"}{clean_path($Path)} = 1; - } - foreach my $Path (split(/\s*\n\s*/, parseTag(\$Content, "search_headers"))) - { - if(not -d $Path) { - exitStatus("Access_Error", "can't access directory \'$Path\'"); - } - $Path = get_abs_path($Path); - $SysDescriptor{"SearchHeaders"}{clean_path($Path)} = 1; - } - foreach my $Path (split(/\s*\n\s*/, parseTag(\$Content, "tools"))) - { - if(not -d $Path) { - exitStatus("Access_Error", "can't access directory \'$Path\'"); - } - $Path = get_abs_path($Path); - $Path = clean_path($Path); - $SysDescriptor{"Tools"}{$Path} = 1; - push(@Tools, $Path); - } - foreach my $Path (split(/\s*\n\s*/, parseTag(\$Content, "gcc_options"))) { - $SysDescriptor{"GccOpts"}{clean_path($Path)} = 1; - } - if($SysDescriptor{"CrossPrefix"} = parseTag(\$Content, "cross_prefix")) - { # <cross_prefix> section of XML descriptor - $CrossPrefix = $SysDescriptor{"CrossPrefix"}; - } - elsif($CrossPrefix) - { # -cross-prefix tool option - $SysDescriptor{"CrossPrefix"} = $CrossPrefix; - } - $SysDescriptor{"Defines"} = parseTag(\$Content, "defines"); - if($SysDescriptor{"Image"} = parseTag(\$Content, "image")) - { # <image> - # FIXME: isn't implemented yet - if(not -f $SysDescriptor{"Image"}) { - exitStatus("Access_Error", "can't access \'".$SysDescriptor{"Image"}."\'"); - } - } - return {"Tools"=>\@Tools,"CrossPrefix"=>$CrossPrefix}; -} - -sub readOpts($) -{ - my $S = $_[0]; - $OStarget = $S->{"OStarget"}; - $Debug = $S->{"Debug"}; - $Quiet = $S->{"Quiet"}; - $LogMode = $S->{"LogMode"}; - $CheckHeadersOnly = $S->{"CheckHeadersOnly"}; - - $SystemRoot = $S->{"SystemRoot"}; - $MODULES_DIR = $S->{"MODULES_DIR"}; - $GCC_PATH = $S->{"GCC_PATH"}; - $TargetSysInfo = $S->{"TargetSysInfo"}; - $CrossPrefix = $S->{"CrossPrefix"}; - $TargetLibraryName = $S->{"TargetLibraryName"}; - $CrossGcc = $S->{"CrossGcc"}; - $UseStaticLibs = $S->{"UseStaticLibs"}; - $NoStdInc = $S->{"NoStdInc"}; -} - -sub check_list($$) -{ - my ($Item, $Skip) = @_; - return 0 if(not $Skip); - my @Patterns = @{$Skip}; - foreach my $Pattern (@Patterns) - { - if($Pattern=~s/\*/.*/g) - { # wildcards - if($Item=~/$Pattern/) { - return 1; - } - } - elsif($Pattern=~/[\/\\]/) - { # directory - if($Item=~/\Q$Pattern\E/) { - return 1; - } - } - elsif($Item eq $Pattern - or get_filename($Item) eq $Pattern) - { # by name - return 1; - } - } - return 0; -} - -sub filter_format($) -{ - my $FiltRef = $_[0]; - foreach my $Entry (keys(%{$FiltRef})) - { - foreach my $Filt (@{$FiltRef->{$Entry}}) - { - if($Filt=~/[\/\\]/) { - $Filt = path_format($Filt, $OSgroup); - } - } - } -} - -sub read_sys_descriptor($) -{ - my $Path = $_[0]; - my $Content = readFile($Path); - my %Tags = ( - "headers" => "mf", - "skip_headers" => "mf", - "skip_libs" => "mf", - "include_preamble" => "mf", - "non_self_compiled" => "mf", - "add_include_paths" => "mf", - "gcc_options" => "m", - "skip_symbols" => "m", - "skip_types" => "m", - "ignore_symbols" => "h", - "defines" => "s" - ); - my %DInfo = (); - foreach my $Tag (keys(%Tags)) - { - if(my $TContent = parseTag(\$Content, $Tag)) - { - if($Tags{$Tag}=~/m/) - { # multi-line (+order) - my @Items = split(/\s*\n\s*/, $TContent); - $DInfo{$Tag} = []; - foreach my $Item (@Items) - { - if($Tags{$Tag}=~/f/) { - $Item = path_format($Item, $OSgroup); - } - push(@{$DInfo{$Tag}}, $Item); - } - - } - elsif($Tags{$Tag}=~/s/) - { # single element - $DInfo{$Tag} = $TContent; - } - else - { # hash array - my @Items = split(/\s*\n\s*/, $TContent); - foreach my $Item (@Items) { - $DInfo{$Tag}{$Item}=1; - } - } - } - } - return \%DInfo; -} - -sub read_sys_info($) -{ - my $Target = $_[0]; - my $SYS_INFO_PATH = $MODULES_DIR."/Targets"; - if(-d $SYS_INFO_PATH."/".$Target) - { # symbian, windows - $SYS_INFO_PATH .= "/".$Target; - } - else - { # default - $SYS_INFO_PATH .= "/unix"; - } - if($TargetSysInfo) - { # user-defined target - $SYS_INFO_PATH = $TargetSysInfo; - } - if(not -d $SYS_INFO_PATH) { - exitStatus("Module_Error", "can't access \'$SYS_INFO_PATH\'"); - } - # Library Specific Info - my %SysInfo = (); - if(not -d $SYS_INFO_PATH."/descriptors/") { - exitStatus("Module_Error", "can't access \'$SYS_INFO_PATH/descriptors\'"); - } - foreach my $DPath (cmd_find($SYS_INFO_PATH."/descriptors/","f","",1)) - { - my $LSName = get_filename($DPath); - $LSName=~s/\.xml\Z//; - $SysInfo{$LSName} = read_sys_descriptor($DPath); - } - # Exceptions - if(check_gcc_version($GCC_PATH, "4.4")) - { # exception for libstdc++ - $SysInfo{"libstdc++"}{"gcc_options"} = ["-std=c++0x"]; - } - if($OStarget eq "symbian") - { # exception for libstdcpp - $SysInfo{"libstdcpp"}{"defines"} = "namespace std { struct nothrow_t {}; }"; - } - if($SysDescriptor{"Name"}=~/maemo/i) - { # GL/gl.h: No such file - $SysInfo{"libSDL"}{"skip_headers"}=["SDL_opengl.h"]; - } - if($OStarget eq "linux") { - $SysInfo{"libboost_"}{"headers"} = ["/boost/", "/asio/"]; - } - # Common Info - if(not -f $SYS_INFO_PATH."/common.xml") { - exitStatus("Module_Error", "can't access \'$SYS_INFO_PATH/common.xml\'"); - } - my $SysCInfo = read_sys_descriptor($SYS_INFO_PATH."/common.xml"); - my @CompilerOpts = (); - if($SysDescriptor{"Name"}=~/maemo|meego/i) { - push(@CompilerOpts, "-DMAEMO_CHANGES", "-DM_APPLICATION_NAME=\\\"app\\\""); - } - if(my @Opts = keys(%{$SysDescriptor{"GccOpts"}})) { - push(@CompilerOpts, @Opts); - } - if(@CompilerOpts) - { - if(not $SysCInfo->{"gcc_options"}) { - $SysCInfo->{"gcc_options"} = []; - } - push(@{$SysCInfo->{"gcc_options"}}, @CompilerOpts); - } - foreach my $Name (keys(%SysInfo)) - { # strict headers that should be - # matched for only one library - if($SysInfo{$Name}{"headers"}) { - $SysCInfo->{"sheaders"}{$Name} = $SysInfo{$Name}{"headers"}; - } - } - return (\%SysInfo, $SysCInfo); -} - -sub get_binversion($) -{ - my $Path = $_[0]; - if($OStarget eq "windows" - and $LIB_EXT eq "dll") - { # get version of DLL using "sigcheck" - my $SigcheckCmd = get_CmdPath("sigcheck"); - if(not $SigcheckCmd) { - return ""; - } - my $VInfo = `$SigcheckCmd -n $Path 2>$TMP_DIR/null`; - $VInfo=~s/\s*\(.*\)\s*//; - chomp($VInfo); - return $VInfo; - } - return ""; -} - -sub get_soname($) -{ - my $Path = $_[0]; - return if(not $Path or not -e $Path); - if(defined $Cache{"get_soname"}{$Path}) { - return $Cache{"get_soname"}{$Path}; - } - my $ObjdumpCmd = get_CmdPath("objdump"); - if(not $ObjdumpCmd) { - exitStatus("Not_Found", "can't find \"objdump\""); - } - my $SonameCmd = "$ObjdumpCmd -x $Path 2>$TMP_DIR/null"; - if($OSgroup eq "windows") { - $SonameCmd .= " | find \"SONAME\""; - } - else { - $SonameCmd .= " | grep SONAME"; - } - if(my $SonameInfo = `$SonameCmd`) { - if($SonameInfo=~/SONAME\s+([^\s]+)/) { - return ($Cache{"get_soname"}{$Path} = $1); - } - } - return ($Cache{"get_soname"}{$Path}=""); -} - -sub dumpSystem($) -{ # -dump-system option handler - # should be used with -sysroot and -cross-gcc options - my $Opts = $_[0]; - readOpts($Opts); - my $SYS_DUMP_PATH = "sys_dumps/".$SysDescriptor{"Name"}."/".getArch(1); - if(not $TargetLibraryName) { - rmtree($SYS_DUMP_PATH); - } - my (@SystemLibs, @SysHeaders) = (); - foreach my $Path (keys(%{$SysDescriptor{"Libs"}})) - { - if(not -e $Path) { - exitStatus("Access_Error", "can't access \'$Path\'"); - } - if(-d $Path) - { - if(my @SubLibs = find_libs($Path,"",1)) { - push(@SystemLibs, @SubLibs); - } - $SysDescriptor{"SearchLibs"}{$Path}=1; - } - else - { # single file - push(@SystemLibs, $Path); - $SysDescriptor{"SearchLibs"}{get_dirname($Path)}=1; - } - } - foreach my $Path (keys(%{$SysDescriptor{"Headers"}})) - { - if(not -e $Path) { - exitStatus("Access_Error", "can't access \'$Path\'"); - } - if(-d $Path) - { - if(my @SubHeaders = cmd_find($Path,"f","","")) { - push(@SysHeaders, @SubHeaders); - } - $SysDescriptor{"SearchHeaders"}{$Path}=1; - } - else - { # single file - push(@SysHeaders, $Path); - $SysDescriptor{"SearchHeaders"}{get_dirname($Path)}=1; - } - } - my $GroupByHeaders = 0; - if($CheckHeadersOnly) - { # -headers-only - $GroupByHeaders = 1; - # @SysHeaders = optimize_set(@SysHeaders); - } - elsif($SysDescriptor{"Image"}) - { # one big image - $GroupByHeaders = 1; - @SystemLibs = ($SysDescriptor{"Image"}); - } - writeFile($SYS_DUMP_PATH."/target.txt", $OStarget); - my (%SysLib_Symbols, %SymbolGroup, %Symbol_SysHeaders, - %SysHeader_Symbols, %SysLib_SysHeaders, %MatchByName) = (); - my (%Skipped, %Failed, %Success) = (); - my (%SysHeaderDir_SysLibs, %SysHeaderDir_SysHeaders) = (); - my (%LibPrefixes, %SymbolCounter, %TotalLibs) = (); - my %Glibc = map {$_=>1} ( - "libc", - "libpthread" - ); - my ($SysInfo, $SysCInfo) = read_sys_info($OStarget); - if(not $GroupByHeaders) { - printMsg("INFO", "Indexing sonames ..."); - } - my (%LibSoname, %SysLibVersion) = (); - my %DevelPaths = map {$_=>1} @SystemLibs; - foreach my $Path (sort keys(%{$SysDescriptor{"SearchLibs"}})) { - foreach my $LPath (find_libs($Path,"",1)) { - $DevelPaths{$LPath}=1; - } - } - foreach my $LPath (keys(%DevelPaths)) - { # register SONAMEs - my $LName = get_filename($LPath); - my $LRelPath = cut_path_prefix($LPath, $SystemRoot); - if(not is_target_lib($LName)) { - next; - } - if($OSgroup=~/\A(linux|macos|freebsd)\Z/ - and $LName!~/\Alib/) { - next; - } - if(my $Soname = get_soname($LPath)) - { - if($OStarget eq "symbian") - { - if($Soname=~/[\/\\]/) - { # L://epoc32/release/armv5/lib/gfxtrans{000a0000}.dso - $Soname = get_filename($Soname); - } - $Soname = lc($Soname); - } - if(not defined $LibSoname{$LName}) { - $LibSoname{$LName}=$Soname; - } - if(-l $LPath and my $Path = resolve_symlink($LPath)) - { - my $Name = get_filename($Path); - if(not defined $LibSoname{$Name}) { - $LibSoname{$Name}=$Soname; - } - } - } - else - { # windows and others - $LibSoname{$LName}=$LName; - } - } - my $SONAMES = ""; - foreach (sort {lc($a) cmp lc($b)} keys(%LibSoname)) { - $SONAMES .= $_.";".$LibSoname{$_}."\n"; - } - if(not $GroupByHeaders) { - writeFile($SYS_DUMP_PATH."/sonames.txt", $SONAMES); - } - foreach my $LPath (sort keys(%DevelPaths)) - {# register VERSIONs - my $LName = get_filename($LPath); - if(not is_target_lib($LName) - and not is_target_lib($LibSoname{$LName})) { - next; - } - if(my $V = get_binversion($LPath)) - { # binary version - $SysLibVersion{$LName} = $V; - } - elsif(my $V = parse_libname($LName, "version", $OStarget)) - { # source version - $SysLibVersion{$LName} = $V; - } - elsif($LName=~/([\d\.\-\_]+)\.$LIB_EXT\Z/) - { # libfreebl3.so - if($1 ne 32 and $1 ne 64) { - $SysLibVersion{$LName} = $1; - } - } - } - my $VERSIONS = ""; - foreach (sort {lc($a) cmp lc($b)} keys(%SysLibVersion)) { - $VERSIONS .= $_.";".$SysLibVersion{$_}."\n"; - } - if(not $GroupByHeaders) { - writeFile($SYS_DUMP_PATH."/versions.txt", $VERSIONS); - } - my %SysLibs = (); - foreach my $LPath (sort @SystemLibs) - { - my $LName = get_filename($LPath); - my $LSName = parse_libname($LName, "short", $OStarget); - my $LRelPath = cut_path_prefix($LPath, $SystemRoot); - if(not is_target_lib($LName)) { - next; - } - if($OSgroup=~/\A(linux|macos|freebsd)\Z/ - and $LName!~/\Alib/) { - next; - } - if($OStarget eq "symbian") - { - if(my $V = parse_libname($LName, "version", $OStarget)) - { # skip qtcore.dso - # register qtcore{00040604}.dso - delete($SysLibs{get_dirname($LPath)."\\".$LSName.".".$LIB_EXT}); - my $MV = parse_libname($LibSoname{$LSName.".".$LIB_EXT}, "version", $OStarget); - if($MV and $V ne $MV) - { # skip other versions: - # qtcore{00040700}.dso - # qtcore{00040702}.dso - next; - } - } - } - if(my $Skip = $SysCInfo->{"skip_libs"}) - { # do NOT check some libs - if(check_list($LRelPath, $Skip)) { - next; - } - } - if(-l $LPath) - { # symlinks - if(my $Path = resolve_symlink($LPath)) { - $SysLibs{$Path} = 1; - } - } - elsif(-f $LPath) - { - if($Glibc{$LSName} - and cmd_file($LPath)=~/ASCII/) - {# GNU ld scripts (libc.so, libpthread.so) - my @Candidates = cmd_find($SystemRoot."/lib","",$LSName.".".$LIB_EXT."*","1"); - if(@Candidates) - { - my $Candidate = $Candidates[0]; - if(-l $Candidate - and my $Path = resolve_symlink($Candidate)) { - $Candidate = $Path; - } - $SysLibs{$Candidate} = 1; - } - } - else { - $SysLibs{$LPath} = 1; - } - } - } - @SystemLibs = ();# clear memory - if(not $CheckHeadersOnly) - { - if($SysDescriptor{"Image"}) { - printMsg("INFO", "Reading symbols from image ..."); - } - else { - printMsg("INFO", "Reading symbols from libraries ..."); - } - } - foreach my $LPath (sort keys(%SysLibs)) - { - my $LRelPath = cut_path_prefix($LPath, $SystemRoot); - my $LName = get_filename($LPath); - my $Library_Symbol = getSymbols_Lib(1, $LPath, 0, (), "-Weak"); - my @AllSymbols = keys(%{$Library_Symbol->{$LName}}); - my $tr_name = translateSymbols(@AllSymbols, 1); - foreach my $Symbol (@AllSymbols) - { - $Symbol=~s/[\@\$]+(.*)\Z//g; - if($Symbol=~/\A(_Z|\?)/) - { - if(skipGlobalData($Symbol)) { - next; - } - if($Symbol=~/(C1|C2|D0|D1|D2)E/) - { # do NOT analyze constructors - # and destructors - next; - } - my $Unmangled = $tr_name->{$Symbol}; - $Unmangled=~s/<.+>//g; - if($Unmangled=~/\A([\w:]+)/) - { # cut out the parameters - my @Elems = split(/::/, $1); - my ($Class, $Short) = (); - $Short = $Elems[$#Elems]; - if($#Elems>=1) { - $Class = $Elems[$#Elems-1]; - pop(@Elems); - } - # the short and class name should be - # matched in one header file - $SymbolGroup{$LRelPath}{$Class} = $Short; - foreach my $Sym (@Elems) - { - if($SysCInfo->{"ignore_symbols"}{$Symbol}) - { # do NOT match this symbol - next; - } - $SysLib_Symbols{$LPath}{$Sym}=1; - if(my $Prefix = getPrefix($Sym)) { - $LibPrefixes{$Prefix}{$LName}+=1; - } - $SymbolCounter{$Sym}{$LName}=1; - } - } - } - else - { - if($SysCInfo->{"ignore_symbols"}{$Symbol}) - { # do NOT match this symbol - next; - } - $SysLib_Symbols{$LPath}{$Symbol}=1; - if(my $Prefix = getPrefix($Symbol)) { - $LibPrefixes{$Prefix}{$LName}+=1; - } - $SymbolCounter{$Symbol}{$LName}=1; - } - } - } - if(not $CheckHeadersOnly) { - writeFile($SYS_DUMP_PATH."/symbols.txt", Dumper(\%SysLib_Symbols)); - } - my (%DupLibs, %VersionedLibs) = (); - foreach my $LPath1 (sort keys(%SysLib_Symbols)) - { # match duplicated libs - # libmenu contains all symbols from libmenuw - my $SName = parse_libname(get_filename($LPath1), "shortest", $OStarget); - foreach my $LPath2 (sort keys(%SysLib_Symbols)) - { - next if($LPath1 eq $LPath2); - if($SName eq parse_libname(get_filename($LPath2), "shortest", $OStarget)) - { # libpython-X.Y - $VersionedLibs{$LPath1}{$LPath2}=1; - next; - } - my $Duplicate=1; - foreach (keys(%{$SysLib_Symbols{$LPath1}})) - { - if(not defined $SysLib_Symbols{$LPath2}{$_}) { - $Duplicate=0; - last; - } - } - if($Duplicate) { - $DupLibs{$LPath1}{$LPath2}=1; - } - } - } - foreach my $Prefix (keys(%LibPrefixes)) - { - my @Libs = keys(%{$LibPrefixes{$Prefix}}); - @Libs = sort {$LibPrefixes{$Prefix}{$b}<=>$LibPrefixes{$Prefix}{$a}} @Libs; - $LibPrefixes{$Prefix}=$Libs[0]; - } - printMsg("INFO", "Reading symbols from headers ..."); - foreach my $HPath (@SysHeaders) - { - $HPath = path_format($HPath, $OSgroup); - my $HRelPath = cut_path_prefix($HPath, $SystemRoot); - my ($HDir, $HName) = separate_path($HRelPath); - if(is_not_header($HName)) - { # have a wrong extension: .gch, .in - next; - } - if($HName=~/~\Z/) - { # reserved copy - next; - } - if($HRelPath=~/[\/\\]_gen/) - { # telepathy-1.0/telepathy-glib/_gen - # telepathy-1.0/libtelepathy/_gen-tp-constants-deprecated.h - next; - } - if($HRelPath=~/include[\/\\]linux[\/\\]/) - { # kernel-space headers - next; - } - if($HRelPath=~/include[\/\\]asm[\/\\]/) - { # asm headers - next; - } - if($HRelPath=~/[\/\\]microb-engine[\/\\]/) - { # MicroB engine (Maemo 4) - next; - } - if($HRelPath=~/\Wprivate(\W|\Z)/) - { # private directories (include/tcl-private, ...) - next; - } - my $Content = readFile($HPath); - $Content=~s/\/\*(.|\n)+?\*\///g; - $Content=~s/\/\/.*?\n//g;# remove comments - $Content=~s/#\s*define[^\n\\]*(\\\n[^\n\\]*)+\n*//g;# remove defines - $Content=~s/#[^\n]*?\n//g;# remove directives - $Content=~s/(\A|\n)class\s+\w+;\n//g;# remove forward declarations - # FIXME: try to add preprocessing stage - foreach my $Symbol (split(/\W+/, $Content)) - { - $Symbol_SysHeaders{$Symbol}{$HRelPath} = 1; - $SysHeader_Symbols{$HRelPath}{$Symbol} = 1; - } - $SysHeaderDir_SysHeaders{$HDir}{$HName} = 1; - my $HShort = $HName; - $HShort=~s/\.\w+\Z//g; - if($HShort=~/\Alib/) { - $MatchByName{$HShort} = $HRelPath; - } - elsif(get_filename(get_dirname($HRelPath))=~/\Alib(.+)\Z/) - { # libical/ical.h - if($HShort=~/\Q$1\E/) { - $MatchByName{"lib".$HShort} = $HRelPath; - } - } - elsif($OStarget eq "windows" - and $HShort=~/api\Z/) { - $MatchByName{$HShort} = $HRelPath; - } - } - my %SkipDHeaders = ( - # header files, that should be in the <skip_headers> section - # but should be matched in the algorithm - # MeeGo 1.2 Harmattan - "libtelepathy-qt4" => ["TelepathyQt4/_gen", "client.h", - "TelepathyQt4/*-*", "debug.h", "global.h", - "properties.h", "Channel", "channel.h", "message.h"], - ); - filter_format(\%SkipDHeaders); - if(not $GroupByHeaders) { - printMsg("INFO", "Matching symbols ..."); - } - foreach my $LPath (sort keys(%SysLibs)) - { # matching - my $LName = get_filename($LPath); - my $LNameSE = parse_libname($LName, "name+ext", $OStarget); - my $LRelPath = cut_path_prefix($LPath, $SystemRoot); - my $LSName = parse_libname($LName, "short", $OStarget); - my $SName = parse_libname($LName, "shortest", $OStarget); - if($LRelPath=~/\/debug\//) - { # debug libs - $Skipped{$LRelPath}=1; - next; - } - $TotalLibs{$LRelPath}=1; - $SysLib_SysHeaders{$LRelPath} = (); - if(keys(%{$SysLib_Symbols{$LPath}})) - { # try to match by name of the header - if(my $Path = $MatchByName{$LSName}) { - $SysLib_SysHeaders{$LRelPath}{$Path}="exact match ($LSName)"; - } - if(length($SName)>=3 - and my $Path = $MatchByName{"lib".$SName}) { - $SysLib_SysHeaders{$LRelPath}{$Path}="exact match (lib$SName)"; - } - } - my (%SymbolDirs, %SymbolFiles) = (); - foreach my $Symbol (sort {length($b) cmp length($a)} - sort keys(%{$SysLib_Symbols{$LPath}})) - { - if($SysCInfo->{"ignore_symbols"}{$Symbol}) { - next; - } - if(not $DupLibs{$LPath} - and not $VersionedLibs{$LPath} - and keys(%{$SymbolCounter{$Symbol}})>=2 - and my $Prefix = getPrefix($Symbol)) - { # duplicated symbols - if($LibPrefixes{$Prefix} - and $LibPrefixes{$Prefix} ne $LName - and not $Glibc{$LSName}) { - next; - } - } - if(length($Symbol)<=2) { - next; - } - if($Symbol!~/[A-Z_0-9]/ - and length($Symbol)<10 - and keys(%{$Symbol_SysHeaders{$Symbol}})>=3) - { # undistinguished symbols - # FIXME: improve this filter - # signalfd (libc.so) - # regcomp (libpcreposix.so) - next; - } - if($Symbol=~/\A(_M_|_Rb_|_S_)/) - { # _M_insert, _Rb_tree, _S_destroy_c_locale - next; - } - if($Symbol=~/\A[A-Z][a-z]+\Z/) - { # Clone, Initialize, Skip, Unlock, Terminate, Chunk - next; - } - if($Symbol=~/\A[A-Z][A-Z]\Z/) - { # BC, PC, UP, SP - next; - } - if($Symbol=~/_t\Z/) - { # pthread_mutex_t, wchar_t - next; - } - my @SymHeaders = keys(%{$Symbol_SysHeaders{$Symbol}}); - @SymHeaders = sort {lc($a) cmp lc($b)} @SymHeaders;# sort by name - @SymHeaders = sort {length(get_dirname($a))<=>length(get_dirname($b))} @SymHeaders;# sort by length - if(length($SName)>=3) - { # sort candidate headers by name - @SymHeaders = sort {$b=~/\Q$SName\E/i<=>$a=~/\Q$SName\E/i} @SymHeaders; - } - else - { # libz, libX11 - @SymHeaders = sort {$b=~/lib\Q$SName\E/i<=>$a=~/lib\Q$SName\E/i} @SymHeaders; - @SymHeaders = sort {$b=~/\Q$SName\Elib/i<=>$a=~/\Q$SName\Elib/i} @SymHeaders; - } - @SymHeaders = sort {$b=~/\Q$LSName\E/i<=>$a=~/\Q$LSName\E/i} @SymHeaders; - @SymHeaders = sort {$SymbolDirs{get_dirname($b)}<=>$SymbolDirs{get_dirname($a)}} @SymHeaders; - @SymHeaders = sort {$SymbolFiles{get_filename($b)}<=>$SymbolFiles{get_filename($a)}} @SymHeaders; - foreach my $HRelPath (@SymHeaders) - { - if(my $Group = $SymbolGroup{$LRelPath}{$Symbol}) { - if(not $SysHeader_Symbols{$HRelPath}{$Group}) { - next; - } - } - if(my $Search = $SysInfo->{$LSName}{"headers"}) - { # search for specified headers - if(not check_list($HRelPath, $Search)) { - next; - } - } - if(my $Skip = $SysInfo->{$LSName}{"skip_headers"}) - { # do NOT search for some headers - if(check_list($HRelPath, $Skip)) { - next; - } - } - if(my $Skip = $SysCInfo->{"skip_headers"}) - { # do NOT search for some headers - if(check_list($HRelPath, $Skip)) { - next; - } - } - if(my $Skip = $SysInfo->{$LSName}{"non_self_compiled"}) - { # do NOT search for some headers - if(check_list($HRelPath, $Skip)) { - $SymbolDirs{get_dirname($HRelPath)}+=1; - $SymbolFiles{get_filename($HRelPath)}+=1; - next; - } - } - my $Continue = 1; - foreach my $Name (keys(%{$SysCInfo->{"sheaders"}})) - { - if($LSName!~/\Q$Name\E/ - and check_list($HRelPath, $SysCInfo->{"sheaders"}{$Name})) - { # restriction to search for C++ or Boost headers - # in the boost/ and c++/ directories only - $Continue=0; - last; - } - } - if(not $Continue) { - next; - } - $SysLib_SysHeaders{$LRelPath}{$HRelPath}=$Symbol; - $SysHeaderDir_SysLibs{get_dirname($HRelPath)}{$LNameSE}=1; - $SysHeaderDir_SysLibs{get_dirname(get_dirname($HRelPath))}{$LNameSE}=1; - $SymbolDirs{get_dirname($HRelPath)}+=1; - $SymbolFiles{get_filename($HRelPath)}+=1; - last;# select one header for one symbol - } - } - if(keys(%{$SysLib_SysHeaders{$LRelPath}})) { - $Success{$LRelPath}=1; - } - else { - $Failed{$LRelPath}=1; - } - } - if(not $GroupByHeaders) - { # matching results - writeFile($SYS_DUMP_PATH."/match.txt", Dumper(\%SysLib_SysHeaders)); - writeFile($SYS_DUMP_PATH."/skipped.txt", join("\n", sort keys(%Skipped))); - writeFile($SYS_DUMP_PATH."/failed.txt", join("\n", sort keys(%Failed))); - } - (%SysLib_Symbols, %SymbolGroup, %Symbol_SysHeaders, %SysHeader_Symbols) = ();# free memory - if($GroupByHeaders) - { - if($SysDescriptor{"Image"} and not $CheckHeadersOnly) { - @SysHeaders = keys(%{$SysLib_SysHeaders{$SysDescriptor{"Image"}}}); - } - %SysLib_SysHeaders = (); - foreach my $Path (@SysHeaders) - { - if(my $Skip = $SysCInfo->{"skip_headers"}) - { # do NOT search for some headers - if(check_list($Path, $Skip)) { - next; - } - } - $SysLib_SysHeaders{$Path}{$Path} = 1; - } - if($CheckHeadersOnly) { - writeFile($SYS_DUMP_PATH."/mode.txt", "headers-only"); - } - else { - writeFile($SYS_DUMP_PATH."/mode.txt", "group-by-headers"); - } - } - @SysHeaders = ();# clear memory - my (%Skipped, %Failed, %Success) = (); - printMsg("INFO", "Generating XML descriptors ..."); - foreach my $LRelPath (keys(%SysLib_SysHeaders)) - { - my $LName = get_filename($LRelPath); - my $DPath = $SYS_DUMP_PATH."/descriptors/$LName.xml"; - unlink($DPath); - if(my @LibHeaders = keys(%{$SysLib_SysHeaders{$LRelPath}})) - { - my $LSName = parse_libname($LName, "short", $OStarget); - if($GroupByHeaders) - { # header short name - $LSName = $LName; - $LSName=~s/\.(.+?)\Z//; - } - my (%DirsHeaders, %Includes) = (); - foreach my $HRelPath (@LibHeaders) { - $DirsHeaders{get_dirname($HRelPath)}{$HRelPath}=1; - } - foreach my $Dir (keys(%DirsHeaders)) - { - my $DirPart = 0; - my $TotalHeaders = keys(%{$SysHeaderDir_SysHeaders{$Dir}}); - if($TotalHeaders) { - $DirPart = (keys(%{$DirsHeaders{$Dir}})*100)/$TotalHeaders; - } - my $Neighbourhoods = keys(%{$SysHeaderDir_SysLibs{$Dir}}); - if($Neighbourhoods==1) - { # one lib in this directory - if(get_filename($Dir) ne "include" - and $DirPart>=5) - { # complete directory - $Includes{$Dir} = 1; - } - else - { # list of headers - @Includes{keys(%{$DirsHeaders{$Dir}})}=values(%{$DirsHeaders{$Dir}}); - } - } - elsif((keys(%{$DirsHeaders{$Dir}})*100)/($#LibHeaders+1)>5) - {# remove 5% divergence - if(get_filename($Dir) ne "include" - and $DirPart>=50) - { # complete directory - $Includes{$Dir} = 1; - } - else - { # list of headers - @Includes{keys(%{$DirsHeaders{$Dir}})}=values(%{$DirsHeaders{$Dir}}); - } - } - } - if($GroupByHeaders) - { # one header in one ABI dump - %Includes = ($LibHeaders[0] => 1); - } - my $LVersion = $SysLibVersion{$LName}; - if($LVersion) - {# append by system name - $LVersion .= "-".$SysDescriptor{"Name"}; - } - else { - $LVersion = $SysDescriptor{"Name"}; - } - my @Content = ("<version>\n $LVersion\n</version>"); - my @IncHeaders = sort {natural_sorting($a, $b)} keys(%Includes); - sort_by_word(\@IncHeaders, parse_libname($LName, "shortest", $OStarget)); - if(is_abs($IncHeaders[0])) { - push(@Content, "<headers>\n ".join("\n ", @IncHeaders)."\n</headers>"); - } - else { - push(@Content, "<headers>\n {RELPATH}/".join("\n {RELPATH}/", @IncHeaders)."\n</headers>"); - } - if($GroupByHeaders) - { - if($SysDescriptor{"Image"}) { - push(@Content, "<libs>\n ".$SysDescriptor{"Image"}."\n</libs>"); - } - } - else - { - if(is_abs($LRelPath) or -f $LRelPath) { - push(@Content, "<libs>\n $LRelPath\n</libs>"); - } - else { - push(@Content, "<libs>\n {RELPATH}/$LRelPath\n</libs>"); - } - } - if(my @SearchHeaders = keys(%{$SysDescriptor{"SearchHeaders"}})) { - push(@Content, "<search_headers>\n ".join("\n ", @SearchHeaders)."\n</search_headers>"); - } - if(my @SearchLibs = keys(%{$SysDescriptor{"SearchLibs"}})) { - push(@Content, "<search_libs>\n ".join("\n ", @SearchLibs)."\n</search_libs>"); - } - if(my @Tools = keys(%{$SysDescriptor{"Tools"}})) { - push(@Content, "<tools>\n ".join("\n ", @Tools)."\n</tools>"); - } - my @Skip = (); - if($SysInfo->{$LSName}{"skip_headers"}) { - @Skip = (@Skip, @{$SysInfo->{$LSName}{"skip_headers"}}); - } - if($SysCInfo->{"skip_headers"}) { - @Skip = (@Skip, @{$SysCInfo->{"skip_headers"}}); - } - if($SysInfo->{$LSName}{"non_self_compiled"}) { - @Skip = (@Skip, @{$SysInfo->{$LSName}{"non_self_compiled"}}); - } - if($SkipDHeaders{$LSName}) { - @Skip = (@Skip, @{$SkipDHeaders{$LSName}}); - } - if(@Skip) { - push(@Content, "<skip_headers>\n ".join("\n ", @Skip)."\n</skip_headers>"); - } - if($SysInfo->{$LSName}{"add_include_paths"}) { - push(@Content, "<add_include_paths>\n ".join("\n ", @{$SysInfo->{$LSName}{"add_include_paths"}})."\n</add_include_paths>"); - } - if($SysInfo->{$LSName}{"skip_types"}) { - push(@Content, "<skip_types>\n ".join("\n ", @{$SysInfo->{$LSName}{"skip_types"}})."\n</skip_types>"); - } - my @SkipSymb = (); - if($SysInfo->{$LSName}{"skip_symbols"}) { - push(@SkipSymb, @{$SysInfo->{$LSName}{"skip_symbols"}}); - } - if($SysCInfo->{"skip_symbols"}) { - push(@SkipSymb, @{$SysCInfo->{"skip_symbols"}}); - } - if(@SkipSymb) { - push(@Content, "<skip_symbols>\n ".join("\n ", @SkipSymb)."\n</skip_symbols>"); - } - my @Preamble = (); - if($SysCInfo->{"include_preamble"}) { - push(@Preamble, @{$SysCInfo->{"include_preamble"}}); - } - if($LSName=~/\AlibX\w+\Z/) - { # add Xlib.h for libXt, libXaw, libXext and others - push(@Preamble, "Xlib.h", "X11/Intrinsic.h"); - } - if($SysInfo->{$LSName}{"include_preamble"}) { - push(@Preamble, @{$SysInfo->{$LSName}{"include_preamble"}}); - } - if(@Preamble) { - push(@Content, "<include_preamble>\n ".join("\n ", @Preamble)."\n</include_preamble>"); - } - my @Defines = (); - if($SysCInfo->{"defines"}) { - push(@Defines, $SysCInfo->{"defines"}); - } - if($SysInfo->{$LSName}{"defines"}) { - push(@Defines, $SysInfo->{$LSName}{"defines"}); - } - if($SysDescriptor{"Defines"}) { - push(@Defines, $SysDescriptor{"Defines"}); - } - if(@Defines) { - push(@Content, "<defines>\n ".join("\n ", @Defines)."\n</defines>"); - } - my @CompilerOpts = (); - if($SysCInfo->{"gcc_options"}) { - push(@CompilerOpts, @{$SysCInfo->{"gcc_options"}}); - } - if($SysInfo->{$LSName}{"gcc_options"}) { - push(@CompilerOpts, @{$SysInfo->{$LSName}{"gcc_options"}}); - } - if(@CompilerOpts) { - push(@Content, "<gcc_options>\n ".join("\n ", @CompilerOpts)."\n</gcc_options>"); - } - if($SysDescriptor{"CrossPrefix"}) { - push(@Content, "<cross_prefix>\n ".$SysDescriptor{"CrossPrefix"}."\n</cross_prefix>"); - } - writeFile($DPath, join("\n\n", @Content)); - $Success{$LRelPath}=1; - } - } - printMsg("INFO", "Dumping ABIs:"); - my %DumpSuccess = (); - my @Descriptors = cmd_find($SYS_DUMP_PATH."/descriptors","f","*.xml","1"); - foreach my $DPath (sort {lc($a) cmp lc($b)} @Descriptors) - { - my $DName = get_filename($DPath); - my $LName = ""; - if($DName=~/\A(.+).xml\Z/) { - $LName = $1; - } - else { - next; - } - if(not is_target_lib($LName) - and not is_target_lib($LibSoname{$LName})) { - next; - } - $DPath = cut_path_prefix($DPath, $ORIG_DIR); - my $ACC_dump = "perl $0"; - if($GroupByHeaders) - { # header name is going here - $ACC_dump .= " -l $LName"; - } - else { - $ACC_dump .= " -l ".parse_libname($LName, "name", $OStarget); - } - $ACC_dump .= " -dump \"$DPath\""; - if($SystemRoot) - { - $ACC_dump .= " -relpath \"$SystemRoot\""; - $ACC_dump .= " -sysroot \"$SystemRoot\""; - } - my $DumpPath = "$SYS_DUMP_PATH/abi_dumps/$LName.abi.".getAR_EXT($OSgroup); - $ACC_dump .= " -dump-path \"$DumpPath\""; - my $LogPath = "$SYS_DUMP_PATH/logs/$LName.txt"; - unlink($LogPath); - $ACC_dump .= " -log-path \"$LogPath\""; - if($CrossGcc) { - $ACC_dump .= " -cross-gcc \"$CrossGcc\""; - } - if($CheckHeadersOnly) { - $ACC_dump .= " -headers-only"; - } - if($UseStaticLibs) { - $ACC_dump .= " -static-libs"; - } - if($GroupByHeaders) { - $ACC_dump .= " -header $LName"; - } - if($NoStdInc - or $OStarget=~/windows|symbian/) - { # 1. user-defined - # 2. windows/minGW - # 3. symbian/GCC - $ACC_dump .= " -nostdinc"; - } - if($Quiet) - { # quiet mode - $ACC_dump .= " -quiet"; - } - if($LogMode eq "n") { - $ACC_dump .= " -logging-mode n"; - } - elsif($Quiet) { - $ACC_dump .= " -logging-mode a"; - } - if($Debug) - { # debug mode - $ACC_dump .= " -debug"; - printMsg("INFO", "$ACC_dump"); - } - printMsg("INFO_C", "Dumping $LName: "); - system($ACC_dump." 1>$TMP_DIR/null 2>$TMP_DIR/$LName.stderr"); - appendFile("$SYS_DUMP_PATH/logs/$LName.txt", "The ACC parameters:\n $ACC_dump\n"); - if(-s "$TMP_DIR/$LName.stderr") - { - appendFile("$SYS_DUMP_PATH/logs/$LName.txt", readFile("$TMP_DIR/$LName.stderr")); - if(get_CoreError($?>>8) eq "Invalid_Dump") { - printMsg("INFO", "Empty"); - } - else { - printMsg("INFO", "Failed (\'$SYS_DUMP_PATH/logs/$LName.txt\')"); - } - } - elsif(not -f $DumpPath) { - printMsg("INFO", "Failed (\'$SYS_DUMP_PATH/logs/$LName.txt\')"); - } - else - { - $DumpSuccess{$LName}=1; - printMsg("INFO", "Ok"); - } - } - if(not $GroupByHeaders) - { # general mode - printMsg("INFO", "Total libraries: ".keys(%TotalLibs)); - printMsg("INFO", "Skipped libraries: ".keys(%Skipped)." ($SYS_DUMP_PATH/skipped.txt)"); - printMsg("INFO", "Failed to find headers: ".keys(%Failed)." ($SYS_DUMP_PATH/failed.txt)"); - } - printMsg("INFO", "Created descriptors: ".keys(%Success)." ($SYS_DUMP_PATH/descriptors/)"); - printMsg("INFO", "Dumped ABIs: ".keys(%DumpSuccess)." ($SYS_DUMP_PATH/abi_dumps/)"); - printMsg("INFO", "The ".$SysDescriptor{"Name"}." system ABI has been dumped to:\n $SYS_DUMP_PATH"); -} - -return 1;
\ No newline at end of file |