<Poprzedni | Spis treści | Następne>
6.10. Dostosowywanie łańcucha narzędzi
Teraz, gdy zainstalowano już ostatnie biblioteki C, nadszedł czas na dostosowanie łańcucha narzędzi tak, aby łączył każdy nowo skompilowany program z tymi nowymi bibliotekami.
/tools/bin/{ld,ld-old}
/tools/$(uname -m)-pc-linux-gnu/bin/{ld,ld-old}
/tools/bin/{ld-nowy,ld}
/tools/bin/{ld,ld-old}
/tools/$(uname -m)-pc-linux-gnu/bin/{ld,ld-old}
/tools/bin/{ld-nowy,ld}
Najpierw wykonaj kopię zapasową pliku /narzędzia linker i zastąp go poprawionym linkerem, który zrobiliśmy w rozdziale 5. Utworzymy także łącze do jego odpowiednika w /tools/$(uname -m)-pc-linux-gnu/bin:
mw mw mw
ln
-v
-v
-v
mw mw mw
ln
-sv /tools/bin/ld /tools/$(uname -m)-pc-linux-gnu/bin/ld
-sv /tools/bin/ld /tools/$(uname -m)-pc-linux-gnu/bin/ld
Następnie zmień plik specyfikacji GCC tak, aby wskazywał nowy dynamiczny linker. Samo usunięcie wszystkich wystąpień „/tools” powinno pozostawić nam poprawną ścieżkę do dynamicznego linkera. Dostosuj także plik specs, aby GCC wiedziało, gdzie znaleźć prawidłowe nagłówki i pliki startowe Glibc. A sed polecenie realizuje to:
gcc -dumpspecs | sed -e 's@/tools@@g' \
-e '/\*startfile_prefix_spec:/{n;s@.*@/usr/lib/ @}' \
-e '/\*cpp:/{n;s@$@ -isystem /usr/include@}' > \
`nazwa_katalogu $(gcc --print-libgcc-nazwa-pliku)`/specs
gcc -dumpspecs | sed -e 's@/tools@@g' \
-e '/\*startfile_prefix_spec:/{n;s@.*@/usr/lib/ @}' \
-e '/\*cpp:/{n;s@$@ -isystem /usr/include@}' > \
`nazwa_katalogu $(gcc --print-libgcc-nazwa-pliku)`/specs
Dobrym pomysłem jest wizualne sprawdzenie pliku specyfikacji, aby sprawdzić, czy faktycznie wprowadzono zamierzoną zmianę.
Na tym etapie konieczne jest upewnienie się, że podstawowe funkcje (kompilacja i łączenie) dostosowanego zestawu narzędzi działają zgodnie z oczekiwaniami. Aby to zrobić, wykonaj następujące testy poprawności:
echo 'int main(){}' > dummy.c
cc dummy.c -v -Wl,--verbose &> dummy.log readelf -l a.out | grep ': /lib'
echo 'int main(){}' > dummy.c
cc dummy.c -v -Wl,--verbose &> dummy.log readelf -l a.out | grep ': /lib'
Nie powinno być żadnych błędów, a wyjściem ostatniego polecenia będzie (uwzględniając różnice specyficzne dla platformy w nazwie dynamicznego linkera):
[Wymagający interpreter programu: /lib64/ld-linux-x86-64.so.2]
[Wymagający interpreter programu: /lib64/ld-linux-x86-64.so.2]
Należy pamiętać, że w systemach 64-bitowych / lib to lokalizacja naszego dynamicznego linkera, ale dostęp do niego odbywa się poprzez dowiązanie symboliczne w /lib64.
Note
W systemach 32-bitowych interpreterem powinien być /lib/ld-linux.so.2.
Note
W systemach 32-bitowych interpreterem powinien być /lib/ld-linux.so.2.
Teraz upewnij się, że jesteśmy skonfigurowani do używania poprawnych plików startowych:
grep -o '/usr/lib.*/crt[1in].*udało się' dummy.log
grep -o '/usr/lib.*/crt[1in].*udało się' dummy.log
Dane wyjściowe ostatniego polecenia powinny wyglądać następująco:
/usr/lib/../lib/crt1.o powiodło się
/usr/lib/../lib/crti.o powiodło się
/usr/lib/../lib/crtn.o powiodło się
/usr/lib/../lib/crt1.o powiodło się
/usr/lib/../lib/crti.o powiodło się
/usr/lib/../lib/crtn.o powiodło się
Sprawdź, czy kompilator szuka poprawnych plików nagłówkowych:
grep -B1 '^ /usr/include' dummy.log
grep -B1 '^ /usr/include' dummy.log
To polecenie powinno zwrócić następujące dane wyjściowe:
#include <...> wyszukiwanie rozpoczyna się tutaj:
/ Usr / include
#include <...> wyszukiwanie rozpoczyna się tutaj:
/ Usr / include
Następnie sprawdź, czy nowy linker jest używany z poprawnymi ścieżkami wyszukiwania:
grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'
grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'
Odniesienia do ścieżek zawierających komponenty z opcją „-linux-gnu” należy zignorować, ale w przeciwnym razie wynikiem ostatniego polecenia powinno być:
SEARCH_DIR("/usr/lib") SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib") SEARCH_DIR("/lib")
Następnie upewnij się, że używamy poprawnej biblioteki libc:
grep "/lib.*/libc.so.6" dummy.log
grep "/lib.*/libc.so.6" dummy.log
Dane wyjściowe ostatniego polecenia powinny wyglądać następująco:
próba otwarcia /lib/libc.so.6 powiodła się
próba otwarcia /lib/libc.so.6 powiodła się
Na koniec upewnij się, że GCC używa prawidłowego linkera dynamicznego:
grep znalazł dummy.log
grep znalazł dummy.log
Wynikiem ostatniego polecenia powinno być (uwzględniając różnice specyficzne dla platformy w nazwie dynamicznego linkera):
znaleziono ld-linux-x86-64.so.2 w /lib/ld-linux-x86-64.so.2
znaleziono ld-linux-x86-64.so.2 w /lib/ld-linux-x86-64.so.2
Jeśli sygnał wyjściowy nie wygląda jak pokazano powyżej lub w ogóle nie jest odbierany, oznacza to, że coś jest poważnie nie tak. Sprawdź i powtórz kroki, aby dowiedzieć się, gdzie leży problem i go naprawić. Najbardziej prawdopodobną przyczyną jest to, że coś poszło nie tak z dostosowaniem pliku specyfikacji. Przed kontynuowaniem procesu należy rozwiązać wszelkie problemy.
Gdy wszystko będzie działać poprawnie, wyczyść pliki testowe:
rm -v dummy.c a.out dummy.log
rm -v dummy.c a.out dummy.log