Ręczne sterowanie
Transkrypt
Ręczne sterowanie
Make COVER STORY Co robić, gdy make odmawia współpracy? Ręczne sterowanie Po zakończonym sukcesem uruchomieniu skryptu configure, ostatnim etapem do zbudowania aplikacji jest już tylko pokonanie trudności związanych z uruchomieniem poleceń make i make install. ANDREA MÜLLER B łędy pojawiające się przy wywoływaniu poleceń make i make install nie powinny w ogóle występować. Działania, które podejmuje program make podczas kompilacji i instalacji oprogramowania, opisane są w pliku Makefile, generowanym przez skrypt configure. Jeśli configure wykryje, że wymagana biblioteka znajduje się w katalogu /usr/local/multimedia/lib, informacja ta będzie zapisana w Makefile jako jeden z parametrów kompilacji. Powierzchowne testy Plik Makefile powinien być idealnie dopasowany do Twojego systemu. Jeśli tak nie jest i polecenie make zwraca błędy, to najczęściej jest to wina źle napisanego kodu źródłowego. W najgorszym przypadku będziesz potrzebował pomocy twórcy programu. Możliwe jednak, że z niektórymi problemami poradzisz sobie samodzielnie – chodzi tu głównie o niechlujnie przygotowane skrypty configure, które nie zbierają wszystkich informacji niezbędnych do po- myślnej pracy polecenia make (Listing 1). W przypadku nieprawidłowości, make może zwrócić nawet kilkadziesiąt komunikatów błędów. Zasada jest taka, że pierwsza informacja jest najważniejsza; wszystkie pozostałe zazwyczaj z niej wynikają. Na Listingu 1 make informuje o niepowodzeniu, ponieważ kompilator nie znalazł pliku nagłówkowego mimepp.h. Błąd ten wystąpił podczas kompilacji pliku o nazwie decodeRFC2047.cpp w linii nr 21 tego pliku. Gdy komunikat błędu jest oczywisty, tak jak w przypadku mimelib/mimepp.h: No such file or directory, nie jest konieczne sprawdzanie kodu źródłowego. Aby znaleźć potrzebny pakiet, wykorzystaj polecenia wyszukujące konkretne pliki w pakietach, np.: urpmf mimepp.h (Mandrake Linux), pin mimepp.h (SuSE Linux) lub internetową wyszukiwarkę pakietów http://www.rpmseek.com/. Mandrake Linux jako rezultat wyszukiwania zwróci nazwę kdenetwork-devel. Po zainstalowaniu pakietu ponownie uruchom make. Tym razem gcc nie powinien mieć trudności ze znalezieniem mimepp.h. W rzadkich przypadkach make może nie znaleźć pliku, mimo że znajduje się on w Twoim systemie. Roztargnieni programiści Jeśli czujesz się na tyle pewnie, by samemu dodać coś do kodu źródłowego, łatwo wyeliminujesz błędy, takie jak ten na Listingu 2. Zwyczajnie rozłożysz na czynniki pierwsze te zagadkowo wyglądające komunikaty. Początek linii wskazuje, że kompilator przetwarza legacyimport.cpp. Linia 143 odnosi się do KInputDialog, ale kom- SŁOWNICZEK Makefile: Plik zawierający zestaw reguł i wszystkie szczegóły wymagane do zbudowania programu, np. lokalizacje bibliotek i plików nagłówkowych, dyrektywy i opcje sterujące dla kompilatora, a także komendy potrzebne do zainstalowania gotowej aplikacji w katalogu docelowym. www.linux-magazine.pl Lipiec 2004 31 COVER STORY Make Listing 1: Typowy przykład braku pliku potrzebnego do kompilacji [andi@doomtrain kshowmail-3.1.0-pre1]$ make [...] decodeRFC2047.cpp:21:28: mimelib/mimepp.h: No such file or directory decodeRFC2047.cpp: In function `QCString decodeQuotedPrintable(const QCString&)': decodeRFC2047.cpp:40: error: `DwString' undeclared (first use this function) [...] make[2]: *** [decodeRFC2047.o] Error 1 make[2]: Leaving directory `/home/andi/test/kshowmail-3.1.0-pre1/kshowmail' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/home/andi/test/kshowmail-3.1.0-pre1' make: *** [all] Error2 [andi@doomtrain]$ make pilator nie rozumie tej funkcji (undeclared (first use this function)). Undeclared oznacza, że klasa KInputDialog, która jest używana po raz pierwszy w tym miejscu, nie została wcześniej zdefiniowana tak, by kompilator mógł ją zauważyć. Oznacza to, że brakuje części kodu wymaganej do zbudowania pakietu. Programiści używają wielokrotnie tych samych klas, by uniknąć pisania za każdym razem od nowa kodu potrzebnego do stworzenia tak skomplikowanych obiektów. Jeśli potrzebujesz obiektu należącego do danej klasy, wywołaj jej konstruktor. Klasy są interfejsem programu, dlatego programy C/C++ umieszczają je w plikach nagłówkowych. Pliki te, najczęściej o rozszerzeniu .h, umieszczane są w tzw. pakietach deweloperskich. W celu umożliwienia kompilacji, programista dodaje do źródeł dyrektywy włączające pliki deklaracji: #include U <kmessagebox.h> mym katalogu co kompilowany plik. Jak widać na Listingu 2, programista zapomniał włączyć plik nagłówkowy opisujący klasę. Aby rozwiązać ten problem, musisz samodzielnie znaleźć ten plik. Polecenie grep jest użyteczne w znajdowaniu łańcuchów w plikach. Zaczynając w katalogu z plikami źródłowymi lub w podkatalogu src, polecenie grep KInputDialog *.h będzie szukało łańcucha znaków KInputDialog w plikach o rozszerzeniu .h. Nie zadziała to w naszym przypadku, ponieważ KInputDialog należy do standardowych klas KDE, znajdujących się w jednym z systemowych katalogów z plikami nagłówkowymi. Najczęściej są to /usr/include oraz /usr/local/inclu- do legacyimport.cpp. Spowoduje to, że kompilator wykorzysta kod zawarty w pliku kmessagebox.h, znajdującym się w specjalnym katalogu z plikami nagłówkowymi. Katalogi te są przekazywane do kompilatora jako opcje zapisane w pliku Makefile, według reguły -I/tutaj/znajduja/sie/pliki/naglowkowe. Zauważmy, że w poniższej linii: Lipiec 2004 Przełącznik -r (rekurencja) zwróci w naszym przykładzie dwa rezultaty: kinputdialog.h i klineeditdlg.h. Rezultat pasujący do szablonu, w drugim pliku jest tylko komentarzem, natomiast linie w kinputdialog.h wyglądają na tyle skomplikowanie, by być klasą... (Ramka 1: kinputdialog.h) Zauważmy, że nazwa pliku przypomina nazwę klasy, mimo że jest napisana małymi literami. To dobry znak – żeby sprawdzić, czy zgadłeś poprawnie, możesz dodać legacyimport.cpp poniżej innych dyrektyw włączania plików nagłówkowych (Rysunek 1). Zwróć uwagę, że make nie zgłasza już błędu. Metoda ta działa tylko w przypadku, gdy plik nagłówkowy, zawierający wymaganą definicję, znajduje się w Twoim systemie. Instalacja z przeszkodami #include „myinclude.h” 32 grep -r KInputDialog U /usr/local/include/* #include <kinputdialog.h> Rysunek 1: Dodawanie dyrektywy dołączania brakuje nawiasów trójkątnych. Oznacza to, że kompilator oczekuje, iż plik nagłówkowy myinclude.h będzie znajdował się w tym sa- de. W niektórych wypadkach KDE wykorzystuje katalog /opt/kde3/include. Rysunek 2: Jeśli zainstalujesz K3b w katalogu „/usr/local”, nie znajdzie on ikon i wtyczek. www.linux-magazine.pl Zdarzają się przypadki, gdy końcowe polecenie make install także zwróci błąd. Większość z nich występuje, gdy użytkownicy próbują zainstalować program w katalogu innym niż /usr/local. Jeśli chcesz umieścić aplikację w /usr/local/test, może się to nie udać. Stanie się tak, gdy programista nie doda do Makefile wpisów tworzących katalogi docelowe. W przypadku, gdy /usr/local/test/bin nie istnieje, jakakolwiek próba skopiowania pliku do tego katalogu zakończy się Make Ramka 1: kinputdialog.h /usr/local/include/kinputdialog.h:class KInputDialog : public KDialogBase /usr/local/include/kinputdialog.h: KInputDialog( const QString &caption, const QString &label, Listing 2: Brakująca dyrektywa włączająca plik nagłówkowy [andi@doomtrain]$ make [...] legacyimport.cpp: In member function `void KLegacyImport::finished()': legacyimport.cpp:143: `KInputDialog' undeclared (first use this function) legacyimport.cpp:143: (Each undeclared identifier is reported only once for each function it appears in.) legacyimport.cpp:143: parse error before `::' token make: *** [legacyimport.o] Error 1 oczywiście fiaskiem. Najłatwiejszym sposobem na pozbycie się tego rodzaju błędu jest użycie mkdir do tworzenia docelowych katalogów, których nazwy można wyśledzić w komunikatach błędów. Kac po instalacji Po zbudowaniu nowej aplikacji KDE, możesz się rozczarować próbując ją uruchomić. Program może nie być w stanie zlokalizować wtyczek, mieć pusty pasek narzędzi, albo uruchomić się w nieprawidłowej wersji językowej (Rysunek 2). Domyślenie aplikacje KDE przeszukują wyłącznie katalogi położenia podstawowych aplikacji. W przypadku SuSE Linux, katalogiem domowym KDE jest /opt/kde3, podczas gdy Red Hat i Mandrake Linux preferują /usr. Gdy budujesz aplikacje KDE, ikony, wtyczki i pliki pomocy zostaną umieszczone w /usr/local. Często na internetowych listach dyskusyj- nych początkujący użytkownicy są instruowani, aby rekompilować aplikację i tym razem określić docelowy katalog KDE, wywołując skrypt ./configure np. ./configure --prefix=/opt/kde3. Jeżeli posłuchasz tej rady, aplikacja może się uruchomić. Niestety w rzeczywistości może to okazać się niebezpieczne i obrócić się przeciwko Tobie. Katalog /opt/kde3 w przypadku SuSE oraz /usr w Red Hat i Mandrake Linux są zarezerwowane dla menadżera pakietów. Zbudowane na własną rękę programy nie powinny instalować się w tych miejscach. Menadżer pakietów nie będzie w stanie ich usunąć. Przy następnej aktualizacji dystrybucji lub KDE pliki te mogą stać się przyczyną niestabilności. Możesz już nie pamiętać o aplikacjach zbudowanych przez siebie, a to znacznie utrudni znalezienie winnej aplikacji. Prawidłowym podejściem jest wskazanie COVER STORY programom KDE innego katalogu. Użyj zmiennej środowiskowej KDEDIRS: export KDEDIRS=/usr/U local:/opt/kde3 Ustala ona zmienną dla obu katalogów SuSE Linux, /usr/local dla samodzielnie skompilowanego oprogramowania oraz /opt/kde3 dla komponentów dystrybucyjnych KDE. W przypadku Red Hat Linux i Mandrake Linux używamy export KDEDIRS=/usr/local:/usr. Po dostrojeniu zmiennej w powyższy sposób, aplikacje KDE będą szukały danych w podkatalogach /usr/local. Gdybyś chciał ustawić tę zmienną środowiskową na stałe, dobrym do tego celu miejscem jest .bash_profile w Twoim katalogu /home. Wszystkie polecenia, jakie dodasz do tego pliku, zostaną uruchomione przez Bash-a w momencie logowania do systemu Użytkownicy SuSE Linux mają nieco więcej pracy do wykonania, ponieważ polecenie unset KDEDIRS wywoływane przez /opt/kde3/bin/startkde, jest skryptem powłoki uruchamiającym środowisko KDE. Program unset usuwa zawartość zmiennej środowiskowej, nadpisując w ten sposób export. Ze względu na to, że skrypt ~/.bash_profile uruchamia się przed KDE, KDE nigdy nie „dowie” się, że istnieje jeszcze inny katalog. Jeżeli chcesz ustawić tę zmienną na SuSE Linux, upewnij się, że jesteś zalogowany jako root. Otwórz plik /opt/kde3/bin/startkde w edytorze tekstowym i postaw znak komentarza (#) przed linią unset KDEDIRS, zakazując powłoce uruchamiania tego polecenie. Gdyby zaszła w przyszłości taka potrzeba, możesz łatwo później usunąć znak „#”. ■