Соединение Библиотек с Дублирующимися Именами классов с помощью GCC

Существует ли путь к GCC для создания предупреждения при соединении библиотек, которые содержат классы с тем же именем? Например,

Port.h

class Port {
public:
  std::string me();
};

Port.cpp

#include "Port.h"
std::string Port::me() { return "Port"; }

FakePort.h

class Port {
public:
  std::string me();
};

FakePort.cpp

#include "FakePort.h"
std::string Port::me() { return "FakePort"; }

main.cpp

#include "Port.h"

int main() {
  Port port;
  std::cout << "Hello world from " << port.me() << std::endl;
  return 0;
}

Создание

# g++ -c -o Port.o Port.cpp
# ar rc Port.a Port.o
# g++ -c -o FakePort.o FakePort.cpp
# ar rc FakePort.a FakePort.o
# g++ -c -o main.o main.cpp
# g++ main.o Port.a FakePort.a
# ./a.out
  Hello world from Port

Порядок библиотеки изменения

# g++ main.o FakePort.a Port.a
# ./a.out
  Hello world from FakePort

Согласно этой странице:

Если символ будет определен в двух различных библиотеках gcc, то будет использовать первый, который он находит, и проигнорируйте второй, если второй не включен в объектный файл, который включен по некоторой другой причине.

Так вышеупомянутое поведение имеют смысл. К сожалению, я наследовал значительную кодовую базу, которая не использует пространства имен (и добавление их не выполнимо прямо сейчас), и использует некоторые универсальные имена классов всюду по нескольким библиотекам. Я хотел бы автоматически обнаружить двойные названия во время ссылки, чтобы удостовериться, что неправильная копия класса случайно не является инстанцированием. Что-то как:

# g++ -Wl,--warnLibraryDupSymbols main.o FakePort.a Port.a
  Warning: Duplicate symbol: Port

но я ничего не могу найти в опциях компоновщика GCC сделать это. Действительно ли возможно заставить GCC автоматически обнаруживать и сообщать о таких случаях?

11
задан joesdiner 4 May 2010 в 14:13
поделиться

4 ответа

Возможно, стоит попробовать следующее (честно говоря, я не знаю, будет ли это делать то, что вы хотите):

--whole-archive

Для каждого архива, упомянутого в командной строке после опции --whole-archive, включите в ссылку каждый объектный файл из архива, вместо того чтобы искать в архиве нужные объектные файлы. Обычно это используется для превращения архивного файла в разделяемую библиотеку, заставляя каждый объект быть включенным в результирующую разделяемую библиотеку. Эта опция может быть использована более одного раза.

Я не пробовал, но похоже, что он будет включать все объекты в библиотеку, как если бы они были объектными файлами. Вам нужно будет указать эту опцию для каждой библиотеки.

Как сказал Нил, это не даст вам конфликтов на уровне классов, но если есть члены класса с одинаковой сигнатурой, это может заставить компоновщик сообщить вам об этом.

3
ответ дан 3 December 2019 в 11:51
поделиться

Нет, не существует. Причина этого в том, что имя класса не является символом для компоновщика. Компилятор C ++ будет использовать имя класса для создания искаженных имен функций, но само имя класса исчезнет к моменту включения компоновщика.

0
ответ дан 3 December 2019 в 11:51
поделиться

В качестве альтернативы вы можете использовать скрипт, использующий nm для поиска кандидатов, например, что-то вроде:

import collections, subprocess, os, re, sys

def filt(s):
  p = subprocess.Popen(['c++filt', s],stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  return p.communicate()[0].strip()

rx  = re.compile('^[\\d\\w]+ T [\\w]+', re.MULTILINE)
sym = collections.defaultdict(set)

for file in sys.argv[1:]:
  proc = subprocess.Popen(['nm', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  for s in rx.findall(proc.communicate()[0]):
    sym[s.split()[2]].add(file)

for s in filter(lambda x: len(sym[x])>1, sym):
    print 'Duplicate "%s" in %s' % (filt(s), str(sym[s]))

foo:$ python dups.py *.a  
Duplicate "Port::me()" in set(['Port.a', 'FakePort.a'])
1
ответ дан 3 December 2019 в 11:51
поделиться

Я тоже не вижу никаких вариантов, чтобы делать то, что вы хотите. Возможно, подумайте горизонтально и используйте инструмент документации кода, такой как Doxygen, чтобы создать документацию для всех ваших классов и вручную искать дубликаты

0
ответ дан 3 December 2019 в 11:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: