2011-03-12 11 views
13

Rekompilacja app C++ iPhone z Xcode 4 otrzymuję ten paskudny błąd linkera:"zły Codegen, wskaźnik diff" Błąd linkera z Xcode 4

ld: bad codegen, pointer diff in __static_initialization_and_destruction_0(int, int) 
to global weak symbol vmml::Vector2<float>::ZERO for architecture armv6 

ktoś wie co to znaczy? Jak sprawić, by odejść byłoby miłe też oczywiście :)

Aplikacja opracowana & połączony bezbłędnie w Xcode 3.

Edit: rozwiązaniem jest ustawienie Symbole domyślnie ukryte do Tak we wszystkich ustawieniach kompilacji wszystkich obiektów docelowych w projekcie. Wciąż żaden mądrzejszy, jaki był faktyczny problem.

+0

Dzięki! Rozwiązany również dla mnie - nie rozumiem! –

Odpowiedz

18

Rozwiązaniem jest ustawienie Symbols Hidden By Default na Tak we wszystkich ustawieniach kompilacji wszystkich obiektów docelowych w projekcie. Wciąż żaden mądrzejszy, jaki był faktyczny problem.

+0

Otrzymywałem ... globalną zmienną słaby symbol wartownika dla ... dla wzmocnienia rzeczy i to się udało. Dzięki tobie – ort11

4

Wpadłem na ten problem, próbując dołączyć do bibliotek boost jeden z moich projektów. Po znalezieniu tego posta, ustawienie Symbols Hidden By Default na Yes również rozwiązało ten problem dla mnie. Musiałem również dokonać tego samego ustawienia w każdym z zależnych projektów, aby całkowicie pozbyć się błędu.

Po prostu FYI - zdarzyło się to tylko na moich celach, które używały stosu clang ++. Cele GCC i LLVM + GCC wydają się nie mieć wpływu.

+0

Używanie GCC lub LLVM + GCC również działało dla mnie. Zmiana "Symboli ukrytych domyślnie" na "Tak" nie zmieniła niczego. – Andrew

5

Miałem ten sam problem, a także zakończyłem dostosowywanie ustawień widoczności. Byłem jednak zdenerwowany, bawiąc się widocznością symbolu i nie rozumiejąc problemu, więc zrobiłem trochę więcej badań.

Jeśli, tak jak ja, używasz skryptu/pakietu Pete'a Goodliffe'a do budowania boostu jako struktury, skrypt ustawia domyślną widoczność na ukryty (== tak). Opcje widoczności zmieniają sposób oznaczania symboli przez kompilator (domyślnie, ukryty, wewnętrzny). Ta informacja jest używana przez linker podczas tworzenia elfów obiektów współdzielonych (bibliotek współdzielonych). Nie powinno się go tutaj stosować, więc podejrzewam, że jest to błąd łącznika. W bibliotece wzmocnienia znajduje się słaby symbol oznaczony jako ukryty, a następnie w projekcie/innej bibliotece ten sam symbol oznaczony jako domyślny. Linker jest zdezorientowany?

Jeśli chodzi o XCode 3 vs. 4, być może domyślną wartością w 3 było ukrywanie symboli?

W każdym razie zmiana domyślnej widoczności na ukrytą nie powinna mieć żadnego wpływu tylko na obecność statycznych bibliotek, więc czuję się o wiele bezpieczniej na tej trasie.

Zamieściłem kilka dodatkowych informacji w blog entry dla zainteresowanych.

+0

Thx Tyler kilka świetnych informacji tutaj! – Stoff81

+0

+1 za opisanie badań nad problemem zamiast dawania kultowych odpowiedzi! –

2

Zasadniczo wszystkie symbole w bibliotece, do których należy link do & własnego kodu, muszą używać tego samego poziomu widoczności, tj. Jeśli wszystkie symbole w dołączonej bibliotece są ukryte, należy się upewnić, że pliki dołączane odnoszą się do symboli w projekt nie próbuj ustawić go jako widocznego. Najbezpieczniejszym sposobem na osiągnięcie tego jest stały poziom domyślnej widoczności w całym projekcie, dla mnie stał się tylko problem z optymalizacją.

1

Być może używasz biblioteki, która ma ukryte informacje o symbolu. Jeśli symbol nie został wyeksportowany z biblioteki i próbujesz użyć go na zewnątrz, powoduje to podobny błąd linkera.Poprawnym rozwiązaniem wydaje się znalezienie sposobu na uczynienie tego symbolu "widocznym" dla świata zewnętrznego poprzez makrodefinicje GCC i/lub zmodyfikowanie samej biblioteki, aby upewnić się, że dany symbol jest naprawdę "ukryty" przed światem zewnętrznym - -to znaczy to nie jest coś, co jest kiedykolwiek używane lub ujawnione w pliku nagłówkowym.

Należy jednak zachować ostrożność: zgodnie z dokumentacją firmy Apple nie należy ukrywać niektórych informacji o symbolu z wielu powodów; Poniżej ten wydaje się być najbardziej niepokojące z tego grona:

If your symbol uses runtime type identification (RTTI) information, exceptions, or dynamic casts for an object that is defined in another library, your symbol must be visible if it expects to handle requests initiated by the other library. For example, if you define a catch handler for a type in the C++ standard library, and you want to catch exceptions of that type thrown by the C++ standard library, you must make sure that your typeinfo object is visible.

Źródło

: http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/CppRuntimeEnv/Articles/SymbolVisibility.html

Zatem jeśli chcesz złapać wyjątek z biblioteki jesteś łączącej przeciw, ukrywając się pojawi, informacje symbol być złym wyborem. Prawidłowym rozwiązaniem byłoby odkrycie symboli dowolnej biblioteki, z którą się łączysz. To może być wykonane przez pomijając następujące kompilatora GCC flagi:

-fvisibility=hidden --fvisibility-inlines-hidden

(domyślną widoczność powinna być wystarczająca), lub istnieje też kompilator pragma, które pozwalają to zrobić. Zobacz: http://gcc.gnu.org/wiki/Visibility