Цель урока: настроить кросс-компиляцию в ОС 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