Среда, 24.04.2024, 16:48
PIXELCODEПриветствую Вас Гость | RSS
Главная | Каталог статей | Регистрация | Вход
Меню сайта

Категории раздела
SDL и C/C++ [6]

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Форма входа

Главная » Статьи » SDL и C/C++

Статья 1. Настройка кросскомпиляции в GNU Linux
   Цель урока: настроить кросс-компиляцию в ОС GNU Linux на целевые платформы Linux, Windows, WindowsCE

Содержание урока:
1. Введение;
2. Что нужно иметь;
3. Приступим. Первый проект в Linux;
4. Добавляем компиляцию под Windows32;
5. Добавляем компиляцию под WindowsCE;
6. В добрый путь.

1.  Введение
   В один прекрасный день, установив Linux, я решил начать изучение С/С++. Скомпилировал первый «Helo World», «прикрутил» графическую библиотеку SDL, возрадовался, но ненадолго: библиотека SDL является кросс-платформенной и поэтому у меня возникло желание сделать кросс-платформенный микро-проект для 3-х ОС: (Linux, Win32, WinCE) c использованием библиотеки SDL.
   Т.к. я являюсь новичком в программировании и в Linux, прошу не судить строго. То как я это сделал и описал, возможно, неверно, но у моего способа есть два больших плюса: это не сложно и это работает =). Надеюсь статья будет полезна таким же новичкам как я.

2.  Что нужно иметь
   ОС Linux (у меня Kubuntu 9.04) в других дистрибутивах установка и настройка проводится аналогично (разница лишь в командах менеджера пакетов для установки ПО). Для написания исходного кода я использовал текстовый редактор Kate с подсветкой С++ синтаксиса (он в составе дистрибутива), конечно можно любой другой редактор – дело вкуса.
   Для компиляции и запуска полученных исполняемых файлов – файловый менеджер GNU Midnight Commander (устанавливается через менеджер пакетов или aptitude install mc под рутом). И конечно-же gcc - GNU Compiler Collection http://gcc.gnu.org/
, русскоязычная страничка википедии http://ru.wikipedia.org/wiki/GNU_Compiler_Collection. Им и его портированными под другие платформы версиями мы и будем пользоваться.
   Последняя по списку но не по значению для кросс-компиляции – утилита для сборки проектов GNU Make http://www.gnu.org/software/make/manual/, страничка вики на русском http://ru.wikipedia.org/wiki/Make и хорошая статья Владимира Игнатова "Эффективное использование GNU Make".


3. Приступим. Первый проект в Linux
   Для начала проверим установлен ли в нашей системе компилятор g++ для чего в консоли введем 
g++ --version
Если получаем что-то подобное :
$ g++ --version
c++ (Ubuntu 4.3.3-5ubuntu4) 4.3.3

и т.д. значит все нормально, g++ установлен, если что-то похожее на:
$ g++ --version
bash: g++: команда не найдена

значит g++ нужно установить. Из под рута вводим aptitude install g++ или же в менеджере пакетов (у меня это Synaptic выбираем установку g++) . Теперь g++ --version выдает нам версию нашего C++ компилятора.

Так же поступаем с утилитой Make:
$ make --version
GNU Make 3.81 ……

Если GNU Make не установлен — ставим аналогично пакету g++ (из консоли или менеджера пакетов)

В консоли запустим Midnight Comander:
$ mc
если mc не запустился установим его (aptitude install mc в консоли под рутом или из Synaptic)

   Попробуем наш компилятор в деле. В текстовом редакторе создадим файл main.cpp такого содержания и сохраним его в папке test:

#include <cstdio>
int main()
{
   printf("Hello Word\n");
   return 0;
}


перейдем в mc в папку test, временно скроем панели commandera нажатием Ctrl-O. Здесь в консоли запустим наш файл на компиляцию строкой:
g++ -o main main.cpp
здесь –o это ключ компилятора, указывающий, что нужно создать исполняемый файл с именем main, имя исходного файла на языке С++ main.cpp.
Компиляция должна пройти без ошибок и предупреждений и завершиться созданием исполняемого файла main.
Запустим наш файл из текущей директории командой:
./main
Hello Word

Ну вот, он работает =) Вернуть панели mc можно повторным нажатием Ctrl-O.
   Будем привыкать к хорошему, чтобы каждый раз не вводить строку компиляции воспользуемся утилитой GNU Make:
В нашей папке test создадим простейший make-файл с именем Makefile (без расширения):

# так обозначаем комментарии make файла
# зададим необходимые переменные make,
# подставлять их значения можно так: $(имя_переменной)

# имя исходного и исполняемого файла
TARGET= main
# компилятор
CC_LINUX= g++

# теперь опишем первую цель нашей сборки ее имя – linux
# команды сборки обязательно предваряются Tab-ом
linux:
# Compiling for linux
    $(CC_LINUX) -o $(TARGET)_linux $(TARGET).cpp
    strip $(TARGET)_linux


из консоли, находясь в нашей папке test запустим Makefile командой:
make linux

вывод утилиты make:
$ make
g++ -o main_linux main.cpp
strip main_linux


   Здесь  видно, что вместо переменных make подставил их значения и скомпилировал исполняемый файл, в конце запустил утилиту strip из набора утилит компилятора, которая убрала из нашего исполняемого файла отладочную информацию существенно сократив его размер.
Особенность утилиты make в том, что если мы запустим make без указания цели, то выполняться будет первая описанная цель - linux (в нешем случае мы могли компилировать и make без параметров).

   Теперь мы умеем компилировать под целевую платформу Linux простые консольные программы. Но голая консоль – это скучно, создадим простейшее приложение с использованием графической кросс-платформенной библиотеки SDL.

   Для начала установим libsdl1.2-dev (самый простой путь – Synaptic или другой менеджер пакетов). Для проверки работ SDL создадим простой проект (редактируем наш старый main.cpp):

#include <cstdio>
#include "SDL.h"

//Константы и переменные
const int SCREEN_WIDTH= 240;
const int SCREEN_HEIGHT= 320;
const int SCREEN_BPP= 16;
Uint16 back_color; //Этим цветом будем закрашивать экран
//Основная поверхность SDL
SDL_Surface *screen= NULL;

//Главная функция программы
int main( int argc, char* args[] )
{
   //Инициализация SDL
   SDL_Init(SDL_INIT_VIDEO);
   //Создадим поверхность SDL
   screen= SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT,       SCREEN_BPP, SDL_SWSURFACE);
   //Проверим, создалась ли она
   if(screen== NULL) printf("Unable to SetVideoMode\n");
   else printf("VideoMode settings -Ok\n");
   //Получим back_color в формате screen
    back_color= SDL_MapRGB(screen->format, 128, 0, 0);
   //Запрещаем доступ к поверхности
   SDL_LockSurface(screen);
   //Заполним поверхность красным  
   SDL_FillRect (screen, NULL, back_color);
   //Разрешаем доступ к поверхности
   SDL_UnlockSurface(screen);
   //Отобразим поверхность
   SDL_Flip(screen); // show screen
   //Ждем 3 сек., радуемся
   SDL_Delay(3000);
   //Выход из SDL
   printf("Quiting SDL...\n");
   SDL_FreeSurface(screen);
   SDL_Quit();
   return 0;
}


Теперь сообщим компилятору и линковщику, где брать хедеры (заголовочные файлы .h) и либы (библиотечные файлы .a, .so) библиотеки SDL. Для этого отредактируем наш Makefile:

TARGET= main
CC_LINUX= g++
#Путь к SDL и линковка SDL.so
LIBSDL= -I/usr/include/SDL -L/usr/lib -lSDL

linux:
# Compiling for linux
    $(CC_LINUX) -o $(TARGET)_linux $(TARGET).cpp $(LIBSDL)
    strip $(TARGET)_linux


    Ввели новую переменную LIBSDL в которой с помощь ключей –I и –L задали путь к хедерам и либам. Линковщику ключом -l указали прилинковать libSDL.so (префикс lib и расширение .so, .a указывать не нужно).
Скомпилируем:
$ make linux
на этот раз вывод такой:
g++ -o main_linux main.cpp -I/usr/include/SDL -L/usr/lib -lSDL
strip main_linux


После сборки проекта командой make linux получаем исполняемый файл для Linux main_linux, который покажет нам красный экран 240х320 на 3 секунды.

4.  Добавляем компиляцию под Windows
    Наш исходный код (файл main.cpp) без переделок может быть скомпилирован и под Windows. Для этого применим компилятор MinGW  (Minimalist GNU for Windows) http://www.mingw.org. MinGW обеспечивает нативную функциональность и производительность посредством прямых вызовов Windows API и хорошо подходит для компиляции кроссплатформенных библиотек подобных SDL и приложений c их использованием.
Установим MinGW в нашу систему. Самый простой путь – установить из менеджера пакетов. Ставим пакет mingw32 (он потянет за собой runtime и binutils).

    Теперь скачаем и установим SDL для MinGW. Тут менеджер пакетов нам не помощник — надо руками. Скачиваем отсюда: http://www.libsdl.org/download-1.2.php

берем эту
  
   Распаковываем полученный архив (я не мудрствовал и сделал это прямо их контекстного меню архива). Переходим в mc в этот архив(так чтобы видеть файл Makefile), гасим панели,Ctrl-O, в консоли становимся рутом у меня
$ sudo su
затем устанавливаем SDL для mingw32
# make cross
выводом этой команды будут много строк копирования (со знаком → в середине). Кстати посмотрите куда кладутся .h и .a файлы, там же увидите где потом взять SDL.dll чтобы положить его в папку с .exe файлом (который мы скоро создадим).
    Ок, все готово для компиляции под win32.
Наш предыдущий исходник main.cpp вполне заработает и здесь, менять его не нужно. Добавим только переменные CC_WIN32, LIB_WIN32, CFLAGS_WIN32, LIBSDL_WIN32 и цель win32 в наш Makefile:

TARGET= main

#for linux
CC_LINUX= g++
LIBSDL= -I/usr/include/SDL -L/usr/lib -lSDL

#for win32
CC_WIN32= i586-mingw32msvc-g++
LIB_WIN32= -I/usr/i586-mingw32msvc/include -L/usr/i586-mingw32msvc/lib -lmingw32 -luser32 -lgdi32 -lwinmm -ldxguid
CFLAGS_WIN32= -mwindows
LIBSDL_WIN32= -I/usr/local/cross-tools/i386-mingw32/include/SDL -L/usr/local/cross-tools/i386-mingw32/lib  -lSDLmain -lSDL

linux:
# Compiling for linux
    $(CC_LINUX) -o $(TARGET)_linux $(TARGET).cpp $(LIBSDL)
    strip $(TARGET)_linux

win32:
# Compiling for win32
    $(CC_WIN32) -o $(TARGET)_win32.exe $(TARGET).cpp $(LIB_WIN32) $(LIBSDL_WIN32) $(CFLAGS_WIN32)
    i586-mingw32msvc-strip $(TARGET)_win32.exe

clean:
    rm -f $(TARGET)_linux $(TARGET)_win32.exe


Запустите компиляцию командой make win32
В результате получили исполняемый файл main_win32.exe.
Попробуем его запустить и получаем сообщение об ошибке:
$ ./main_win32.exe
err:module:import_dll Library SDL.dll (which is needed by L"H:\\test\\main_win32.exe") not found
err:module:LdrInitializeThunk Main exe initialization for L"H:\\test\\main_win32.exe" failed, status c0000135

    Нашему файлу необходима библиотека  SDL.dll (не удивительно, ведь его размер всего 8192 байта). Библиотеку копируем из /usr/local/cross-tools/i386-mingw32/bin и вставляем в папку нашего проекта — test (далее, распространяя ваши программы для платформы win32 не забывайте класть в папку с проектом SDL.dll). Запускаем ./main_win32.exe, теперь все работает.
    Если Вы были внимательны, то заметили — у нас в Makefile появилась еще одна новая цель- clean. Эта цель применяется для очистки папки проекта от объектных и исполняемых файлов (у нас пока только для исполняемых). Подробнее на этой цели мы остановимся позже — при описании создания проекта с несколькими файлами.

5.  Добавляем компиляцию под WindowsCE
    На этот раз все еще проще. Для компиляции будем использовать GNU gcc (cegcc) — именно его разновидность -компилятор mingw32ce, обеспечивающий нативный код под WinCE. Для данной платформы воспользуемся библиотекой SDL 1.2.6 c патчем от Arisme скачать все это можно с этой странички. Но Вы можете поступить проще - скачать архив, который содержит уже установленные mingw32ce и пропатченную под WinCE SDL. Вам останется только разархивировать и разнести по папкам файлы из opt в /opt а из usr в /usr. И все. Для начала нам этого вполне хватит.
    Наш «старый» файл main.cpp опять оставим без изменений. Makefile же дополним для компиляции под wince переменными CC_WINCE, CFLAGS_WINCE, LIBSDL_WINCE, добавляем цель компиляции wince. Для того, чтобы make clean могла удалять экзешники wince подправим ее описание соответствующим образом:

TARGET= main

#for linux
CC_LINUX= g++
LIBSDL= -I/usr/include/SDL -L/usr/lib -lSDL

#for win32
CC_WIN32= i586-mingw32msvc-g++
LIB_WIN32= -I/usr/i586-mingw32msvc/include -L/usr/i586-mingw32msvc/lib -lmingw32 -luser32 -lgdi32 -lwinmm -ldxguid
CFLAGS_WIN32= -mwindows
LIBSDL_WIN32= -I/usr/local/cross-tools/i386-mingw32/include/SDL -L/usr/local/cross-tools/i386-mingw32/lib  -lSDLmain -lSDL

#for wince
CC_WINCE= arm-mingw32ce-g++
CFLAGS_WINCE= -fno-exceptions
LIBSDL_WINCE= -I/opt/mingw32ce/arm-mingw32ce/include/sdl -llibSDL

linux:
# Compiling for linux
    $(CC_LINUX) -o $(TARGET)_linux $(TARGET).cpp $(LIBSDL)
    strip $(TARGET)_linux

win32:
# Compiling for win32
    $(CC_WIN32) -o $(TARGET)_win32.exe $(TARGET).cpp $(LIB_WIN32) $(LIBSDL_WIN32) $(CFLAGS_WIN32)
    i586-mingw32msvc-strip $(TARGET)_win32.exe

wince:
#Compiling for wince
    $(CC_WINCE) $(CFLAGS_WINCE) -o $(TARGET)_wince.exe $(TARGET).cpp $(LIBSDL_WINCE)
    arm-mingw32ce-strip $(TARGET)_wince.exe

clean:
    rm -f $(TARGET)_linux $(TARGET)_win32.exe $(TARGET)_wince.exe


Компилируем под wince командой make wince   
По размеру исполняемого файла для wince можно догадаться что он уже содержит SDL (она прилинкована статически) и добавления SDL.dll в папку проекта для wince не требуется. Использование статически прилинкованной библиотеки SDL накладывает на нас определенные обязательства - мы имеем право использовать SDL в таком виде только в свободных проектах. Подробнее об использовании этой библиотеки читаем здесь.
    Иногда бывает, что файл на WinCE все же отказывается запускаться жалуясь на отсутствие необходимой библиотеки (или нескольких). Что конкретно ему требуется можно определить (как для win32 так и для wince) программой  Dependency walker она хорошо работает в Linux Wine.

6.  В добрый путь
    Ну вот, в общем-то и вся премудрость. Теперь мы можем компилировать один исходный файл под три платформы. Что-то в этой статье я намеренно упростил (зачаточное использование мощной GNU Make), о чем-то намеренно умолчал (флаги компиляции). Но это ведь статья а не книга =). «Копайте» сами, для дальнейшего роста это необходимо.
   В любом случае если что-то не получится, возникнут вопросы, дополнения, предложения и пожелания — я к Вашим услугам.

C уважением,
J3d1, e-mail: j3d1adm1n[a]yandex.ru

Категория: SDL и C/C++ | Добавил: J3d1 (21.12.2009)
Просмотров: 7985 | Теги: Linux, SDL, CeGCC, MinGw, кросскомпиляция, GCC, Кросс-компиляция, компьютерная графика | Рейтинг: 5.0/1
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Поиск

Друзья сайта
  • Все для веб-мастера
  • Программы для всех
  • Мир развлечений
  • Лучшие сайты Рунета

  • Copyright MyCorp © 2024 Создать бесплатный сайт с uCoz