new tool to test gcc4/5 ABI
This commit is contained in:
parent
9a47744fc0
commit
ba6e274efa
19
tools/gccabicheck/Makefile
Normal file
19
tools/gccabicheck/Makefile
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
CFLAGS = -Wall
|
||||||
|
LOADLIBES = -ldl
|
||||||
|
|
||||||
|
gcc-glibmm-abi-check:
|
||||||
|
$(CC) $(CPPFLAGS) $(CFLAGS) \
|
||||||
|
-o gcc-glibmm-abi-check \
|
||||||
|
abicheck.c \
|
||||||
|
$(LDFLAGS) $(LOADLIBES)
|
||||||
|
|
||||||
|
check: gcc-glibmm-abi-check
|
||||||
|
./gcc-glibmm-abi-check
|
||||||
|
|
||||||
|
gcc-glibmm-abi-check.1: gcc-glibmm-abi-check
|
||||||
|
help2man -N \
|
||||||
|
-n 'glib gcc4/5 C++11 ABI compatibility test' \
|
||||||
|
-o gcc-glibmm-abi-check.1 \
|
||||||
|
./gcc-glibmm-abi-check
|
||||||
|
|
||||||
|
.PHONY: check
|
34
tools/gccabicheck/README
Normal file
34
tools/gccabicheck/README
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
g++5 ABI test tool
|
||||||
|
==================
|
||||||
|
|
||||||
|
This is a simple tool to test a system for g++5's glibmm at runtime.
|
||||||
|
|
||||||
|
GCC5.1 introduced a new ABI for the C++ standard library.
|
||||||
|
The old 3.4 .. 5.0 ABI is not compatible. By default gcc provides a
|
||||||
|
dual ABI, so testing libstc++ itself is not sufficient.
|
||||||
|
|
||||||
|
|
||||||
|
Some GNU/Linux distributions systems switched to the new ABI already
|
||||||
|
and compile *plugins* with the new gcc.
|
||||||
|
|
||||||
|
If a plugin uses a c++ library that is also shipped with ardour-bundles,
|
||||||
|
the ABI of that library must match. Currently known cases: gtkmm, glibmm.
|
||||||
|
|
||||||
|
e.g. Ingen or eq10q provided by a distro compiled with gcc5 will not
|
||||||
|
load in Ardour from ardour.org compiled with gcc4 because ardour
|
||||||
|
ships an incompatible gtkmm, glibmm, cairomm, ...
|
||||||
|
|
||||||
|
Likewise Ardour gcc5-compiled binaries will fail to load plugins that
|
||||||
|
are compiled with gcc4.
|
||||||
|
|
||||||
|
This simiple tool `gcc-glibmm-abi-check` checks for gcc4/gcc5 specific
|
||||||
|
symbols in libglibmm (a common denominator C++ lib), it is intended
|
||||||
|
to be run when deploying ardour binaries.
|
||||||
|
|
||||||
|
|
||||||
|
References
|
||||||
|
----------
|
||||||
|
|
||||||
|
https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
|
||||||
|
https://wiki.debian.org/GCC5
|
||||||
|
https://mail.gnome.org/archives/gtkmm-list/2015-June/thread.html
|
166
tools/gccabicheck/abicheck.c
Normal file
166
tools/gccabicheck/abicheck.c
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
// gcc -Wall -o gcc-glibmm-abi-check abicheck.c -ldl
|
||||||
|
// help2man -N -n 'glib gcc4/5 C++11 ABI compatibility test' -o gcc-glibmm-abi-check.1 ./gcc-glibmm-abi-check
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
|
#ifndef VERSION
|
||||||
|
#define VERSION "0.1"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void print_usage (void) {
|
||||||
|
printf ("gcc-glibmm-abi-check - gcc4/5 C++11 ABI compatibility test\n\n");
|
||||||
|
|
||||||
|
printf ("Usage: gcc-glibmm-abi-check [ OPTIONS ]\n\n");
|
||||||
|
printf (
|
||||||
|
"This tool checks for C++ specific symbols in libglimm which are different in\n"
|
||||||
|
"the gcc4 and gcc5/c++11 ABI in order to determine system-wide use of gcc5.\n"
|
||||||
|
// TODO document error codes,...
|
||||||
|
);
|
||||||
|
|
||||||
|
printf ("\nOptions:\n"
|
||||||
|
" -f, --fail fail if system cannot be determined.\n"
|
||||||
|
" -h, --help Display this help and exit.\n"
|
||||||
|
" -4, --gcc4 Test succeeds if gcc4 ABI is found.\n"
|
||||||
|
" -5, --gcc5 Test succeeds if gcc5 ABI is found.\n"
|
||||||
|
" -g <soname>, --glibmm <soname>\n"
|
||||||
|
" Specify alternative file for libglibmm-2.4.so\n"
|
||||||
|
" -v, --verbose Print information.\n"
|
||||||
|
" -V, --version Print version information and exit.\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_version (void) {
|
||||||
|
printf ("gcc-glibmm-abi-check version %s\n\n", VERSION);
|
||||||
|
printf (
|
||||||
|
"Copyright (C) GPL 2015 Robin Gareus <robin@gareus.org>\n"
|
||||||
|
"This is free software; see the source for copying conditions. There is NO\n"
|
||||||
|
"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main (int argc, char **argv) {
|
||||||
|
int expect = 0;
|
||||||
|
int error_fail = 0;
|
||||||
|
int verbose = 0;
|
||||||
|
|
||||||
|
char *glibmm = "libglibmm-2.4.so";
|
||||||
|
|
||||||
|
const struct option long_options[] = {
|
||||||
|
{ "help", no_argument, 0, 'h' },
|
||||||
|
{ "gcc4", no_argument, 0, '4' },
|
||||||
|
{ "gcc5", no_argument, 0, '5' },
|
||||||
|
{ "glibmm", required_argument, 0, 'g' },
|
||||||
|
{ "version", no_argument, 0, 'V' },
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *optstring = "fh45g:vV";
|
||||||
|
|
||||||
|
int c;
|
||||||
|
while ((c = getopt_long (argc, argv, optstring, long_options, NULL)) != -1) {
|
||||||
|
switch (c) {
|
||||||
|
case 'f':
|
||||||
|
error_fail = 1;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
print_usage ();
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case '4':
|
||||||
|
expect |= 1;
|
||||||
|
break;
|
||||||
|
case '5':
|
||||||
|
expect |= 2;
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
glibmm = optarg;
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
verbose = 1;
|
||||||
|
break;
|
||||||
|
case 'V':
|
||||||
|
print_version ();
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf (stderr, "invalid argument.\n");
|
||||||
|
print_usage ();
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int gcc5 = 0;
|
||||||
|
int gcc4 = 0;
|
||||||
|
|
||||||
|
dlerror (); // reset error
|
||||||
|
|
||||||
|
void *h = dlopen (glibmm, RTLD_LAZY);
|
||||||
|
if (!h) {
|
||||||
|
if (verbose) {
|
||||||
|
fprintf (stderr, "Cannot open '%s': %s.\n", glibmm, dlerror ());
|
||||||
|
}
|
||||||
|
return error_fail ? 3 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Glib::ustring::ustring(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
|
||||||
|
if (dlsym (h, "_ZN4Glib7ustringC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE")) {
|
||||||
|
gcc5 |= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Glib::ustring::ustring(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
|
||||||
|
if (dlsym (h, "_ZN4Glib7ustringC1ERKSs")) {
|
||||||
|
gcc4 |= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Glib::Module::Module(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Glib::ModuleFlags)
|
||||||
|
if (dlsym (h, "_ZN4Glib6ModuleC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_11ModuleFlagsE")) {
|
||||||
|
gcc5 |= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Glib::Module::Module(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Glib::ModuleFlags)
|
||||||
|
if (dlsym (h, "_ZN4Glib6ModuleC1ERKSsNS_11ModuleFlagsE")) {
|
||||||
|
gcc4 |= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Glib::ustring::operator=(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
|
||||||
|
if (dlsym (h, "_ZN4Glib7ustringaSERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE")) {
|
||||||
|
gcc5 |= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Glib::ustring::operator=(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
|
||||||
|
if (dlsym (h, "_ZN4Glib7ustringaSERKSs")) {
|
||||||
|
gcc4 |= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
dlclose (h);
|
||||||
|
|
||||||
|
if (7 != (gcc4 ^ gcc5)) {
|
||||||
|
if (verbose) {
|
||||||
|
fprintf (stderr, "Inconsistent result: gcc4=%x gcc5=%x\n", gcc4, gcc5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (gcc4 == 7) {
|
||||||
|
if (verbose) {
|
||||||
|
printf ("System uses gcc4 c++ ABI\n");
|
||||||
|
}
|
||||||
|
if (expect != 0) {
|
||||||
|
return (expect & 1) ? 0 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (gcc5 == 7) {
|
||||||
|
if (verbose) {
|
||||||
|
printf ("System uses gcc5 c++11 ABI\n");
|
||||||
|
}
|
||||||
|
if (expect != 0) {
|
||||||
|
return (expect & 2) ? 0 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (verbose) {
|
||||||
|
fprintf (stderr, "Incomplete result: gcc4=%x gcc5=%x\n", gcc4, gcc5);
|
||||||
|
}
|
||||||
|
|
||||||
|
return error_fail ? 2 : 0;
|
||||||
|
}
|
22
tools/gccabicheck/wscript
Normal file
22
tools/gccabicheck/wscript
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
from waflib.extras import autowaf as autowaf
|
||||||
|
from waflib import Options
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Mandatory variables
|
||||||
|
top = '.'
|
||||||
|
out = 'build'
|
||||||
|
|
||||||
|
def options(opt):
|
||||||
|
autowaf.set_options(opt)
|
||||||
|
|
||||||
|
def configure(conf):
|
||||||
|
conf.load('compiler_c')
|
||||||
|
autowaf.configure(conf)
|
||||||
|
|
||||||
|
def build(bld):
|
||||||
|
obj = bld(features = 'c cprogram')
|
||||||
|
obj.source = [ 'abicheck.c' ]
|
||||||
|
obj.target = 'gcc-glibmm-abi-check'
|
||||||
|
obj.name = 'gcc-glibmm-abi-check'
|
||||||
|
obj.lib = 'dl'
|
2
wscript
2
wscript
@ -1070,6 +1070,7 @@ int main () { int x = SFC_AUTO_DOWNGRADE_RF64; return 0; }
|
|||||||
sub_config_and_use(conf, 'libs/appleutility')
|
sub_config_and_use(conf, 'libs/appleutility')
|
||||||
elif Options.options.dist_target != 'mingw':
|
elif Options.options.dist_target != 'mingw':
|
||||||
sub_config_and_use(conf, 'tools/sanity_check')
|
sub_config_and_use(conf, 'tools/sanity_check')
|
||||||
|
sub_config_and_use(conf, 'tools/gccabicheck')
|
||||||
|
|
||||||
sub_config_and_use(conf, 'libs/clearlooks-newer')
|
sub_config_and_use(conf, 'libs/clearlooks-newer')
|
||||||
|
|
||||||
@ -1185,6 +1186,7 @@ def build(bld):
|
|||||||
bld.recurse('libs/appleutility')
|
bld.recurse('libs/appleutility')
|
||||||
elif bld.env['build_target'] != 'mingw':
|
elif bld.env['build_target'] != 'mingw':
|
||||||
bld.recurse('tools/sanity_check')
|
bld.recurse('tools/sanity_check')
|
||||||
|
bld.recurse('tools/gccabicheck')
|
||||||
|
|
||||||
bld.recurse('libs/clearlooks-newer')
|
bld.recurse('libs/clearlooks-newer')
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user