@@ -101,8 +101,18 @@ Options
* ``--headers-dir1 | --hd1`` <headers-directory-path-1>
Specifies where to find the public headers of the first shared
- library that the tool has to consider. The tool will thus filter
- out ABI changes on types that are not defined in public headers.
+ library (or binary in general) that the tool has to consider. The
+ tool will thus filter out ABI changes on types that are not
+ defined in public headers.
+
+ Note that several public header directories can be specified for
+ the first shared library. In that case the ``--headers-dir1``
+ option should be present several times on the command line, like
+ in the following example: ::
+
+ $ abidiff --headers-dir1 /some/path \
+ --headers-dir1 /some/other/path \
+ binary-version-1 binary-version-2
* ``--header-file1 | --hf1`` <header-file-path-1>
@@ -116,6 +126,15 @@ Options
library that the tool has to consider. The tool will thus filter
out ABI changes on types that are not defined in public headers.
+ Note that several public header directories can be specified for
+ the second shared library. In that case the ``--headers-dir2``
+ option should be present several times like in the following
+ example: ::
+
+ $ abidiff --headers-dir2 /some/path \
+ --headers-dir2 /some/other/path \
+ binary-version-1 binary-version-2
+
* ``--header-file2 | --hf2`` <header-file-path-2>
Specifies where to find one public header of the second shared
@@ -128,9 +128,18 @@ Options
* ``--headers-dir | --hd`` <headers-directory-path-1>
- Specifies where to find the public headers of the first shared
- library that the tool has to consider. The tool will thus filter
- out types that are not defined in public headers.
+ Specifies where to find the public headers of the binary that the
+ tool has to consider. The tool will thus filter out types that
+ are not defined in public headers.
+
+ Note that several public header directories can be specified for
+ the binary to consider. In that case the ``--header-dir`` option
+ should be present several times on the command line, like in the
+ following example: ::
+
+ $ abidw --header-dir /some/path \
+ --header-dir /some/other/path \
+ binary > binary.abi
* ``--header-file | --hf`` <header-file-path>
@@ -91,6 +91,10 @@ suppr::type_suppression_sptr
gen_suppr_spec_from_headers(const string& hdrs_root_dir,
const vector<string>& hdr_files);
+suppr::type_suppression_sptr
+gen_suppr_spec_from_headers(const vector<string>& headers_root_dirs,
+ const vector<string>& header_files);
+
suppr::suppressions_type
gen_suppr_spec_from_kernel_abi_whitelists
(const vector<string>& abi_whitelist_paths);
@@ -1842,12 +1842,44 @@ handle_fts_entry(const FTSENT *entry,
}
}
+/// Populate a type_supression from header files found in a given
+/// directory tree.
+///
+/// The suppression suppresses types defined in source files that are
+/// *NOT* found in the directory tree.
+///
+/// This is a subroutine for gen_suppr_spect_from_headers.
+///
+/// @param headers_root_dir the directory tree to consider for header
+/// files.
+///
+/// @param result the type_supression to populate from the content of
+/// @p headers_root_dir.
+static void
+gen_suppr_spec_from_headers_root_dir(const string& headers_root_dir,
+ type_suppression_sptr &result)
+{
+ if (!headers_root_dir.empty())
+ {
+ char* paths[] = {const_cast<char*>(headers_root_dir.c_str()), 0};
+
+ if (FTS *file_hierarchy = fts_open(paths, FTS_LOGICAL|FTS_NOCHDIR, NULL))
+ {
+ FTSENT *entry;
+ while ((entry = fts_read(file_hierarchy)))
+ handle_fts_entry(entry, result);
+ fts_close(file_hierarchy);
+ }
+ }
+}
+
/// Generate a type suppression specification that suppresses ABI
/// changes for types defined in source files that are neither in a
-/// given header root dir, not in a set of header files.
+/// given set of header root directories nor in a set of header
+/// files.
///
-/// @param headers_root_dir ABI changes in types defined in files
-/// *NOT* found in this directory tree are going be suppressed.
+/// @param headers_root_dirs ABI changes in types defined in files
+/// *NOT* found in these directory trees are going be suppressed.
///
/// @param header_files a set of additional header files that define
/// types that are to be kept (not supressed) by the returned type
@@ -1856,29 +1888,15 @@ handle_fts_entry(const FTSENT *entry,
/// @return the resulting type suppression generated, if any file was
/// found in the directory tree @p headers_root_dir.
type_suppression_sptr
-gen_suppr_spec_from_headers(const string& headers_root_dir,
+gen_suppr_spec_from_headers(const vector<string>& headers_root_dirs,
const vector<string>& header_files)
{
type_suppression_sptr result;
- if (headers_root_dir.empty() && header_files.empty())
- // We were given no headers root dir and no header files
- // so the resulting suppression specification shall be empty.
- return result;
-
- if (!headers_root_dir.empty())
- {
- char* paths[] = {const_cast<char*>(headers_root_dir.c_str()), 0};
-
- FTS *file_hierarchy = fts_open(paths, FTS_LOGICAL|FTS_NOCHDIR, NULL);
- if (!file_hierarchy)
- return result;
-
- FTSENT *entry;
- while ((entry = fts_read(file_hierarchy)))
- handle_fts_entry(entry, result);
- fts_close(file_hierarchy);
- }
+ for (vector<string>::const_iterator root_dir = headers_root_dirs.begin();
+ root_dir != headers_root_dirs.end();
+ ++root_dir)
+ gen_suppr_spec_from_headers_root_dir(*root_dir, result);
for (vector<string>::const_iterator file = header_files.begin();
file != header_files.end();
@@ -1889,6 +1907,32 @@ gen_suppr_spec_from_headers(const string& headers_root_dir,
}
/// Generate a type suppression specification that suppresses ABI
+/// changes for types defined in source files that are neither in a
+/// given header root dir, not in a set of header files.
+///
+/// @param headers_root_dir ABI changes in types defined in files
+/// *NOT* found in this directory tree are going be suppressed.
+///
+/// @param header_files a set of additional header files that define
+/// types that are to be kept (not supressed) by the returned type
+/// suppression.
+///
+/// @return the resulting type suppression generated, if any file was
+/// found in the directory tree @p headers_root_dir.
+type_suppression_sptr
+gen_suppr_spec_from_headers(const string& headers_root_dir,
+ const vector<string>& header_files)
+{
+ type_suppression_sptr result;
+ vector<string> root_dirs;
+
+ if (!headers_root_dir.empty())
+ root_dirs.push_back(headers_root_dir);
+
+ return gen_suppr_spec_from_headers(root_dirs, header_files);
+}
+
+/// Generate a type suppression specification that suppresses ABI
/// changes for types defined in source files that are not in a given
/// header root dir.
///
@@ -174,6 +174,16 @@ test-abidiff-exit/test-net-change-report0.txt \
test-abidiff-exit/test-net-change-report1.txt \
test-abidiff-exit/test-net-change-report2.txt \
test-abidiff-exit/test-net-change-report3.txt \
+test-abidiff-exit/test-headers-dirs/headers-a/header-a-v0.h \
+test-abidiff-exit/test-headers-dirs/headers-a/header-a-v1.h \
+test-abidiff-exit/test-headers-dirs/headers-b/header-b-v0.h \
+test-abidiff-exit/test-headers-dirs/headers-b/header-b-v1.h \
+test-abidiff-exit/test-headers-dirs/test-headers-dir-report-1.txt \
+test-abidiff-exit/test-headers-dirs/test-headers-dir-report-2.txt \
+test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.c \
+test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.o \
+test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.c \
+test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.o \
\
test-diff-dwarf/test0-v0.cc \
test-diff-dwarf/test0-v0.o \
new file mode 100644
@@ -0,0 +1,26 @@
+typedef struct opaque_struct * opaque_struct_pointer_type;
+
+typedef struct public_struct_type *public_struct_pointer_type;
+typedef struct public_struct_type2 *public_struct_pointer_type2;
+
+typedef void (*FuncPointerType0) (public_struct_pointer_type,
+ public_struct_pointer_type);
+
+typedef void (*FuncPointerType1) (public_struct_pointer_type, int);
+
+typedef struct public_struct_type2
+{
+ FuncPointerType0 m0;
+ FuncPointerType1 m1;
+} public_struct_type2;
+
+typedef struct public_struct_type
+{
+ opaque_struct_pointer_type m0;
+ public_struct_type2 *m1;
+} public_struct_type;
+
+void foo(public_struct_pointer_type p1);
+
+void bar(second_public_struct_pointer_type p1,
+ second_opaque_struct_pointer_type p2);
new file mode 100644
@@ -0,0 +1,26 @@
+typedef struct opaque_struct * opaque_struct_pointer_type;
+
+typedef struct public_struct_type *public_struct_pointer_type;
+typedef struct public_struct_type2 *public_struct_pointer_type2;
+
+typedef void (*FuncPointerType0) (public_struct_pointer_type,
+ public_struct_pointer_type);
+
+typedef void (*FuncPointerType1) (public_struct_pointer_type, int);
+
+typedef struct public_struct_type2
+{
+ FuncPointerType0 m0;
+ FuncPointerType1 m1;
+} public_struct_type2;
+
+typedef struct public_struct_type
+{
+ opaque_struct_pointer_type m0;
+ public_struct_type2 *m1;
+} public_struct_type;
+
+void foo(public_struct_pointer_type p1);
+
+void bar(second_public_struct_pointer_type p1,
+ second_opaque_struct_pointer_type p2);
new file mode 100644
@@ -0,0 +1,8 @@
+typedef struct second_opaque_struct *second_opaque_struct_pointer_type;
+
+typedef struct second_public_struct * second_public_struct_pointer_type;
+
+struct second_public_struct
+{
+ int m1;
+};
new file mode 100644
@@ -0,0 +1,9 @@
+typedef struct second_opaque_struct *second_opaque_struct_pointer_type;
+
+typedef struct second_public_struct * second_public_struct_pointer_type;
+
+struct second_public_struct
+{
+ int m1;
+ char m2;
+};
new file mode 100644
@@ -0,0 +1,3 @@
+Functions changes summary: 0 Removed, 0 Changed (2 filtered out), 0 Added functions
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
new file mode 100644
@@ -0,0 +1,13 @@
+Functions changes summary: 0 Removed, 1 Changed (1 filtered out), 0 Added functions
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
+1 function with some indirect sub-type change:
+
+ [C] 'function void bar(second_public_struct_pointer_type, second_opaque_struct_pointer_type)' at test-headers-dir-v1.c:33:1 has some indirect sub-type changes:
+ parameter 1 of type 'typedef second_public_struct_pointer_type' has sub-type changes:
+ underlying type 'second_public_struct*' changed:
+ in pointed to type 'struct second_public_struct' at header-b-v1.h:5:1:
+ type size changed from 32 to 64 (in bits)
+ 1 data member insertion:
+ 'char second_public_struct::m2', at offset 32 (in bits) at header-b-v1.h:8:1
+
new file mode 100644
@@ -0,0 +1,33 @@
+/*
+ * Compile this test with:
+ * gcc -c -g test-headers-dir-v0.c
+ *
+ * This test exhibits changes that are redundant in a weird way.
+ * The redundant path through the diff graph involves typedefs,
+ * function types and function parameter diff nodes.
+ *
+ */
+#include "headers-b/header-b-v0.h"
+#include "headers-a/header-a-v0.h"
+
+struct opaque_struct
+{
+ int m0;
+ int m1;
+ struct public_struct_type *m2;
+};
+
+struct second_opaque_struct
+{
+ int m0;
+};
+
+void foo(public_struct_pointer_type p __attribute__((unused)))
+{
+}
+
+void
+bar(second_public_struct_pointer_type p1 __attribute__((unused)),
+ second_opaque_struct_pointer_type p2 __attribute__((unused)))
+{
+}
new file mode 100644
GIT binary patch
literal 3840
zcmbtWU1%It6ux(FHko9a&8A6fLu$K%ng%+vo1_h~nsjYwo1&CZtcnn~GrN=B(fxCF
zHl+R)R4RQD3qo5cSkPC&N5L1N=tCdG2hmqweAgGz`k?3Bxo10jGohdt_TF>8^PQi2
z=gyhEa{Bo*Db5)U&Q{n1jZnslBQaTuMK;0qvWsiieqFov&Yv51Nm{$s{cYp!JqR)&
zd4>$PBj$kz@mLDw6kmc_7%MPK&jCL9BFO1Rf${xUKmv}OgaeB(sxU{yR2t3c#vDrx
zMa02@wBHOPzTnp-{|521eDqt%hrnZ!kFGq6;y}7F&-nNcAR5YDpdyT)&<a1672|)w
zf^~_BtB9bxnDk+f22sp|ph?OoN)aWqEGcpqVsHi&VOTH^NgQi3a8h}P*CgRQ5?+N#
z+6-B56k!a@5C+<YH(M>nr_dP(JuH6v78pm`V8Xzu>osP&PQdsfNrNe)1b%y@4QFr&
zPaJ3?Z8(L)mQ*e=I1v6sX2KMi>C8CaJCuC{Nc)+{oG_m@&rLuPW6YGozyuc=(?pyD
zo*sqzBGQt{*x=(pTQP+JJKD!*rjTN!8Acek`N^q>J2QnjiU)3-l7x|TFGdP3jhRS<
zLXTpx@WY1?AMuM8$KM4d#ax&<|2s1ZvwRKUym-xXDqhgBTt<?^Sm<>^i}Z>gSX%|V
zi~%FeauKNE%cB4%0%T3YQDwjuQ~dpfuTv?=m#?)NUcS<*yyoYteweTOuH*Vu$FJub
z-Fh!s9y53H6(@A0XaT9>Z*E%NHaO{Jb=cYS7jvt*WA>7LJU3sMJ6>3vU&tM~;8k*K
zP8i|V!c((3s}Xja-g4DzdVyaC)d|YA<?W?KYw=jls<Kwwd86x<I$_W)hpgRo>wZ~j
zrSNjwOMvEC$1As*l~SK?sojE?(F-E4BnCUvZI;&~)(a52paXLhxUUSYg1$8RxkQia
z;dS*T=&zieU0pqqI|AoB`|#t%n*n1oS{Q%x0^{3RKD}qi_!#cULBR2cL%yxgX0lgP
ztD}RbfdClVo<SoF`HqtPTx5?dJ7)+DE$H`uc3R--C3beid$+UCO@Jk7h^Wc!FbOue
z14BTtp<VFdU2y0X2}7{a1Qg>_7wb0*wx=He4LTQmweXapL7j3MRK!W|MNGa&*lw|r
z_I8YZ@!eBq#BrA|!4JoHw8%V&Z>UoCX}D4uwREJ#pVDlMAMbZ|49ECCD*dE}|DklM
zi|YJH)l<{>_?g1-VYKw>?<oAHhJUK`?=<|B;{UASUnu>)hJT~<N0lGdX)1k1!{x^o
zd`cQlakdnWOZ+_VXgKD<LC+NRv_zsQt7JV+YZpAHaLgIcThwsM%k0kOM(DV(hC#H}
zND95}klFY>V7A-oFgx(-j$QHGZnfk$H(Ownvg5jex7BBM0;gH^`d#XN(<2v1!R&IY
z(eU8klih5Eo(=8J>V!`Dbrr~~l{N#X;i<y^=YsDYo*|txg)1sS|9Y#(L^SpoNQmj3
z>g67zU(o$$z>M$DfAyaOUp*#fr2OA&MopFfTJT?G5uIYAs9NSP$^q{i^5|Wsb6EyV
zkBMQPRF~{?RANKtu7gd-kbY137h=9B>fGl5OR7JI%?AegWBs@#z5WVddQ5=WeU<+`
zRANKtmcW*je_iFLbHe-x>G|7$VN9wML^<A87vf7TA*r;!1?(jMqpDd@KUQITdnNx5
zlt0;NeI?#(2u$GKQkXif9`lm&r+Y{S+CS-^fRJ>4wS?z~-$e4KbH#n=xiR)vDt}FF
o6u*1;_166{jsETd#B%EXA4VlM=-ddxxJmvuRsEk4QLVcFzx`ZyR{#J2
literal 0
HcmV?d00001
new file mode 100644
@@ -0,0 +1,36 @@
+/*
+ * Compile this test with:
+ * gcc -c -g test-headers-dir-v1.c
+ *
+ * This test exhibits changes that are redundant in a weird way.
+ * The redundant path through the diff graph involves typedefs,
+ * function types and function parameter diff nodes.
+ *
+ */
+
+#include "headers-b/header-b-v1.h"
+#include "headers-a/header-a-v1.h"
+
+struct opaque_struct
+{
+ int m0;
+ int m1;
+ struct public_struct_type *m2;
+ char m3;
+};
+
+struct second_opaque_struct
+{
+ int m0;
+ char m1;
+};
+
+void foo(public_struct_pointer_type p __attribute__((unused)))
+{
+}
+
+void
+bar(second_public_struct_pointer_type p1 __attribute__((unused)),
+ second_opaque_struct_pointer_type p2 __attribute__((unused)))
+{
+}
new file mode 100644
GIT binary patch
literal 3920
zcmbtW-D@0G6hC)wHkovi?Ivk!LJMw+(iWWAe6%H2+eTyC6s4A8F)wAE*_~up_siMY
zk}4{wRQe*VAE;1NsIS@=3xY3|zW4|DF9^OU)rS%gKhC*x?q>F8s-PG4-gAEEcRudt
z>>DSZIhhdxbQ5q4HZ_d`T-~-QFDh{nCSV-SFJJj_`O0e>7w%|j`AYZhg*(4tkO9TB
zRJbiMCpY6khUAP`z+PI%uveaz*yW*|ZOnj}{17D+XF*I|SA^I{)=`mGs37dDOqQ5L
z%nY&59AvE6XK)}}Yeq0629XnImEtQDrS&!TD(j@k{fx58n%~SiM&dxWF$ZFN14S#_
zm<KUIaq}EW5-zPjiHJYQ%du&kHbs&XHwdA!<c@0yTAE@%r75E%#gts2C~Asw@L5!(
zb)F!?hp9Z(ao*v!B3vZG<sLzm9!J<tWk_Y)w%Tfe*h9ro)0--;e}@#ijV6koxmJY{
z-wQ!ZD;jn=7Q}VCjhis-#WcH(3$oWy$_oHuOgx;Muw`y{ZcL01<sZOUyFliS*pJz#
zC$Na^U@Ku@LdcwL6D|<Xj$(Z=X~6~<d<bdBY-s@uv55Jtonqe<v4^uj!M3^L_*Cq+
zZ;H|_PJZ;HBG}npxD1}NkyIkq{0P;JKiZFEL!Z?4I-(iyu@~a^+$i?y=HSwaYT#9Z
zu;cikC0wB>=tPdzE49$MIO~=va*R1X0adzh40ti1Y8s9!L$=%_-kSe5lfit&YO4_x
zE3L|lwc=VWD%NYh=hxP}TD{ol)_ci{l(|!^c#)?>2T7IM>Z%j0qmx-y2Tq+iUsx&}
zbQj!1g}Is8Lo<ix<_r7J1(m|G7sa?U|LB2&(}=pw;OJV=48mF&RWB@8kFGBqb`Bpb
zIBU>qdoOo`QYQ+#<p|nczg{b|R*EjQgA`~EIzhSBtd#nEOYIik)F6z#%!1=}O!I@2
z-Ddf0?E4%hoH2n}ovyDqqprT>|4>)Cig$#|=!@51KAc)wI#Sq=i+teU*O-n6wjJ>R
z;+1nC*7IWb$dGjv4+>pfeSOvKeIl2?oLL$jJb?tZJ<h)B&T9MV*v_Uc1BS*Y>DRxu
z7!Z)DUj)K?N3_pPq9v`#_|e;9lAzw>6ntn4Mu3Fj`{4L?q%;YmDJaF!uUfxZ!bm@W
z8op%swWC#vn|?WWqe{5edlA#mEIq&Uu=Zw5e#zPE%!Jb{pT{4yv3O8<2*1brP6KBZ
zrdXhgle=^v!B0MVZUU$HKd^q>z(;rqd;@=<@s5EnG5(o>zsvX+2Hs)(mVs;kUkrSO
z`TF4Mb^DTed)cn>+l-$uaQZ}2TQ%@G*55Jk+lmeFDdRLG*ZF$`r~K6PUXz|xNZjRF
zHsiGJgBKX5oXNb42Cnmh+qu+;JRip>jK`{$qF_A&mp&HY`kfBAVNmznO5k_bO10){
z3vEjFd_N2>_L;rVYpw<TF7;Y7&@Pw)+;XeY2=ITG+iXRFi_f6biM;Yl94M%kRzt55
zaN+-Rp!-N`sMlGCTV%ofwDUG;8cd@^nE8UO^ceku>Aw%nbg%xa|1A2NF)5?Yf6p))
zs`^Vq|2`MVDbd#XDcxWPI&Z|&Z-8ExqllR?Da;u@WH(7kG?RN4Z6-$aKiGdJ;Y*^)
zeHyW}`rGs<VblIpKTXN3zk-+<6CrSTL*67M(M)a$ZE5*G=lpt|C_h1F{x)J1Q`d>2
zYBxFmEhC{;_4q2X)BG#^Sm<|}!}jK?{oiJPZP(*_$;U>6DcnyO<L&A(KW2Y@4z)qg
zU+W*BkhXr`r0gGkE49B~SDJ^Jn_}PP{8gSPeGloYZu(Oi^X?%8D}4SRBqh=Gx@m~w
QruqNG_21A$9!>wh0TY6SUH||9
literal 0
HcmV?d00001
@@ -34,6 +34,7 @@
#include <sys/wait.h>
#include <cstring>
#include <string>
+#include <vector>
#include <fstream>
#include <iostream>
#include <cstdlib>
@@ -47,6 +48,8 @@ struct InOutSpec
const char* in_elfv0_path;
const char* in_elfv1_path;
const char* in_suppr_path;
+ const char* in_elfv0_headers_dirs;
+ const char* in_elfv1_headers_dirs;
const char* abidiff_options;
abidiff_status status;
const char* in_report_path;
@@ -59,6 +62,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test1-voffset-change-v0.o",
"data/test-abidiff-exit/test1-voffset-change-v1.o",
"",
+ "",
+ "",
"--no-default-suppression --no-show-locs",
abigail::tools_utils::ABIDIFF_ABI_CHANGE
| abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE,
@@ -69,6 +74,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test1-voffset-change-v0.o",
"data/test-abidiff-exit/test1-voffset-change-v1.o",
"data/test-abidiff-exit/test1-voffset-change.abignore",
+ "",
+ "",
"--no-default-suppression --no-show-locs",
abigail::tools_utils::ABIDIFF_OK,
"data/test-abidiff-exit/test1-voffset-change-report1.txt",
@@ -78,6 +85,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test2-filtered-removed-fns-v0.o",
"data/test-abidiff-exit/test2-filtered-removed-fns-v1.o",
"",
+ "",
+ "",
"--no-default-suppression --no-show-locs",
abigail::tools_utils::ABIDIFF_ABI_CHANGE
| abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE,
@@ -88,6 +97,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test2-filtered-removed-fns-v0.o",
"data/test-abidiff-exit/test2-filtered-removed-fns-v1.o",
"data/test-abidiff-exit/test2-filtered-removed-fns.abignore",
+ "",
+ "",
"--no-default-suppression --no-show-locs",
abigail::tools_utils::ABIDIFF_OK,
"data/test-abidiff-exit/test2-filtered-removed-fns-report1.txt",
@@ -98,6 +109,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-loc-v1.bi",
"",
"",
+ "",
+ "",
abigail::tools_utils::ABIDIFF_ABI_CHANGE,
"data/test-abidiff-exit/test-loc-with-locs-report.txt",
"output/test-abidiff-exit/test-loc-with-locs-report.txt"
@@ -106,6 +119,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-loc-v0.bi",
"data/test-abidiff-exit/test-loc-v1.bi",
"",
+ "",
+ "",
"--no-show-locs",
abigail::tools_utils::ABIDIFF_ABI_CHANGE,
"data/test-abidiff-exit/test-loc-without-locs-report.txt",
@@ -115,6 +130,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-no-stray-comma-v0.o",
"data/test-abidiff-exit/test-no-stray-comma-v1.o",
"",
+ "",
+ "",
"--leaf-changes-only",
abigail::tools_utils::ABIDIFF_ABI_CHANGE,
"data/test-abidiff-exit/test-no-stray-comma-report.txt",
@@ -124,6 +141,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-leaf-stats-v0.o",
"data/test-abidiff-exit/test-leaf-stats-v1.o",
"",
+ "",
+ "",
"--no-show-locs --leaf-changes-only",
abigail::tools_utils::ABIDIFF_ABI_CHANGE,
"data/test-abidiff-exit/test-leaf-stats-report.txt",
@@ -133,6 +152,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-leaf-more-v0.o",
"data/test-abidiff-exit/test-leaf-more-v1.o",
"",
+ "",
+ "",
"--no-show-locs --leaf-changes-only",
abigail::tools_utils::ABIDIFF_ABI_CHANGE
| abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE,
@@ -143,6 +164,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-leaf-fun-type-v0.o",
"data/test-abidiff-exit/test-leaf-fun-type-v1.o",
"",
+ "",
+ "",
"--no-show-locs --leaf-changes-only",
abigail::tools_utils::ABIDIFF_ABI_CHANGE,
"data/test-abidiff-exit/test-leaf-fun-type-report.txt",
@@ -152,6 +175,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-leaf-redundant-v0.o",
"data/test-abidiff-exit/test-leaf-redundant-v1.o",
"",
+ "",
+ "",
"--leaf-changes-only",
abigail::tools_utils::ABIDIFF_ABI_CHANGE,
"data/test-abidiff-exit/test-leaf-redundant-report.txt",
@@ -161,6 +186,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-leaf-peeling-v0.o",
"data/test-abidiff-exit/test-leaf-peeling-v1.o",
"",
+ "",
+ "",
"--leaf-changes-only",
abigail::tools_utils::ABIDIFF_ABI_CHANGE,
"data/test-abidiff-exit/test-leaf-peeling-report.txt",
@@ -170,6 +197,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-leaf-cxx-members-v0.o",
"data/test-abidiff-exit/test-leaf-cxx-members-v1.o",
"",
+ "",
+ "",
"--leaf-changes-only",
abigail::tools_utils::ABIDIFF_ABI_CHANGE
| abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE,
@@ -181,6 +210,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-member-size-v1.o",
"",
"",
+ "",
+ "",
abigail::tools_utils::ABIDIFF_ABI_CHANGE,
"data/test-abidiff-exit/test-member-size-report0.txt",
"output/test-abidiff-exit/test-member-size-report0.txt"
@@ -189,6 +220,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-member-size-v0.o",
"data/test-abidiff-exit/test-member-size-v1.o",
"",
+ "",
+ "",
"--leaf-changes-only",
abigail::tools_utils::ABIDIFF_ABI_CHANGE,
"data/test-abidiff-exit/test-member-size-report1.txt",
@@ -198,6 +231,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-decl-struct-v0.o",
"data/test-abidiff-exit/test-decl-struct-v1.o",
"",
+ "",
+ "",
"--harmless",
abigail::tools_utils::ABIDIFF_ABI_CHANGE,
"data/test-abidiff-exit/test-decl-struct-report.txt",
@@ -208,6 +243,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-fun-param-v1.abi",
"",
"",
+ "",
+ "",
abigail::tools_utils::ABIDIFF_ABI_CHANGE,
"data/test-abidiff-exit/test-fun-param-report.txt",
"output/test-abidiff-exit/test-fun-param-report.txt"
@@ -216,6 +253,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-decl-enum-v0.o",
"data/test-abidiff-exit/test-decl-enum-v1.o",
"",
+ "",
+ "",
"--harmless",
abigail::tools_utils::ABIDIFF_ABI_CHANGE,
"data/test-abidiff-exit/test-decl-enum-report.txt",
@@ -226,6 +265,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-decl-enum-v1.o",
"",
"",
+ "",
+ "",
abigail::tools_utils::ABIDIFF_OK,
"data/test-abidiff-exit/test-decl-enum-report-2.txt",
"output/test-abidiff-exit/test-decl-enum-report-2.txt"
@@ -234,6 +275,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-decl-enum-v0.o",
"data/test-abidiff-exit/test-decl-enum-v1.o",
"",
+ "",
+ "",
"--leaf-changes-only",
abigail::tools_utils::ABIDIFF_OK,
"data/test-abidiff-exit/test-decl-enum-report-3.txt",
@@ -243,6 +286,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-net-change-v0.o",
"data/test-abidiff-exit/test-net-change-v1.o",
"",
+ "",
+ "",
"--no-default-suppression --no-show-locs",
abigail::tools_utils::ABIDIFF_ABI_CHANGE
| abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE,
@@ -253,6 +298,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-net-change-v0.o",
"data/test-abidiff-exit/test-net-change-v1.o",
"data/test-abidiff-exit/test-net-change.abignore",
+ "",
+ "",
"--no-default-suppression --no-show-locs",
abigail::tools_utils::ABIDIFF_OK,
"data/test-abidiff-exit/test-net-change-report1.txt",
@@ -262,6 +309,8 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-net-change-v0.o",
"data/test-abidiff-exit/test-net-change-v1.o",
"",
+ "",
+ "",
"--no-default-suppression --no-show-locs --leaf-changes-only",
abigail::tools_utils::ABIDIFF_ABI_CHANGE
| abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE,
@@ -272,44 +321,90 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-net-change-v0.o",
"data/test-abidiff-exit/test-net-change-v1.o",
"data/test-abidiff-exit/test-net-change.abignore",
+ "",
+ "",
"--no-default-suppression --no-show-locs --leaf-changes-only",
abigail::tools_utils::ABIDIFF_OK,
"data/test-abidiff-exit/test-net-change-report3.txt",
"output/test-abidiff-exit/test-net-change-report3.txt"
},
- {0, 0, 0 ,0, abigail::tools_utils::ABIDIFF_OK, 0, 0}
+ {
+ "data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.o",
+ "data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.o",
+ "",
+ "data/test-abidiff-exit/test-headers-dirs/headers-a",
+ "data/test-abidiff-exit/test-headers-dirs/headers-a",
+ "--no-default-suppression",
+ abigail::tools_utils::ABIDIFF_OK,
+ "data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-1.txt",
+ "output/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-1.txt"
+ },
+ {
+ "data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v0.o",
+ "data/test-abidiff-exit/test-headers-dirs/test-headers-dir-v1.o",
+ "",
+ "data/test-abidiff-exit/test-headers-dirs/headers-a, "
+ "data/test-abidiff-exit/test-headers-dirs/headers-b",
+ "data/test-abidiff-exit/test-headers-dirs/headers-a, "
+ "data/test-abidiff-exit/test-headers-dirs/headers-b",
+ "--no-default-suppression",
+ abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+ "data/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-2.txt",
+ "output/test-abidiff-exit/test-headers-dirs/test-headers-dir-report-2.txt"
+ },
+ {0, 0, 0 ,0, 0, 0, abigail::tools_utils::ABIDIFF_OK, 0, 0}
};
+/// Prefix the strings in a vector of string.
+///
+/// @param strings the strings to prefix.
+///
+/// @param prefix the prefix to use.
+static void
+do_prefix_strings(std::vector<std::string> &strings,
+ const std::string& prefix)
+{
+ for (std::vector<std::string>::size_type i = 0; i < strings.size(); ++i)
+ strings[i] = prefix + strings[i];
+}
+
int
main()
{
using std::string;
+ using std::vector;
using std::cerr;
using abigail::tests::get_src_dir;
using abigail::tests::get_build_dir;
using abigail::tools_utils::ensure_parent_dir_created;
+ using abigail::tools_utils::split_string;
using abigail::tools_utils::abidiff_status;
bool is_ok = true;
string in_elfv0_path, in_elfv1_path,
in_suppression_path, abidiff_options, abidiff, cmd,
ref_diff_report_path, out_diff_report_path;
+ vector<string> in_elfv0_headers_dirs, in_elfv1_headers_dirs;
+ string source_dir_prefix = string(get_src_dir()) + "/tests/";
+ string build_dir_prefix = string(get_build_dir()) + "/tests/";
for (InOutSpec* s = in_out_specs; s->in_elfv0_path; ++s)
{
- in_elfv0_path = string(get_src_dir()) + "/tests/" + s->in_elfv0_path;
- in_elfv1_path = string(get_src_dir()) + "/tests/" + s->in_elfv1_path;
+ in_elfv0_path = source_dir_prefix + s->in_elfv0_path;
+ in_elfv1_path = source_dir_prefix + s->in_elfv1_path;
+ split_string(s->in_elfv0_headers_dirs, ",", in_elfv0_headers_dirs);
+ split_string(s->in_elfv1_headers_dirs, ",", in_elfv1_headers_dirs);
+ do_prefix_strings(in_elfv0_headers_dirs, source_dir_prefix);
+ do_prefix_strings(in_elfv1_headers_dirs, source_dir_prefix);
+
if (s->in_suppr_path && strcmp(s->in_suppr_path, ""))
- in_suppression_path =
- string(get_src_dir()) + "/tests/" + s->in_suppr_path;
+ in_suppression_path = source_dir_prefix + s->in_suppr_path;
else
in_suppression_path.clear();
abidiff_options = s->abidiff_options;
- ref_diff_report_path =
- string(get_src_dir()) + "/tests/" + s->in_report_path;
- out_diff_report_path =
- string(get_build_dir()) + "/tests/" + s->out_report_path;
+ ref_diff_report_path = source_dir_prefix + s->in_report_path;
+ out_diff_report_path = build_dir_prefix + s->out_report_path;
if (!ensure_parent_dir_created(out_diff_report_path))
{
@@ -323,6 +418,18 @@ main()
if (!abidiff_options.empty())
abidiff += " " + abidiff_options;
+ if (!in_elfv0_headers_dirs.empty())
+ for (vector<string>::const_iterator s = in_elfv0_headers_dirs.begin();
+ s != in_elfv0_headers_dirs.end();
+ ++s)
+ abidiff += " --headers-dir1 " + *s;
+
+ if (!in_elfv1_headers_dirs.empty())
+ for (vector<string>::const_iterator s = in_elfv1_headers_dirs.begin();
+ s != in_elfv1_headers_dirs.end();
+ ++s)
+ abidiff += " --headers-dir2 " + *s;
+
if (!in_suppression_path.empty())
abidiff += " --suppressions " + in_suppression_path;
@@ -78,9 +78,9 @@ struct options
vector<string> drop_var_regex_patterns;
vector<string> keep_fn_regex_patterns;
vector<string> keep_var_regex_patterns;
- string headers_dir1;
+ vector<string> headers_dirs1;
vector<string> header_files1;
- string headers_dir2;
+ vector<string> headers_dirs2;
vector<string> header_files2;
bool drop_private_types;
bool linux_kernel_mode;
@@ -318,7 +318,9 @@ parse_command_line(int argc, char* argv[], options& opts)
opts.wrong_option = argv[i];
return true;
}
- opts.headers_dir1 = argv[j];
+ // The user can specify several header files directories for
+ // the first binary.
+ opts.headers_dirs1.push_back(argv[j]);
++i;
}
else if (!strcmp(argv[i], "--header-file1")
@@ -344,7 +346,9 @@ parse_command_line(int argc, char* argv[], options& opts)
opts.wrong_option = argv[i];
return true;
}
- opts.headers_dir2 = argv[j];
+ // The user can specify several header files directories for
+ // the first binary.
+ opts.headers_dirs2.push_back(argv[j]);
++i;
}
else if (!strcmp(argv[i], "--header-file2")
@@ -720,22 +724,22 @@ set_diff_context_from_opts(diff_context_sptr ctxt,
load_default_user_suppressions(supprs);
}
- if (!opts.headers_dir1.empty() || !opts.header_files1.empty())
+ if (!opts.headers_dirs1.empty() || !opts.header_files1.empty())
{
// Generate suppression specification to avoid showing ABI
// changes on types that are not defined in public headers.
suppression_sptr suppr =
- gen_suppr_spec_from_headers(opts.headers_dir1, opts.header_files1);
+ gen_suppr_spec_from_headers(opts.headers_dirs1, opts.header_files1);
if (suppr)
ctxt->add_suppression(suppr);
}
- if (!opts.headers_dir2.empty() || !opts.header_files2.empty())
+ if (!opts.headers_dirs2.empty() || !opts.header_files2.empty())
{
// Generate suppression specification to avoid showing ABI
// changes on types that are not defined in public headers.
suppression_sptr suppr =
- gen_suppr_spec_from_headers(opts.headers_dir2, opts.header_files2);
+ gen_suppr_spec_from_headers(opts.headers_dirs2, opts.header_files2);
if (suppr)
ctxt->add_suppression(suppr);
}
@@ -770,7 +774,7 @@ set_suppressions(ReadContextType& read_ctxt, const options& opts)
read_suppressions(*i, supprs);
if (read_context_get_path(read_ctxt) == opts.file1
- && (!opts.headers_dir1.empty() || !opts.header_files1.empty()))
+ && (!opts.headers_dirs1.empty() || !opts.header_files1.empty()))
{
// Generate suppression specification to avoid showing ABI
// changes on types that are not defined in public headers for
@@ -780,7 +784,7 @@ set_suppressions(ReadContextType& read_ctxt, const options& opts)
// corpus loading, they are going to be dropped from the
// internal representation altogether.
suppression_sptr suppr =
- gen_suppr_spec_from_headers(opts.headers_dir1, opts.header_files1);
+ gen_suppr_spec_from_headers(opts.headers_dirs1, opts.header_files1);
if (suppr)
{
if (opts.drop_private_types)
@@ -790,7 +794,7 @@ set_suppressions(ReadContextType& read_ctxt, const options& opts)
}
if (read_context_get_path(read_ctxt) == opts.file2
- && (!opts.headers_dir2.empty() || !opts.header_files2.empty()))
+ && (!opts.headers_dirs2.empty() || !opts.header_files2.empty()))
{
// Generate suppression specification to avoid showing ABI
// changes on types that are not defined in public headers for
@@ -800,7 +804,7 @@ set_suppressions(ReadContextType& read_ctxt, const options& opts)
// corpus loading, they are going to be dropped from the
// internal representation altogether.
suppression_sptr suppr =
- gen_suppr_spec_from_headers(opts.headers_dir2, opts.header_files2);
+ gen_suppr_spec_from_headers(opts.headers_dirs2, opts.header_files2);
if (suppr)
{
if (opts.drop_private_types)
@@ -90,7 +90,7 @@ struct options
string out_file_path;
vector<char*> di_root_paths;
vector<char**> prepared_di_root_paths;
- string headers_dir;
+ vector<string> headers_dirs;
vector<string> header_files;
string vmlinux;
vector<string> suppression_paths;
@@ -239,7 +239,7 @@ parse_command_line(int argc, char* argv[], options& opts)
int j = i + 1;
if (j >= argc)
return false;
- opts.headers_dir = argv[j];
+ opts.headers_dirs.push_back(argv[j]);
++i;
}
else if (!strcmp(argv[i], "--header-file")
@@ -445,7 +445,7 @@ set_suppressions(read_context& read_ctxt, options& opts)
read_suppressions(*i, supprs);
suppression_sptr suppr =
- abigail::tools_utils::gen_suppr_spec_from_headers(opts.headers_dir,
+ abigail::tools_utils::gen_suppr_spec_from_headers(opts.headers_dirs,
opts.header_files);
if (suppr)
{