Среда, 15.05.2024, 23:53
Personal dimanche13 site
Главная | Регистрация | Вход Приветствую Вас Гость | RSS
Категории каталога
Мои статьи [22]
BlitzMax [17]
раздел содержит статьи относящиеся к языку программирования BlitzMax
SDL [9]
раздел содержит статьи на тему SDL
Code::Blocks [3]
в этом разделе рассказывается как прикрутить движок к интегрированной среде разработки(IDE) Code::Blocks
Форма входа
Поиск
Друзья сайта
Главная » Статьи » SDL

Настройка кросс-компиляции в GNU Linux
Настройка кросс-компиляции в 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» http://www.citforum.ru/operating_systems/gnumake/index.shtml

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).
берем этот (версия может быть другой, но нужен mingw32-dev.tar.gz):

Теперь скачаем и установим 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
На этот раз все еще проще. Я не буду заставлять Вас искать портированный для WinCE компилятор GNU gcc (cegcc) — хотя использовать будем именно его разновидность -компилятор mingw32ce для получения нативного кода под WinCE. Не буду заставлять скачивать, патчить для wince и компилировать SDL под эту платформу (если хотите, можете проделать все это самостоятельно). Вместо этого предлагаю Вам скачать http://narod.ru/disk/16146037000/for_wince.tar.gz.html
архив содержит уже установленные mingw32ce и 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 не требуется.
Иногда бывает, что файл на WinCE все же отказывается запускаться жалуясь на отсутствие необходимой библиотеки (или нескольких). Что конкретно ему требуется можно определить (как для win32 так и для wince) программой Dependency walker http://dependencywalker.com/ она хорошо работает в Linux Wine.

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

 

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



Категория: SDL | Добавил: dimanche13 (28.12.2009) | Автор: J3d1
Просмотров: 9283 | Комментарии: 6 | Рейтинг: 4.7/3 |
Всего комментариев: 6
6 FZKClMG  
0
23918387 Chen SOX17 H <a href=http://vardenafil.buzz>closest thing to levitra</a> Fluphenazine about inderal la

5 gainiaqueette  
0
Забавно читать :)

4 Tesewhats  
0
Этот пост — одно из редких исключений, когда читаешь с интересом и что-то для себя выносишь. Спасибо Вам. Добавлю в избранноеhttp://voronezh.recikl.ru/ - . :)

3 Liska  
0
Хороший блог, свежая инфа, почитываю

2 J3d1  
0
Спасибо, главное чтоб полезная была =)

1 dimanche13  
0
отличная статья! с почином up

Имя *:
Email *:
Код *:
Copyright MyCorp © 2024