Как я могу избежать “дублирующегося символа” ошибки в XCode с общими статическими библиотеками?

У меня есть статические библиотеки A, B и C, организованный в проекты XCode. A и B зависят от C. Когда я разрабатываю проект iPhone, который зависит от A и B, я получаю ошибку компоновщика, что дублирующийся символ (от C) был обнаружен в A и B. Как я могу организовать эти три статических библиотеки, таким образом, я могу включать их в другие проекты XCode, не сталкиваясь с этой ошибкой?

29
задан Carl Norum 20 February 2010 в 03:41
поделиться

2 ответа

Эта проблема не обязательно связана с Xcode или Objective-C. Не связывайте/архивируйте библиотеки с другими библиотеками. A и B зависят от C только во время конечного связывания, а не во время сборки. Вы хотите:

  1. собрать A
  2. собрать B
  3. собрать C
  4. собрать app & link

Вот пример проекта, который я сделал для демонстрации:

Makefile:

app: main.o a.a b.a c.a
        gcc $^ -o $@

%.o: %.c
        gcc -Wall -c $^

%.a: %.o
        ar -r $@ $^

clean:
        rm -rf *.o *.a app

a.c:

#include <stdio.h>
void c(void);

void a(void)
{
  printf("a\n");
  c();
}

b.c:

#include <stdio.h>
void c(void);

void b(void)
{
  printf("b\n");
  c();
}

c.c:

#include <stdio.h>

void c(void)
{
  printf("c\n");
}

main. c:

#include <stdio.h>

void a(void);
void b(void);

int main(int argc, char *argv[])
{
  a();
  b();
  return 0;
}

Build and run log:

$ make
gcc -Wall -c main.c
gcc -Wall -c a.c
ar -r a.a a.o
ar: creating archive a.a
gcc -Wall -c b.c
ar -r b.a b.o
ar: creating archive b.a
gcc -Wall -c c.c
ar -r c.a c.o
ar: creating archive c.a
gcc main.o a.a b.a c.a -o app
rm a.o b.o c.o
$ ./app 
a
c
b
c
6
ответ дан 28 November 2019 в 01:53
поделиться

Ответ Карла правильный, но по неправильным причинам: на самом деле нет ничего плохого в связывании статических библиотек вместе, как мы можем видеть, используя собственный образец Карла. Настройте пример кода Карла и сделайте следующее: (Я использую libtool, потому что это то, что использует XCode)

neutron:libtest jamie$ libtool -o a2.a a.a c.a
neutron:libtest jamie$ libtool -o b2.a b.a c.a
neutron:libtest jamie$ gcc main.o a2.a b2.a -o app2
neutron:libtest jamie$ ./app2
a
c
b
c
neutron:libtest jamie$ 

Это связывает a2.a и b2.a с main.o. По словам Карла, это источник проблемы с OP, и app2 не должен связываться. Но, конечно, есть. Компоновщик достаточно умен, чтобы игнорировать два экземпляра одного и того же файла. Мы видим, что как a2.a, так и b2.a содержат c.o:

neutron:libtest jamie$ ar -t a2.a
__.SYMDEF SORTED
a.o
c.o
neutron:libtest jamie$ ar -t b2.a
__.SYMDEF SORTED
b.o
c.o

Тем не менее, это нормально.

Я считаю, что проблема связана с универсальными двоичными файлами, либо с универсальными двоичными файлами PPC / x86, либо с универсальными двоичными файлами для iPhone armv6 / armv7. Проблема здесь в том, что есть ошибка с категориями , и исправление (добавление -all_load к флагам компоновщика) является исправлением, которое работает только для отдельных архитектур. Использование -all_load нарушает способность компоновщика игнорировать символы, определенные для нескольких архитектур, и возникает ошибка повторяющегося символа.

Я писал об этом здесь , включая лучшее решение, чем использование -all_load.

26
ответ дан 28 November 2019 в 01:53
поделиться
Другие вопросы по тегам:

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