« Test działania biblioteki SFML 2.0, lekcja »
Rozdział 4. Testowanie działania biblioteki SFML 2.0 i rozwiązywanie problemów związanych z błędami kompilacji, błędami linkera oraz błędami krytycznymi aplikacji, jakie mogą się pojawić w wyniku nieprawidłowo przeprowadzonej instalacji oraz konfiguracji biblioteki SFML 2.0. (lekcja)
Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Zarejestruj się!
Autor: Piotr Szawdyński
Kurs SFML 2.x, C++

Test działania biblioteki SFML 2.0

[lekcja] Rozdział 4. Testowanie działania biblioteki SFML 2.0 i rozwiązywanie problemów związanych z błędami kompilacji, błędami linkera oraz błędami krytycznymi aplikacji, jakie mogą się pojawić w wyniku nieprawidłowo przeprowadzonej instalacji oraz konfiguracji biblioteki SFML 2.0.

Wprowadzenie

Zanim przystąpisz do właściwej nauki biblioteki SFML w wersji 2.0, warto poświęcić czas na przetestowanie poprawności przeprowadzonej instalacji oraz konfiguracji. W niniejszym rozdziale zawarto więc informacje, umożliwiające przetestowanie poprawności działania SFML 2.0 oraz omówiono często występujące problemy i ich rozwiązania, które zazwyczaj wynikają z błędów popełnionych podczas instalacji, bądź konfiguracji omawianej biblioteki.

Kod źródłowy do testów

Poprawność działania biblioteki SFML 2.0 warto przetestować przy pomocy następującego kodu źródłowego:
C/C++
#include <SFML/Graphics.hpp>
#include <cmath>

int main()
{
    sf::RenderWindow okno( sf::VideoMode( 320, 240 ), "Kurs SFML 2.0 - http://cpp0x.pl" );
    sf::Clock stoper;
    while( okno.isOpen() )
    {
        sf::Event event;
        while( okno.pollEvent( event ) )
        {
            if( event.type == sf::Event::Closed )
                 okno.close();
           
        } //while
        okno.clear();
       
        sf::CircleShape ksztalt( std::sin( stoper.getElapsedTime().asSeconds() ) * okno.getSize().y / 8 + okno.getSize().y / 4 );
        ksztalt.setOrigin( sf::Vector2f( ksztalt.getRadius(), ksztalt.getRadius() ) );
        ksztalt.setPosition( okno.getSize().x / 2.0f, okno.getSize().y / 2.0f );
        ksztalt.setFillColor( sf::Color::Yellow );
        okno.draw( ksztalt );
       
        okno.display();
    } //while
    return 0;
}
Pamiętaj, że niniejszy rozdział jest poświęcony tylko i wyłącznie przetestowaniu poprawności działania biblioteki SFML 2.0, a więc kod przedstawiony powyżej nie zostanie omówiony w niniejszym rozdziale.

Testowanie poprawności działania SFML 2.0

Uwaga! Testy poprawności działania biblioteki SFML 2.0 przeprowadzaj koniecznie na przykładzie zamieszczonym w niniejszym rozdziale. Po ukończeniu niniejszego rozdziału masz mieć bowiem gwarancję, że instalacja oraz konfiguracja biblioteki SFML została wykonana poprawnie.
Rozpocznijmy proces testowania poprawności działania biblioteki SFML 2.0. Otwórz projekt, który został skonfigurowany do pracy z biblioteką SFML 2.0, a następnie otwórz istniejący plik main.cpp. Skopiuj następnie kod źródłowy z niniejszego rozdziału do pliku main.cpp, skompiluj go i uruchom. Jeżeli proces instalacji i konfiguracji przeprowadziłeś poprawnie, na ekranie powinno Ci się pokazać okno aplikacji SFML, wyświetlające żółte (i jednocześnie animowane) koło. Jeżeli tak jest to znaczy, że proces instalacji oraz konfiguracji przeprowadziłeś poprawnie i tym samym możesz zakończyć czytanie niniejszego rozdziału. Dalsza część niniejszego rozdziału jest bowiem poświęcona rozwiązywaniu ewentualnych problemów w przypadku, gdy niniejszy test zakończył się niepowodzeniem.

Program testujący poprawność działania biblioteki SFML 2.0
Program testujący poprawność działania biblioteki SFML 2.0

Błędy kompilacji

Rozpocznijmy od najprostszego błędu kompilacji, z którym początkujący programiści bardzo często nie potrafią sobie poradzić. Treść błędu jaka jest zwracana przez kompilator MinGW, który jest domyślnie używany w Code::Blocks, brzmi następująco:
fatal error: SFML/Graphics.hpp: No such file or directory
Ten sam błąd dla kompilatora Visual C++ 2008 brzmi następująco:
fatal error C1083: Cannot open include file: 'SFML/Graphics.hpp': No such file or directory
Powyższy błąd informuje, że nie można odnaleźć pliku Graphics.hpp w podanym katalogu. Oznacza to, że biblioteka SFML 2.0 albo nie została zainstalowana, albo projekt nie został w ogóle skonfigurowany, albo przeprowadzony proces konfiguracji został po prostu źle wykonany.
Jeżeli konfigurowałeś projekt do pracy z biblioteką SFML 2.0 to upewnij się, że pliki na dysku fizycznie istnieją w katalogu, który podałeś w opcji "Additional Include Directories" (Visual C++), bądź "Compiler Directories" (Code::Blocks). Wskazanie złego, bądź nieistniejącego katalogu skutkuje błędem przedstawionym w niniejszym paragrafie. Upewnij się więc, że proces konfiguracji projektu wykonałeś poprawnie, pliki na dysku istnieją oraz nie popełniłeś żadnej literówki przy wprowadzaniu ścieżki. Sprawdź również, czy wprowadzona konfiguracja dotyczy właściwego trybu kompilacji. Jeżeli wykonasz wszystkie kroki opisane powyżej, omawiany błąd powinien zostać zażegnany.

Błędy linkera

'unresolved external symbol' oraz 'undefined reference to'

Rozwiązywanie błędów linkera zazwyczaj sprawia najwięcej kłopotów i składa się na to kilka powodów. Pierwszym z nich jest czytelność otrzymywanych komunikatów. Przykładowy błąd linkera pod Visual C++ wygląda następująco:
error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall sf::RenderWindow::~RenderWindow(void)" (__imp_??1RenderWindow@sf@@UAE@XZ) referenced in function _main
Podobny (ale nie ten sam!) błąd linkera pod MinGW (Code::Blocks) będzie wyglądał następująco:
undefined reference to `_imp___ZN2sf9VideoModeC1Ejjj'|
Drugim problemem jest fakt, że programiści bardzo często nie zwracają uwagi na to, czy liczba zgłaszanych błędów się zmniejszyła w wyniku wprowadzenia zmian w konfiguracji projektu. Kolejnym problemem związanym z błędami linkera jest fakt, że programista dostaje zazwyczaj co najmniej kilkadziesiąt bardzo długich błędów, a każdy z nich zawiera ciąg dziwnych znaczków i szlaczków. Linker nie potrafi również powiedzieć jakiej biblioteki błąd dotyczy, a ponadto w błędach linkera mogą się znaleźć również funkcje i klasy, które sami zadeklarowaliśmy, ale zapomnieliśmy napisać ich implementacje. Generalnie rzecz biorąc o słabych stronach linkera można by jeszcze długo prawić, jednak nie o to chodzi w niniejszym paragrafie. W każdym razie puentą dla powyższego wywodu jest fakt, że nie da rady omówić każdego błędu linkera. Widząc zapis: 'unresolved external symbol' (dla Visual C++), bądź zapis: 'undefined reference to' (dla kompilatora MinGW) - wiedz, że rozwiązujesz błędy linkera i na etapie konfiguracyjnym jakiejkolwiek biblioteki będzie to zawsze chodziło o dolinkowanie odpowiednich bibliotek w opcjach linkera. Jeżeli w Twoim projekcie pojawiły się błędy linkera o treści podobnej do tej, która została przedstawiona powyżej, to znaczy, że nie przeprowadziłeś procesu konfiguracji projektu (gdybyś wykonał go źle, to linker zgłosiłby inne i jednocześnie dużo czytelniejsze błędy). W celu rozwiązania problemu opisanego powyżej, udaj się do jednego z poniższych rozdziałów:
Warto w tym miejscu również dodać, że linker MinGW jest kapryśny. Objawia się to tym, że jeżeli biblioteki przekazywane do linkera zostaną wprowadzone w opcjach kompilacji projektu w złej kolejności, to również otrzymasz błąd 'undefined reference to'. W przypadku środowiska Visual C++ tego problemu nie ma.

'fatal error LNK1104: cannot open file' oraz 'cannot find -l'

Kolejnym często spotykanym problemem podczas próby skompilowania aplikacji jest błąd linkera informujący o tym, że nie można odnaleźć biblioteki wprowadzonej w opcjach projektu. Jeżeli używasz Visual C++ to błędy mogą mieć następującą treść:
LINK : fatal error LNK1104: cannot open file 'sfml-audio-d.lib'
LINK : fatal error LNK1104: cannot open file 'sfml-graphics-d.lib'
LINK : fatal error LNK1104: cannot open file 'sfml-main-d.lib'
LINK : fatal error LNK1104: cannot open file 'sfml-network-d.lib'
LINK : fatal error LNK1104: cannot open file 'sfml-system-d.lib'
LINK : fatal error LNK1104: cannot open file 'sfml-window-d.lib'
W przypadku kompilatora MinGW (Code::Blocks), błędy te wyglądają następująco:
cannot find -lsfml-audio-d
cannot find -lsfml-graphics-d
cannot find -lsfml-main-d
cannot find -lsfml-network-d
cannot find -lsfml-system-d
cannot find -lsfml-window-d
Przyczyny wystąpienia powyższych błędów mogą być następujące:
  • pobrałeś złą paczkę instalacyjną, w której nie ma bibliotek odpowiednich dla Twojego linkera;
  • nie skonfigurowałeś katalogu, w którym linker ma poszukiwać bibliotek do zlinkowania;
  • wskazany katalog nie istnieje na dysku (np. popełniłeś literówkę), bądź wskazałeś zły katalog, który nie zawiera bibliotek niezbędnych dla linkera;
  • wprowadzone nazwy bibliotek, które chcesz zlinkować, zawierają literówki.
Rozwiązania powyższych problemów znajdziesz w następujących rozdziałach:
W przypadku popełnienia literówek odszukaj stosowny paragraf, opisujący konfigurację linkera w trybie Debug oraz w trybie Release w jednym z rozdziałów, opisujących proces konfiguracji Twojego środowiska programistycznego.

unrecognized command line option '-static-libstdc++'

Powyższy błąd informuje, że komenda -static-libstdc++ jest dla linkera nieznana. Błąd ten pojawia się dla najnowszych wersji kompilatorów MinGW, które dostarczane są razem z Code::Blocks od wersji 12. W przypadku otrzymania wspomnianego błędu, należy wejść w opcje linkera i usunąć omawianą linijkę. Szczegółowe informacje na ten temat znajdziesz w rozdziale » Kurs SFML 2.0, C++ » Instalacja i konfiguracjaKonfiguracja SFML 2.0 (Code::Blocks) lekcja, w sekcji zatytułowanej "Statyczne linkowanie standardowych bibliotek C++".

Błędy przy uruchamianiu aplikacji

Jeżeli udało Ci się skompilować aplikację, ale nie chce się ona poprawnie uruchomić to znaczy, że:
  • nie przekopiowałeś plików *.dll do katalogu, w którym znajduje się wygenerowany plik *.exe z Twoją aplikacją;
  • pliki *.dll, które przekopiowałeś nie pochodzą z właściwej paczki instalacyjnej SFML 2.0;
  • pliki *.dll pochodzą z właściwej paczki instalacyjnej, ale pliki dołączane do linkera pochodzą ze złej paczki instalacyjnej.
  • źle przeprowadziłeś proces konfiguracji trybu Debug oraz trybu Release, np. na odwrót skonfigurowałeś listę bibliotek, jakie mają być dołączone w procesie linkowania aplikacji;
  • [Code::Blocks] nie skonfigurowałeś projektu tak, aby standardowe biblioteki C/C++ były linkowane statycznie ALBO nie przekopiowałeś plików *.dll, należących do kompilatora do katalogu, w którym znajduje się Twoja aplikacja *.exe (uwaga dot. plików *.dll nawiązuje linkowania dynamicznego standardowych bibliotek C/C++);
  • [Code::Blocks] jesteś szczęśliwym posiadaczem unikatowej wersji kompilatora MinGW i rozwiązanie tego problemu wymaga kolejnych godzin walk z instalacją biblioteki SFML 2.0 (szczegóły znajdziesz w pierwszych paragrafach rozdziału » Kurs SFML 2.0, C++ » Instalacja i konfiguracjaKonfiguracja SFML 2.0 (Code::Blocks) lekcja);
  • [Visual C++ 2012] Proces konfiguracji biblioteki SFML 2.0 przeprowadzałeś na paczce instalacyjnej dla Visual C++ 2008 lub Visual C++ 2010 z nadzieją, że zadziała - niestety nie zadziała (wymagana jest samodzielna kompilacja biblioteki SFML 2.0 ze źródeł przy użyciu kompilatora dostarczonego wraz z Visual C++ 2012).
Jeżeli pobrałeś poprawną paczkę instalacyjną dla posiadanego kompilatora oraz właściwie przeprowadziłeś proces konfiguracji, to wszelkie błędy kompilacji, linkera jak i uruchamiania aplikacji powinny zostać zażegnane.

Podsumowanie

Po ukończeniu niniejszego rozdziału powinieneś posiadać sprawną konfigurację projektu, umożliwiającą tworzenie aplikacji z użyciem biblioteki SFML 2.0. Jeżeli w trakcie prowadzenia testów natrafiłeś na błąd, który nie został omówiony w niniejszym rozdziale oraz nie wiesz jak go rozwiązać, zgłoś go na naszym forum. Jeżeli poradziłeś sobie ze wszystkimi napotkanymi błędami i udało Ci się uruchomić program testowy to zapraszam do kolejnego rozdziału niniejszego kursu :)
Poprzedni dokumentNastępny dokument
Konfiguracja SFML 2.0 (Code::Blocks)Podstawy