diff options
author | Andrey Ponomarenko <andrewponomarenko@yandex.ru> | 2016-08-11 20:14:41 +0300 |
---|---|---|
committer | Andrey Ponomarenko <andrewponomarenko@yandex.ru> | 2016-08-11 20:14:41 +0300 |
commit | 81b09e8848c6646369681f534e7157f87533612f (patch) | |
tree | abbef6221e4598da4b2b4fb44969eb6abd6167ca | |
parent | f9f25c9b4ce17c950902c7e09935eccbca6309c5 (diff) | |
download | abi-compliance-checker-81b09e8848c6646369681f534e7157f87533612f.tar.gz |
Added -disable-quick-empty-report option. Improved generation of quick empty reports. Improved SysCheck.pm module for analysis of operating systems. Improved support for Windows 10.
-rw-r--r-- | abi-compliance-checker.pl | 204 | ||||
-rw-r--r-- | modules/Internals/RegTests.pm | 55 | ||||
-rw-r--r-- | modules/Internals/SysCheck.pm | 128 |
3 files changed, 254 insertions, 133 deletions
diff --git a/abi-compliance-checker.pl b/abi-compliance-checker.pl index 9c17b97..e71d93a 100644 --- a/abi-compliance-checker.pl +++ b/abi-compliance-checker.pl @@ -1,6 +1,6 @@ #!/usr/bin/perl ########################################################################### -# ABI Compliance Checker (ABICC) 1.99.22 +# ABI Compliance Checker (ABICC) 1.99.23 # A tool for checking backward compatibility of a C/C++ library API # # Copyright (C) 2009-2011 Institute for System Programming, RAS @@ -31,11 +31,11 @@ # - MinGW (3.0-4.7, 4.8.3, 4.9 or newer) # - MS Visual C++ (dumpbin, undname, cl) # - Active Perl 5 (5.8 or newer) -# - Sigcheck v1.71 or newer -# - Info-ZIP 3.0 (zip, unzip) -# - Ctags (5.8 or newer) +# - Sigcheck v2.52 or newer +# - GnuWin Zip and UnZip +# - Exuberant Ctags (5.8 or newer) # - Add tool locations to the PATH environment variable -# - Run vsvars32.bat (C:\Microsoft Visual Studio 9.0\Common7\Tools\) +# - Run vcvars64.bat (C:\Microsoft Visual Studio 9.0\VC\bin\) # # 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 @@ -60,7 +60,7 @@ use Storable qw(dclone); use Data::Dumper; use Config; -my $TOOL_VERSION = "1.99.22"; +my $TOOL_VERSION = "1.99.23"; my $ABI_DUMP_VERSION = "3.2"; my $XML_REPORT_VERSION = "1.2"; my $XML_ABI_DUMP_VERSION = "1.2"; @@ -91,7 +91,8 @@ $SourceReportPath, $UseXML, $SortDump, $DumpFormat, $ExtraInfo, $ExtraDump, $Force, $Tolerance, $Tolerant, $SkipSymbolsListPath, $CheckInfo, $Quick, $AffectLimit, $AllAffected, $CppIncompat, $SkipInternalSymbols, $SkipInternalTypes, $TargetArch, $GccOptions, -$TypesListPath, $SkipTypesListPath, $CheckPrivateABI, $CountSymbols, $OldStyle); +$TypesListPath, $SkipTypesListPath, $CheckPrivateABI, $CountSymbols, $OldStyle, +$DisableQuickEmptyReport); my $CmdName = get_filename($0); my %OS_LibExt = ( @@ -148,7 +149,7 @@ my $HomePage = "http://lvc.github.io/abi-compliance-checker/"; my $ShortUsage = "ABI Compliance Checker (ABICC) $TOOL_VERSION A tool for checking backward compatibility of a C/C++ library API -Copyright (C) 2015 Andrey Ponomarenko's ABI Laboratory +Copyright (C) 2016 Andrey Ponomarenko's ABI Laboratory License: GNU LGPL or GNU GPL Usage: $CmdName [options] @@ -187,7 +188,7 @@ GetOptions("h|help!" => \$Help, "dump|dump-abi|dump_abi=s" => \$DumpAPI, # extra options "app|application=s" => \$AppPath, - "static-libs!" => \$UseStaticLibs, + "static|static-libs!" => \$UseStaticLibs, "gcc-path|cross-gcc=s" => \$CrossGcc, "gcc-prefix|cross-prefix=s" => \$CrossPrefix, "gcc-options=s" => \$GccOptions, @@ -251,6 +252,7 @@ GetOptions("h|help!" => \$Help, "tolerant!" => \$Tolerant, "check!" => \$CheckInfo, "quick!" => \$Quick, + "disable-quick-empty-report!" => \$DisableQuickEmptyReport, "all-affected!" => \$AllAffected, "skip-internal-symbols|skip-internal=s" => \$SkipInternalSymbols, "skip-internal-types=s" => \$SkipInternalTypes, @@ -401,7 +403,7 @@ EXTRA OPTIONS: This option allows to specify the application that should be checked for portability to the new library version. - -static-libs + -static Check static libraries instead of the shared ones. The <libs> section of the XML-descriptor should point to static libraries location. @@ -754,6 +756,9 @@ OTHER OPTIONS: -quick Quick analysis. Disable check of some template instances. + + -disable-quick-empty-report + Do not generate quick empty report if input ABI dumps are equal. -skip-internal-symbols PATTERN Do not check symbols matched by the pattern. @@ -6742,7 +6747,7 @@ sub detect_recursive_includes($$) { # for #include "..." my $Candidate = join_P($AbsDir, $Include); if(-f $Candidate) { - $HPath = realpath($Candidate); + $HPath = realpath_F($Candidate); } } elsif($IncType>0 @@ -7866,6 +7871,8 @@ sub platformSpecs($) { # add options to MinGW compiler # to simulate the MSVC compiler my %MinGW_Opts = map {$_=>1} ( + "-D__unaligned=\" \"", + "-D__nullptr=\"nullptr\"", "-D_WIN32", "-D_STDCALL_SUPPORTED", "-D__int64=\"long long\"", @@ -7904,11 +7911,14 @@ sub platformSpecs($) "-DDECLSPEC_DEPRECATED=\" \"", "-D__builtin_alignof(x)=__alignof__(x)", "-DSORTPP_PASS"); - if($Arch eq "x86") { + if($Arch eq "x86") + { $MinGW_Opts{"-D_M_IX86=300"}=1; } - elsif($Arch eq "x86_64") { + elsif($Arch eq "x86_64") + { $MinGW_Opts{"-D_M_AMD64=300"}=1; + $MinGW_Opts{"-D_M_X64=300"}=1; } elsif($Arch eq "ia64") { $MinGW_Opts{"-D_M_IA64=300"}=1; @@ -10445,7 +10455,7 @@ sub isPublic($$) # by name in C language # TODO: add other methods to detect private members my $MName = $TypePtr->{"Memb"}{$FieldPos}{"name"}; - if($MName=~/priv|abidata|parent_object/i) + if($MName=~/priv|abidata|parent_object|impl/i) { # C-styled private data return 0; } @@ -15463,7 +15473,7 @@ sub get_abs_path($) if(not is_abs($Path)) { $Path = abs_path($Path); } - return $Path; + return path_format($Path, $OSgroup); } sub get_OSgroup() @@ -17405,9 +17415,11 @@ sub getAffectedSymbols($$$) foreach my $Symbol (sort {lc($a) cmp lc($b)} keys(%SymSel)) { + my $Kind = $SymSel{$Symbol}{"Kind"}; my $Loc = $SymSel{$Symbol}{"Loc"}; + my $PName = getParamName($Loc); - my $Desc = getAffectDesc($Level, $Symbol, $SymSel{$Symbol}{"Kind"}, $Loc); + my $Desc = getAffectDesc($Level, $Symbol, $Kind, $Loc); my $Target = ""; if($PName) @@ -18715,7 +18727,6 @@ sub translateSymbols(@) } elsif(index($Symbol, "?")==0) { - next if($tr_name{$Symbol}); push(@MnglNames2, $Symbol); } else @@ -19011,7 +19022,7 @@ sub readSymbols_Lib($$$$$$) my ($LibVersion, $Lib_Path, $IsNeededLib, $Weak, $Deps, $Vers) = @_; return () if(not $LibVersion or not $Lib_Path); - my $Real_Path = realpath($Lib_Path); + my $Real_Path = realpath_F($Lib_Path); if(not $Real_Path) { # broken link @@ -19156,15 +19167,32 @@ sub readSymbols_Lib($$$$$$) open(LIB, $DumpBinCmd." |"); } while(<LIB>) - { # 1197 4AC 0000A620 SetThreadStackGuarantee - # 1198 4AD SetThreadToken (forwarded to ...) - # 3368 _o2i_ECPublicKey - # 1 0 00005B30 ??0?N = ... (with pdb) - if(/\A\s*\d+\s+[a-f\d]+\s+[a-f\d]+\s+([\w\?\@]+)\s*(?:=.+)?\Z/i - or /\A\s*\d+\s+[a-f\d]+\s+([\w\?\@]+)\s*\(\s*forwarded\s+/ - or /\A\s*\d+\s+_([\w\?\@]+)\s*(?:=.+)?\Z/) - { # dynamic, static and forwarded symbols - my $realname = $1; + { + my $realname = undef; + if($LIB_TYPE eq "dynamic") + { + # 1197 4AC 0000A620 SetThreadStackGuarantee + # 1198 4AD SetThreadToken (forwarded to ...) + # 3368 _o2i_ECPublicKey + # 1 0 00005B30 ??0?N = ... (with pdb) + if(/\A\s*\d+\s+[a-f\d]+\s+[a-f\d]+\s+([\w\?\@]+)\s*(?:=.+)?\Z/i + or /\A\s*\d+\s+[a-f\d]+\s+([\w\?\@]+)\s*\(\s*forwarded\s+/ + or /\A\s*\d+\s+_([\w\?\@]+)\s*(?:=.+)?\Z/) + { # dynamic, static and forwarded symbols + $realname = $1; + } + } + else + { # static + if(/\A\s{10,}\d*\s+([\w\?\@]+)\s*\Z/i) + { + # 16 IID_ISecurityInformation + $realname = $1; + } + } + + if($realname) + { if($IsNeededLib) { if(not defined $RegisteredObjects_Short{$LibVersion}{$Lib_ShortName}) @@ -19876,7 +19904,7 @@ sub getSOPaths_Dest($$) if(get_filename($Path)=~/\A(|lib)\Q$TargetLibraryName\E[\d\-]*\.$LIB_EXT[\d\.]*\Z/i) { registerObject($Path, $LibVersion); - $Libs{realpath($Path)}=1; + $Libs{realpath_F($Path)} = 1; } } } @@ -19887,7 +19915,7 @@ sub getSOPaths_Dest($$) next if(ignore_path($Path)); next if(skipLib($Path, $LibVersion)); registerObject($Path, $LibVersion); - $Libs{realpath($Path)}=1; + $Libs{realpath_F($Path)} = 1; } if($OSgroup eq "macos") { # shared libraries on MacOS X may have no extension @@ -19899,7 +19927,7 @@ sub getSOPaths_Dest($$) and cmd_file($Path)=~/(shared|dynamic)\s+library/i) { registerObject($Path, $LibVersion); - $Libs{realpath($Path)}=1; + $Libs{realpath_F($Path)} = 1; } } } @@ -19911,6 +19939,12 @@ sub getSOPaths_Dest($$) } } +sub realpath_F($) +{ + my $Path = $_[0]; + return path_format(realpath($Path), $OSgroup); +} + sub isCyclical($$) { my ($Stack, $Value) = @_; @@ -19980,10 +20014,16 @@ sub getArch_GCC($) system($Cmd); chdir($ORIG_DIR); - $Arch = getArch_Object("$TMP_DIR/test"); + my $EX = join_P($TMP_DIR, "test"); + + if($OSgroup eq "windows") { + $EX = join_P($TMP_DIR, "test.exe"); + } + + $Arch = getArch_Object($EX); unlink("$TMP_DIR/test.c"); - unlink("$TMP_DIR/test"); + unlink($EX); } if(not $Arch) { @@ -20304,7 +20344,7 @@ sub read_ABI_Dump($$) $Descriptor{$LibVersion}{"Version"} = $ABI->{"LibraryVersion"}; } - if(not $SkipTypes{$LibVersion}) + if(not keys(%{$SkipTypes{$LibVersion}})) { # if not defined by -skip-types option if(defined $ABI->{"SkipTypes"}) { @@ -20322,14 +20362,16 @@ sub read_ABI_Dump($$) } } - if(not $SkipSymbols{$LibVersion}) + if(not keys(%{$SkipSymbols{$LibVersion}})) { # if not defined by -skip-symbols option - $SkipSymbols{$LibVersion} = $ABI->{"SkipSymbols"}; - if(not $SkipSymbols{$LibVersion}) + if(defined $ABI->{"SkipSymbols"}) { + $SkipSymbols{$LibVersion} = $ABI->{"SkipSymbols"}; + } + if(defined $ABI->{"SkipInterfaces"}) { # support for old dumps $SkipSymbols{$LibVersion} = $ABI->{"SkipInterfaces"}; } - if(not $SkipSymbols{$LibVersion}) + if(defined $ABI->{"InternalInterfaces"}) { # support for old dumps $SkipSymbols{$LibVersion} = $ABI->{"InternalInterfaces"}; } @@ -20891,8 +20933,7 @@ sub detect_inc_default_paths() if($Line=~/\A[ \t]*((\/|\w+:\\).+)[ \t]*\Z/) { - my $Path = realpath($1); - $Path = path_format($Path, $OSgroup); + my $Path = realpath_F($1); if(index($Path, "c++")!=-1 or index($Path, "/g++/")!=-1) { @@ -21547,6 +21588,9 @@ sub is_target_lib($) if(not $LName) { return 0; } + if($OSgroup eq "windows") { + $LName = lc($LName); + } if($TargetLibraryName and $LName!~/\Q$TargetLibraryName\E/) { return 0; @@ -21840,9 +21884,9 @@ sub printReport() sub check_win32_env() { - if(not $ENV{"DevEnvDir"} - or not $ENV{"LIB"}) { - exitStatus("Error", "can't start without VS environment (vsvars32.bat)"); + if(not $ENV{"VCINSTALLDIR"} + or not $ENV{"INCLUDE"}) { + exitStatus("Error", "can't start without VC environment (vcvars64.bat)"); } } @@ -22082,13 +22126,14 @@ sub create_ABI_Dump() sub quickEmptyReports() { # Quick "empty" reports - # 4 times faster than merging equal dumps + # ~4 times faster than merging equal dumps # NOTE: the dump contains the "LibraryVersion" attribute # if you change the version, then your dump will be different # OVERCOME: use -v1 and v2 options for comparing dumps # and don't change version in the XML descriptor (and dumps) # OVERCOME 2: separate meta info from the dumps in ACC 2.0 - if(-s $Descriptor{1}{"Path"} == -s $Descriptor{2}{"Path"}) + if($Descriptor{1}{"Path"} eq $Descriptor{2}{"Path"} + or -s $Descriptor{1}{"Path"} == -s $Descriptor{2}{"Path"}) { my $FilePath1 = $Descriptor{1}{"Path"}; my $FilePath2 = $Descriptor{2}{"Path"}; @@ -22116,15 +22161,29 @@ sub quickEmptyReports() my $Content1 = <DUMP1>; close(DUMP1); - open(DUMP2, $FilePath2); - my $Content2 = <DUMP2>; - close(DUMP2); + my $Eq = 0; + + if($FilePath1 eq $FilePath2) { + $Eq = 1; + } - if($Content1 eq $Content2) + if(not $Eq) { + open(DUMP2, $FilePath2); + my $Content2 = <DUMP2>; + close(DUMP2); + + if($Content1 eq $Content2) { + $Eq = 1; + } + # clean memory undef $Content2; - + } + + if($Eq) + { + printMsg("INFO", "Input ABI dumps are equal, so generating quick empty report"); # read a number of headers, libs, symbols and types my $ABIdump = eval($Content1); @@ -22143,6 +22202,11 @@ sub quickEmptyReports() $ABIdump->{"SymbolInfo"} = $ABIdump->{"FuncDescr"}; } read_Source_DumpInfo($ABIdump, 1); + + foreach (keys(%{$Registered_Headers{1}})) { + $TargetHeaders{1}{$_} = 1; + } + read_Libs_DumpInfo($ABIdump, 1); read_Machine_DumpInfo($ABIdump, 1); read_Machine_DumpInfo($ABIdump, 2); @@ -22169,6 +22233,16 @@ sub quickEmptyReports() $Descriptor{1}{"Version"} = $TargetVersion{1}?$TargetVersion{1}:$ABIdump->{"LibraryVersion"}; $Descriptor{2}{"Version"} = $TargetVersion{2}?$TargetVersion{2}:$ABIdump->{"LibraryVersion"}; + + if(defined $ABIdump->{"ABI_DUMPER_VERSION"}) + { + $UsedDump{1}{"DWARF"} = 1; + $UsedDump{2}{"DWARF"} = 1; + + $UsedDump{1}{"M"} = $ABIdump->{"LibraryName"}; + $UsedDump{2}{"M"} = $ABIdump->{"LibraryName"}; + } + exitReport(); } } @@ -22187,7 +22261,7 @@ sub initLogging($) if($LogMode ne "n") { mkpath($LOG_DIR); } - $LOG_PATH{$LibVersion} = get_abs_path($LOG_DIR)."/".$LOG_FILE; + $LOG_PATH{$LibVersion} = join_P(get_abs_path($LOG_DIR), $LOG_FILE); if($Debug) { # debug directory $DEBUG_PATH{$LibVersion} = "debug/$TargetLibraryName/".$Descriptor{$LibVersion}{"Version"}; @@ -22263,10 +22337,14 @@ sub compareInit() } detect_default_paths("bin"); # to extract dumps - if(isDump($Descriptor{1}{"Path"}) - and isDump($Descriptor{2}{"Path"})) - { # optimization: equal ABI dumps - quickEmptyReports(); + + if(not defined $DisableQuickEmptyReport) + { + if(isDump($Descriptor{1}{"Path"}) + and isDump($Descriptor{2}{"Path"})) + { # optimization: equal ABI dumps + quickEmptyReports(); + } } printMsg("INFO", "preparation, please wait ..."); @@ -22682,6 +22760,7 @@ sub getSysOpts() "CrossGcc"=>$CrossGcc, "UseStaticLibs"=>$UseStaticLibs, "NoStdInc"=>$NoStdInc, + "CppCompat"=>$CppCompat, "BinaryOnly" => $BinaryOnly, "SourceOnly" => $SourceOnly @@ -22821,7 +22900,7 @@ sub scenario() } if($ShowVersion) { - printMsg("INFO", "ABI Compliance Checker (ABICC) $TOOL_VERSION\nCopyright (C) 2015 Andrey Ponomarenko's ABI Laboratory\nLicense: LGPL or GPL <http://www.gnu.org/licenses/>\nThis program is free software: you can redistribute it and/or modify it.\n\nWritten by Andrey Ponomarenko."); + printMsg("INFO", "ABI Compliance Checker (ABICC) $TOOL_VERSION\nCopyright (C) 2016 Andrey Ponomarenko's ABI Laboratory\nLicense: LGPL or GPL <http://www.gnu.org/licenses/>\nThis program is free software: you can redistribute it and/or modify it.\n\nWritten by Andrey Ponomarenko."); exit(0); } if($DumpVersion) @@ -22856,8 +22935,14 @@ sub scenario() if(not -f $TargetLibsPath) { exitStatus("Access_Error", "can't access file \'$TargetLibsPath\'"); } - foreach my $Lib (split(/\s*\n\s*/, readFile($TargetLibsPath))) { - $TargetLibs{$Lib} = 1; + foreach my $Lib (split(/\s*\n\s*/, readFile($TargetLibsPath))) + { + if($OSgroup eq "windows") { + $TargetLibs{lc($Lib)} = 1; + } + else { + $TargetLibs{$Lib} = 1; + } } } if($TargetHeadersPath) @@ -22887,7 +22972,10 @@ sub scenario() } if($DumpSystem) { # --dump-system - + if(-d $MODULES_DIR."/Targets/" + and -d $MODULES_DIR."/Targets/".$OStarget) { + $TargetSysInfo = $MODULES_DIR."/Targets/".$OStarget; + } if(not $TargetSysInfo) { exitStatus("Error", "-sysinfo option should be specified to dump system ABI"); } diff --git a/modules/Internals/RegTests.pm b/modules/Internals/RegTests.pm index 587b292..47ee256 100644 --- a/modules/Internals/RegTests.pm +++ b/modules/Internals/RegTests.pm @@ -72,33 +72,33 @@ sub testCpp() $SOURCE2 .= "namespace TestNS {\n"; # Changed template internals - $HEADER1 .= " - template <typename T, int _P> - class $DECL_SPEC ChangedTemplate { - public: - T value; - T*const field; - T array[_P]; - typedef int My; - My var; - }; - ChangedTemplate<int, 1>* changedTemplate();"; - $SOURCE1 .= " - ChangedTemplate<int, 1>* changedTemplate() { return new ChangedTemplate<int, 1>(); }"; - - $HEADER2 .= " - template <typename T, int _P> - class $DECL_SPEC ChangedTemplate { - public: - double value; - T* field; - double array[_P]; - typedef int My; - My var; - }; - ChangedTemplate<int, 1>* changedTemplate();"; - $SOURCE2 .= " - ChangedTemplate<int, 1>* changedTemplate() { return new ChangedTemplate<int, 1>(); }"; + # $HEADER1 .= " + # template <typename T, int _P> + # class $DECL_SPEC ChangedTemplate { + # public: + # T value; + # T*const field; + # T array[_P]; + # typedef int My; + # My var; + # }; + # ChangedTemplate<int, 1>* changedTemplate();"; + # $SOURCE1 .= " + # ChangedTemplate<int, 1>* changedTemplate() { return new ChangedTemplate<int, 1>(); }"; + # + # $HEADER2 .= " + # template <typename T, int _P> + # class $DECL_SPEC ChangedTemplate { + # public: + # double value; + # T* field; + # double array[_P]; + # typedef int My; + # My var; + # }; + # ChangedTemplate<int, 1>* changedTemplate();"; + # $SOURCE2 .= " + # ChangedTemplate<int, 1>* changedTemplate() { return new ChangedTemplate<int, 1>(); }"; # Removed inline method $HEADER1 .= " @@ -4743,6 +4743,7 @@ sub runTests($$$$$$$$) { check_win32_env(); # to run MS VC++ compiler my $CL = get_CmdPath("cl"); + if(not $CL) { exitStatus("Not_Found", "can't find \"cl\" compiler"); } diff --git a/modules/Internals/SysCheck.pm b/modules/Internals/SysCheck.pm index 4f20188..550c4f4 100644 --- a/modules/Internals/SysCheck.pm +++ b/modules/Internals/SysCheck.pm @@ -28,7 +28,7 @@ use Fcntl; my ($Debug, $Quiet, $LogMode, $CheckHeadersOnly, $SystemRoot, $GCC_PATH, $CrossPrefix, $TargetSysInfo, $TargetLibraryName, $CrossGcc, $UseStaticLibs, -$NoStdInc, $OStarget, $BinaryOnly, $SourceOnly); +$NoStdInc, $CppCompat, $OStarget, $BinaryOnly, $SourceOnly); my $OSgroup = get_OSgroup(); my $TMP_DIR = tempdir(CLEANUP=>1); @@ -123,16 +123,9 @@ sub cmpSystems($$$) $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 @Dumps1 = cmd_find($SPath1."/abi_dumps","f","*.abi",1); + my @Dumps2 = cmd_find($SPath2."/abi_dumps","f","*.abi",1); + my (%LibVers1, %LibVers2) = (); my (%ShortNames1, %ShortNames2) = (); foreach my $DPath (@Dumps1) @@ -276,18 +269,18 @@ sub cmpSystems($$$) } foreach my $LSName (keys(%AddedShort)) { # changed SONAME - my @AddedSonames = keys(%{$AddedShort{$LSName}}); + my @AddedSonames = sort keys(%{$AddedShort{$LSName}}); next if($#AddedSonames!=0); if(defined $RemovedShort{$LSName}) { # removed old soname - my @RemovedSonames = keys(%{$RemovedShort{$LSName}}); + my @RemovedSonames = sort keys(%{$RemovedShort{$LSName}}); $ChangedSoname{$AddedSonames[0]} = $RemovedSonames[0]; $ChangedSoname{$RemovedSonames[0]} = $AddedSonames[0]; } elsif(defined $ShortNames1{$LSName}) { # saved old soname - my @Sonames = keys(%{$ShortNames1{$LSName}}); + my @Sonames = sort keys(%{$ShortNames1{$LSName}}); $ChangedSoname{$AddedSonames[0]} = $Sonames[0]; $ChangedSoname{$Sonames[0]} = $AddedSonames[0]; } @@ -1150,6 +1143,7 @@ sub initModule($) $CrossGcc = $S->{"CrossGcc"}; $UseStaticLibs = $S->{"UseStaticLibs"}; $NoStdInc = $S->{"NoStdInc"}; + $CppCompat = $S->{"CppCompat"}; $BinaryOnly = $S->{"BinaryOnly"}; $SourceOnly = $S->{"SourceOnly"}; @@ -1338,7 +1332,7 @@ sub get_binversion($) if(not $SigcheckCmd) { return ""; } - my $VInfo = `$SigcheckCmd -n $Path 2>$TMP_DIR/null`; + my $VInfo = `$SigcheckCmd -nobanner -n $Path 2>$TMP_DIR/null`; $VInfo=~s/\s*\(.*\)\s*//; chomp($VInfo); return $VInfo; @@ -1473,7 +1467,7 @@ sub dumpSystem($) if(not defined $LibSoname{$LName}) { $LibSoname{$LName}=$Soname; } - if(-l $LPath and my $Path = realpath($LPath)) + if(-l $LPath and my $Path = realpath_F($LPath)) { my $Name = get_filename($Path); if(not defined $LibSoname{$Name}) { @@ -1579,7 +1573,7 @@ sub dumpSystem($) } if(-l $LPath) { # symlinks - if(my $Path = realpath($LPath)) { + if(my $Path = realpath_F($LPath)) { $SysLibs{$Path} = 1; } } @@ -1593,7 +1587,7 @@ sub dumpSystem($) { my $Candidate = $Candidates[0]; if(-l $Candidate - and my $Path = realpath($Candidate)) { + and my $Path = realpath_F($Candidate)) { $Candidate = $Path; } $SysLibs{$Candidate} = 1; @@ -1605,6 +1599,11 @@ sub dumpSystem($) } } @SystemLibs = (); # clear memory + + if(not keys(%SysLibs)) { + exitStatus("Error", "can't find libraries"); + } + if(not $CheckHeadersOnly) { if($Debug) { @@ -1630,6 +1629,11 @@ sub dumpSystem($) $ShortestNames{$LPath} = parse_libname($LName, "shortest", $OStarget); my $Res = readSymbols_Lib(1, $LPath, 0, "-Weak", 0, 0); + + if(not keys(%{$Res}) and $TargetLibraryName) { + exitStatus("Error", "can't find exported symbols in the library"); + } + $Syms{$LPath} = $Res->{$LName}; push(@AllSyms, keys(%{$Syms{$LPath}})); } @@ -2339,7 +2343,7 @@ sub dumpSystem($) } my @Content = ("<version>\n $LVersion\n</version>"); - my @IncHeaders = keys(%Includes); + my @IncHeaders = sort keys(%Includes); # sort files up @IncHeaders = sort {$b=~/\.h\Z/<=>$a=~/\.h\Z/} @IncHeaders; @@ -2373,13 +2377,13 @@ sub dumpSystem($) } # system - if(my @SearchHeaders = keys(%{$SysDescriptor{"SearchHeaders"}})) { + if(my @SearchHeaders = sort keys(%{$SysDescriptor{"SearchHeaders"}})) { push(@Content, "<search_headers>\n ".join("\n ", @SearchHeaders)."\n</search_headers>"); } - if(my @SearchLibs = keys(%{$SysDescriptor{"SearchLibs"}})) { + if(my @SearchLibs = sort keys(%{$SysDescriptor{"SearchLibs"}})) { push(@Content, "<search_libs>\n ".join("\n ", @SearchLibs)."\n</search_libs>"); } - if(my @Tools = keys(%{$SysDescriptor{"Tools"}})) { + if(my @Tools = sort keys(%{$SysDescriptor{"Tools"}})) { push(@Content, "<tools>\n ".join("\n ", @Tools)."\n</tools>"); } if(my $Prefix = $SysDescriptor{"CrossPrefix"}) { @@ -2402,6 +2406,27 @@ sub dumpSystem($) push(@TryNames, $LSName); } + # common + if(my $List = $SysCInfo->{"include_preamble"}) { + push(@Preamble, @{$List}); + } + if(my $List = $SysCInfo->{"skip_headers"}) { + @Skip = (@Skip, @{$List}); + } + if(my $List = $SysCInfo->{"skip_including"}) { + @SkipInc = (@SkipInc, @{$List}); + } + if(my $List = $SysCInfo->{"skip_symbols"}) { + push(@SkipSymb, @{$List}); + } + if(my $List = $SysCInfo->{"gcc_options"}) { + push(@CompilerOpts, @{$List}); + } + if($SysCInfo->{"defines"}) { + push(@Defines, $SysCInfo->{"defines"}); + } + + # particular foreach (@TryNames) { if(my $List = $SysInfo->{$_}{"include_preamble"}) { @@ -2433,26 +2458,6 @@ sub dumpSystem($) } } - # common - if(my $List = $SysCInfo->{"include_preamble"}) { - push(@Preamble, @{$List}); - } - if(my $List = $SysCInfo->{"skip_headers"}) { - @Skip = (@Skip, @{$List}); - } - if(my $List = $SysCInfo->{"skip_including"}) { - @SkipInc = (@SkipInc, @{$List}); - } - if(my $List = $SysCInfo->{"skip_symbols"}) { - push(@SkipSymb, @{$List}); - } - if(my $List = $SysCInfo->{"gcc_options"}) { - push(@CompilerOpts, @{$List}); - } - if($SysCInfo->{"defines"}) { - push(@Defines, $SysCInfo->{"defines"}); - } - # common other if($LSName=~/\AlibX\w+\Z/) { # add Xlib.h for libXt, libXaw, libXext and others @@ -2538,7 +2543,7 @@ sub dumpSystem($) $ACC_dump .= " -relpath \"$SystemRoot\""; $ACC_dump .= " -sysroot \"$SystemRoot\""; } - my $DumpPath = "$SYS_DUMP_PATH/abi_dumps/$LName.abi.".getAR_EXT($OSgroup); + my $DumpPath = "$SYS_DUMP_PATH/abi_dumps/$LName.abi"; $ACC_dump .= " -dump-path \"$DumpPath\""; my $LogPath = "$SYS_DUMP_PATH/logs/$LName.txt"; unlink($LogPath); @@ -2562,6 +2567,9 @@ sub dumpSystem($) # 3. symbian/GCC $ACC_dump .= " -nostdinc"; } + if($CppCompat) { + $ACC_dump .= " -cpp-compatible"; + } if($Quiet) { # quiet mode $ACC_dump .= " -quiet"; @@ -2579,15 +2587,20 @@ sub dumpSystem($) } printMsg("INFO_C", "Dumping $LName: "); system($ACC_dump." 1>$TMP_DIR/null 2>$TMP_DIR/$LName.stderr"); + my $ErrCode = $?; appendFile("$SYS_DUMP_PATH/logs/$LName.txt", "The ACC parameters:\n $ACC_dump\n"); - if(-s "$TMP_DIR/$LName.stderr") + my $ErrCont = readFile("$TMP_DIR/$LName.stderr"); + if($ErrCont) { + appendFile("$SYS_DUMP_PATH/logs/$LName.txt", $ErrCont); + } + + if(filterError($ErrCont)) { - appendFile("$SYS_DUMP_PATH/logs/$LName.txt", readFile("$TMP_DIR/$LName.stderr")); - if(get_CodeError($?>>8) eq "Invalid_Dump") { + if(get_CodeError($ErrCode>>8) eq "Invalid_Dump") { printMsg("INFO", "Empty"); } else { - printMsg("INFO", "Failed (\'$SYS_DUMP_PATH/logs/$LName.txt\')"); + printMsg("INFO", "Errors (\'$SYS_DUMP_PATH/logs/$LName.txt\')"); } } elsif(not -f $DumpPath) { @@ -2610,4 +2623,23 @@ sub dumpSystem($) printMsg("INFO", "The ".$SysDescriptor{"Name"}." system ABI has been dumped to:\n $SYS_DUMP_PATH"); } -return 1;
\ No newline at end of file +sub filterError($) +{ + my $Error = $_[0]; + + if(not $Error) { + return undef; + } + + my @Err = (); + foreach my $L (split(/\n/, $Error)) + { + if($L!~/warning:/) { + push(@Err, $L); + } + } + + return join("\n", @Err); +} + +return 1; |