1 /* Copyright (C) 2015 Robin Gareus <robin@gareus.org>
3 * This program is free software. It comes without any warranty, to
4 * the extent permitted by applicable law. You can redistribute it
5 * and/or modify it under the terms of the Do What The Fuck You Want
6 * To Public License, Version 2, as published by Sam Hocevar. See
7 * http://www.wtfpl.net/ for more details.
10 // gcc -Wall -o gcc-glibmm-abi-check abicheck.c -ldl
11 // help2man -N -n 'glib gcc4/5 C++11 ABI compatibility test' -o gcc-glibmm-abi-check.1 ./gcc-glibmm-abi-check
21 static void print_usage (void) {
22 printf ("gcc-glibmm-abi-check - gcc4/5 C++11 ABI compatibility test\n\n");
24 printf ("Usage: gcc-glibmm-abi-check [ OPTIONS ]\n\n");
26 "This tool checks for C++ specific symbols in libglimm which are different in\n"
27 "the gcc4 and gcc5/c++11 ABI in order to determine system-wide use of gcc5.\n"
28 // TODO document error codes,...
31 printf ("\nOptions:\n"
32 " -f, --fail fail if system cannot be determined.\n"
33 " -h, --help Display this help and exit.\n"
34 " -4, --gcc4 Test succeeds if gcc4 ABI is found.\n"
35 " -5, --gcc5 Test succeeds if gcc5 ABI is found.\n"
36 " -g <soname>, --glibmm <soname>\n"
37 " Specify alternative file for libglibmm-2.4.so\n"
38 " -v, --verbose Print information.\n"
39 " -V, --version Print version information and exit.\n"
43 static void print_version (void) {
44 printf ("gcc-glibmm-abi-check version %s\n\n", VERSION);
46 "Copyright (C) 2015 Robin Gareus <robin@gareus.org>\n"
47 "This is free software; see the source for copying conditions. There is NO\n"
48 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
52 int main (int argc, char **argv) {
57 char const * glibmm = "libglibmm-2.4.so.1";
59 const struct option long_options[] = {
60 { "fail", no_argument, 0, 'f' },
61 { "help", no_argument, 0, 'h' },
62 { "gcc4", no_argument, 0, '4' },
63 { "gcc5", no_argument, 0, '5' },
64 { "glibmm", required_argument, 0, 'g' },
65 { "verbose", no_argument, 0, 'v' },
66 { "version", no_argument, 0, 'V' },
69 const char *optstring = "fh45g:vV";
72 while ((c = getopt_long (argc, argv, optstring, long_options, NULL)) != -1) {
98 fprintf (stderr, "invalid argument.\n");
108 dlerror (); // reset error
110 void *h = dlopen (glibmm, RTLD_LAZY);
113 fprintf (stderr, "Cannot open '%s': %s.\n", glibmm, dlerror ());
115 return error_fail ? 3 : 0;
118 // Glib::ustring::ustring(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
119 if (dlsym (h, "_ZN4Glib7ustringC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE")) {
123 // Glib::ustring::ustring(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
124 if (dlsym (h, "_ZN4Glib7ustringC1ERKSs")) {
129 // Glib::Module::Module(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Glib::ModuleFlags)
130 if (dlsym (h, "_ZN4Glib6ModuleC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_11ModuleFlagsE")) {
134 // Glib::Module::Module(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Glib::ModuleFlags)
135 if (dlsym (h, "_ZN4Glib6ModuleC1ERKSsNS_11ModuleFlagsE")) {
140 // Glib::ustring::operator=(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
141 if (dlsym (h, "_ZN4Glib7ustringaSERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE")) {
145 // Glib::ustring::operator=(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
146 if (dlsym (h, "_ZN4Glib7ustringaSERKSs")) {
152 if (7 != (gcc4 ^ gcc5)) {
154 fprintf (stderr, "Inconsistent result: gcc4=%x gcc5=%x\n", gcc4, gcc5);
157 else if (gcc4 == 7) {
159 printf ("System uses gcc4 c++ ABI\n");
162 return (expect & 1) ? 0 : 1;
165 else if (gcc5 == 7) {
167 printf ("System uses gcc5 c++11 ABI\n");
170 return (expect & 2) ? 0 : 1;
174 fprintf (stderr, "Incomplete result: gcc4=%x gcc5=%x\n", gcc4, gcc5);
177 return error_fail ? 2 : 0;