2011-06-22 9 views
11

Czy są jakieś przyzwoite narzędzia do określenia optymalnej kolejności linków statycznych z g ++ pod Linuksem? Jestem zaznajomiony z ogólnymi problemami, w tym (jeśli to konieczne) z użyciem powtarzających się odniesień do pojedynczej biblioteki lub --start-group i -end-group w celu rozwiązania zależności cyklicznych, ale w razie potrzeby chciałbym jest narzędziem, które pobiera kilka plików .a i wypisuje dla nich dobrą kolejność linków statycznych, powtarzając w razie potrzeby biblioteki, zachowując minimalne powtarzanie.Szukasz narzędzia Static Link Order w systemie Linux

Kontekst: Pracuję nad projektem obejmującym około 800K linii odziedziczonego kodu C++ i próbuję go przekształcić w mniejsze, łatwiejsze w zarządzaniu części. Niektóre z istniejących plików są ogromnymi monolitami - dziś zmagałem się z pojedynczym plikiem linii .h 34K, który zdefiniował 113 klas i struktur. Wiele klas zostało zdefiniowanych niemal w całości w pliku .h. Kiedy podzielę to na mniejsze części i zmigruję część kodu implementacji do plików .cpp, wymagana kolejność linków w systemie Linux ciągle się zmienia. Prawdopodobnie dlatego, że każda biblioteka, która zawierała plik .h, służyła do kompilowania własnej implementacji niezależnie od tego, jakie klasy były potrzebne, a teraz muszą łączyć się ze wspólną implementacją w jednym pliku biblioteki. Na dłuższą metę prawdopodobnie przeorganizujemy niektóre klasy do różnych bibliotek i zerwamy niektóre łańcuchy zależności, ale teraz zależności są dość splątane i próbuję zminimalizować perturbacje kodu, który może zmienić zachowanie. Wolałbym nie musieć ręcznie sprawdzać prawidłowej kolejności linków za każdym razem, gdy się zmienia. Propozycje?

Odpowiedz

4

Nie znam jednego z nich, ale można go wprowadzić samodzielnie. Po prostu użyj nm, aby uzyskać listę symboli z każdej biblioteki statycznej, użyj jej do zbudowania wykresu zależności, a następnie wykonaj sortowanie topologiczne na wykresie dla właściwej kolejności linków.

Alternatywnie zamiast linek statycznych użyj linków częściowych (ld -r). Ponieważ to wyprowadza scalony plik .o, twój ostateczny link może zadeklarować biblioteki w dowolnej kolejności, a wszystkie zostaną poprawnie połączone. Wadą jest to, że linker nie będzie w stanie odrzucić nieużywanych plików źródłowych, ponieważ są one już połączone w pliki monolityczne, zanim dane dotyczące użytkowania są dostępne (można obejść to poprzez przekazanie -ffunction-sections -fdata-sections podczas kompilacji i -Wl,--gc-sections na ostatecznym łączu, chociaż może to wpływ na czas kompilacji)

+1

Myślałam o tym, ale problem jest nieco trudniejsze niż to. Sortowanie topologiczne działa, jeśli musisz poczekać na każdego, kto zadzwoni, zanim zostaniesz uwzględniony. Ale nie jest to wymagane: jeśli biblioteka A ma symbol a, który potrzebuje symbolu b z biblioteki B, to jest w porządku (i rzeczywiście może być konieczne), aby B poprzedzało A w kolejności linków, o ile istnieje ktoś wcześniej w zlecenie, które wymaga również b. Prawdopodobnie mógłbym wypracować rozsądny algorytm, ale zajęłoby to trochę czasu, a tymczasem trzeba wykonać pracę z ustalonymi terminami. Dlatego wolę sprawdzone w walce rozwiązanie, które już tam jest. – dewtell

+0

@dewtell: Może się zdarzyć, że takie podejście nie zadziała, ale czy masz pewność, że baza kodów jest jedną z nich? –

+0

@Andrew - całkiem pewny. Na podstawie włączenia plików .h, istnieje wiele przypadków, w których plik1a w bibliotece lib1 odwołuje się do symbolu zdefiniowanego w pliku2a w bibliotece lib2, natomiast plik2b w bibliotece lib2 odwołuje się do symbolu zdefiniowanego w pliku1b w bibliotece lib1. – dewtell

1

Można użyć bibliotek współdzielonych zamiast statycznych i skompilować z opcją -fPIC.

+0

To nie jest dobry pomysł na krótką metę, ponieważ radykalnie zmieniłby sposób, w jaki wysyłamy i instalujemy program, i wprowadzamy całkiem nowe źródło błędów. W dłuższej perspektywie jest to coś, na co mogliśmy spojrzeć, ale prawdopodobnie nie tylko w celu rozwiązania tego konkretnego problemu. – dewtell

Powiązane problemy