Make abipkgdiff compare directories containing binaries

abipkgdiff knows how to compare the ABI of binaries contained in .deb
and .rpm files.  This patch adds support for comparing the ABI of
binaries contained in two directories.

	* include/abg-tools-utils.h (enum file_type): Add a new
	FILE_TYPE_DIR enumerator.
	* src/abg-tools-utils.cc (operator<<(ostream&, file_type)):
	Support serialization of the new FILE_TYPE_DIR enumerator.
	(guess_file_type): Detect that the path given is a directory.
	* tools/abipkgdiff.cc (package::package): If the package is a
	directory, then set its extracted directory path to the path of
	the directory.
	(package::erase_extraction_directory): Do not erase the extraction
	directory if the package is a directory provided by the user.
	(extract_package): If the package is a directory provided by the
	user, then there is nothing to extract.
	(main): If the first package is a directory, then the second one
	should be a directory as well.
	* tools/abidiff.cc (main): Support directories as input.
	* tools/abilint.cc (main): Likewise.
	* tests/data/test-diff-pkg/dirpkg-0-dir{1,2}/libobj-v0.so: New
	binary test inputs.
	* test/data/test-diff-pkg/dirpkg-0-report-0.txt: New input test
	file.
	* tests/data/test-diff-pkg/dirpkg-1-dir{1,2}/obj-v0.cc: Source
	code of the binary test inputs above.
	* tests/data/Makefile.am: Add the new files above to the source
	distribution.
	* tests/test-diff-pkg.cc (in_out_specs): Add the new test input
	files above to the set of tests this harness has to run over.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2015-08-22 11:44:08 +02:00
parent ae5e1be5c3
commit d7dbbf0d50
12 changed files with 101 additions and 2 deletions

View File

@ -117,6 +117,8 @@ enum file_type
FILE_TYPE_SRPM,
/// An DEB (.deb) binary file
FILE_TYPE_DEB,
/// A plain directory
FILE_TYPE_DIR
};
/// Exit status for abidiff and abicompat tools.

View File

@ -474,6 +474,9 @@ operator<<(ostream& output,
case FILE_TYPE_DEB:
repr = "Debian binary file type";
break;
case FILE_TYPE_DIR:
repr = "Directory type";
break;
}
output << repr;
@ -578,6 +581,9 @@ guess_file_type(istream& in)
file_type
guess_file_type(const string& file_path)
{
if (is_dir(file_path))
return FILE_TYPE_DIR;
ifstream in(file_path.c_str(), ifstream::binary);
file_type r = guess_file_type(in);
in.close();

View File

@ -831,4 +831,9 @@ test-diff-pkg/libsigc++-2.0-0c2a-dbgsym_2.4.0-1_amd64.ddeb \
test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt \
test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64.deb \
test-diff-pkg/libsigc++-2.0-0v5-dbgsym_2.4.1-1ubuntu2_amd64.ddeb \
test-diff-pkg/libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64.deb
test-diff-pkg/libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64.deb \
test-diff-pkg/dirpkg-0-dir1/libobj-v0.so \
test-diff-pkg/dirpkg-0-dir2/libobj-v0.so \
test-diff-pkg/dirpkg-0-report-0.txt \
test-diff-pkg/dirpkg-0-dir1/obj-v0.cc \
test-diff-pkg/dirpkg-0-dir2/obj-v0.cc

Binary file not shown.

View File

@ -0,0 +1,15 @@
// Compile with:
// g++ -g -shared -o libobj-v0.so obj-v0.cc
struct S
{
int mem0;
S()
: mem0()
{}
};
void
bar(S&)
{}

Binary file not shown.

View File

@ -0,0 +1,17 @@
// Compile with:
// g++ -g -shared -o libobj-v0.so obj-v0.cc
struct S
{
int mem0;
char mem1;
S()
: mem0(),
mem1()
{}
};
void
bar(S&)
{}

View File

@ -0,0 +1,16 @@
================ changes of 'libobj-v0.so'===============
Functions changes summary: 0 Removed, 1 Changed, 0 Added function
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1 function with some indirect sub-type change:
[C]'function void bar(S&)' has some indirect sub-type changes:
parameter 1 of type 'S&' has sub-type changes:
in referenced type 'struct S':
type size changed from 32 to 64 bits
1 data member insertion:
'char S::mem1', at offset 32 (in bits)
================ end of changes of 'libobj-v0.so'===============

View File

@ -54,6 +54,15 @@ struct InOutSpec
static InOutSpec in_out_specs[] =
{
{
"data/test-diff-pkg/dirpkg-0-dir1",
"data/test-diff-pkg/dirpkg-0-dir2",
"",
"",
"",
"data/test-diff-pkg/dirpkg-0-report-0.txt",
"output/test-diff-pkg/dirpkg-0-report-0.txt"
},
#ifdef WITH_RPM
// Two RPM packages with debuginfo available and have ABI changes
{

View File

@ -565,6 +565,8 @@ main(int argc, char* argv[])
break;
case abigail::tools_utils::FILE_TYPE_DEB:
break;
case abigail::tools_utils::FILE_TYPE_DIR:
break;
}
switch (t2_type)
@ -605,6 +607,8 @@ main(int argc, char* argv[])
break;
case abigail::tools_utils::FILE_TYPE_DEB:
break;
case abigail::tools_utils::FILE_TYPE_DIR:
break;
}
if (!t1 && !c1)

View File

@ -229,6 +229,8 @@ main(int argc, char* argv[])
break;
case abigail::tools_utils::FILE_TYPE_DEB:
break;
case abigail::tools_utils::FILE_TYPE_DIR:
break;
}
if (!tu && !corp)

View File

@ -195,7 +195,10 @@ public:
is_debug_info_(is_debug_info)
{
type_ = guess_file_type(path);
extracted_dir_path_ = extracted_packages_parent_dir() + "/" + dir;
if (type_ == abigail::tools_utils::FILE_TYPE_DIR)
extracted_dir_path_ = path;
else
extracted_dir_path_ = extracted_packages_parent_dir() + "/" + dir;
}
/// Getter of the path of the package.
@ -300,6 +303,12 @@ public:
void
erase_extraction_directory() const
{
if (type() == abigail::tools_utils::FILE_TYPE_DIR)
// If we are comparing two directories, do not erase the
// directory as it was provided by the user; it's not a
// temporary directory we created ourselves.
return;
if (verbose)
cerr << "Erasing temporary extraction directory "
<< extracted_dir_path()
@ -540,6 +549,12 @@ extract_package(const package& package)
return false;
#endif // WITH_DEB
break;
case abigail::tools_utils::FILE_TYPE_DIR:
// The input package is just a directory that contains binaries,
// there is nothing to extract.
break;
default:
return false;
}
@ -1128,6 +1143,14 @@ main(int argc, char* argv[])
}
break;
case abigail::tools_utils::FILE_TYPE_DIR:
if (second_package->type() != abigail::tools_utils::FILE_TYPE_DIR)
{
cerr << opts.package2 << " should be a directory\n";
return 1;
}
break;
default:
cerr << opts.package1 << " should be a valid package file \n";
return 1;