Właściwy sposób łączenia statycznej biblioteki za pomocą GCC

Dlaczego niektóre biblioteki statyczne (lib*.a) mogą być połączone w taki sam sposób, jak biblioteki współdzielone (lib*. so) są połączone (LD-l switch), ale niektóre nie mogą?

Zawsze uczono mnie, że wszystkie biblioteki, statyczne lub nie, mogą być połączone za pomocą-l... jednak do tej pory natknąłem się na jedną bibliotekę (GLFW), która nic nie robi, ale wypluwa błędy linku "undefined reference", jeśli spróbuję połączyć go w ten sposób.

Zgodnie z odpowiedzią na to pytanie , "właściwy" sposób linkowania biblioteki statyczne mają dołączać je bezpośrednio, wraz z moimi własnymi plikami obiektowymi, a nie używać opcji-l. w przypadku biblioteki GLFW to z pewnością rozwiązuje problem. Ale każda inna statyczna biblioteka, której używam, działa dobrze, gdy jest połączona z-l.

Więc:

  • co może spowodować, że ta jedna biblioteka nie będzie działać, gdy zostanie połączona, a nie włączona bezpośrednio? Gdybym znał przyczynę, może mógłbym edytować i przekompilować bibliotekę, aby rozwiązać problem.
  • Czy to prawda, że nie jesteś masz łączyć biblioteki statyczne w taki sam sposób, w jaki łączysz biblioteki współdzielone? (A jeśli nie, to dlaczego nie?)
  • czy linker nadal jest w stanie wyeliminować nieużywane funkcje biblioteczne z wyjściowego pliku wykonywalnego, gdy Biblioteka jest bezpośrednio dołączona w ten sposób?
Author: Community, 2012-03-31

4 answers

Dzięki za odpowiedzi! Okazało się, że problem był spowodowany kolejnością połączeń. Najwidoczniej, jeśli używasz biblioteki, która z kolei ma inne zależności biblioteczne, te inne zależności muszą być wymienione po bibliotece, a nie wcześniej, jak to robiłem. Nauczyłem się czegoś nowego!

 25
Author: Nairou,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-01 21:26:00

Poprawnym sposobem łączenia statycznej biblioteki jest użycie opcji-l, ale działa to tylko wtedy, gdy Biblioteka znajduje się na ścieżce wyszukiwania. Jeśli tak nie jest, możesz dodać katalog do listy używając opcji-L lub nazwać plik po nazwie, tak jak mówisz.

To samo dotyczy bibliotek współdzielonych, chociaż prawdopodobnie można je znaleźć.

 6
Author: ams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-31 13:02:59

Czy zechciałeś wskazać GCC ścieżkę swojej biblioteki (używając-L) ? Używając wyłącznie opcji-l, GCC będzie w stanie połączyć biblioteki dostępne w standardowych katalogach.

-L[path] -l[lib]
 5
Author: Vincent L.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-31 01:29:05

Powód jest historyczny. Narzędzie " ar " było oryginalnym narzędziem archiwizacji plików w PDP11 unix, choć później zostało zastąpione w tym celu przez "tar". Przechowuje pliki (w tym przypadku pliki obiektowe) w pakiecie. Jest też osobne rozszerzenie zawierające tabelę symboli dla linkera. Jest to możliwe, jeśli ręcznie zarządzasz plikami w archiwum, że tabela symboli może być nieaktualna.

Krótka odpowiedź jest taka, że możesz użyć narzędzia "ranlib" w dowolnym archiwum aby odtworzyć tabelę symboli. Spróbuj. Szerzej, spróbuj dowiedzieć się, skąd pochodzą uszkodzone biblioteki i to naprawić.

 1
Author: Andy Ross,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-31 04:34:59