Показаны сообщения с ярлыком исходники. Показать все сообщения
Показаны сообщения с ярлыком исходники. Показать все сообщения

Сборка libGDX из исходного кода

Перед сборкой исходников libGDX, убедитесь, что установлены все компоненты, необходимые в требованиях.

Простой путь

Система сборки libGDX основана на Ant. Различные Ant скрипты отвечают за сборку разных частей libGDX.

Основной сценарий сборки называется build.xml и находиться в корневой директории libGDX репозитория. Он собирает дистрибутив libGDX, включая core API, back-end, все расширения и Javadoc. Чтобы построить дистрибутив выполните следующие команды в shell.

ant -f fetch.xml
ant

Этим самым загрузятся последние версии нативных библиотек (скомпилированный C/C++ код для всех платформ) из сервера сборки, так что вам не нужно делать их сборку самостоятельно. Затем будет вызван основной сценарий для сборки всех Java частей.

Конечным результатом будет zip архив с названием libgdx-версия.zip и директория под названием dist, содержащая распакованный контент архива, который будет, по сути, таким же, как и тот, который можно загрузить с nightly сервера сборки, плюс изменения, сделанные вами в исходниках.

Файл build.xml имеет target для каждого модуля. Каждая target настраивает несколько параметров (classpath, конечная директория и так далее), которые затем передаются на вход build-template.xml файлу. Файл build-template.xml отвечает за компиляцию исходного Java кода, а также исходников нативного кода. Последнее делается вызовом Ant сценария, называемого build.xml и находящегося в jni директории модуля. Если хотите использовать данный метод для компилирования нативного кода, то это не удастся. Как скомпилировать нативные исходники смотрите информацию ниже.

Сложный путь

Существует несколько проблем при сборке исходников нативного кода libGDX:

  • C/C++ код может быть доступен из Java только через JNI, для которого есть специальное решение, называемое gdx-jnigen.
  • Нам нужна сборка для различных платформ, Windows (32/64 бит), Linux (32/64 бит), Mac OS X (32/64 бит), Android(arm6/arm7) и iOS(i386/arm7).
  • Mac OS X и iOS сборки могут быть выполнены только на Mac.
  • В дополнение к компиляции нативного C/C++ нам нужно конвертировать различные jar файлы в .Net assemblies с помощью IKVM для iOS.

Давайте обсудим каждую часть, прежде чем погружаться в настройку цепи средств кросскомпиляции и посмотрим на процесс компиляции.

Jnigen

Jnigen - это расширение, которое позволяет поместить C/C++ код прямо в исходники Java кода. Это повышает локальность кода, которая концептуально относиться друг к другу (нативные методы Java класса и фактическая реализация) и делает рефакторинг кода намного проще по сравнению с обычным процессом JNI.

jnigen имеет две функции:

  • Проверять исходные Java файлы определенной директории, обнаруживать нативные методы и прилагаемую C++ реализацию и отбрасывать исходные C++ файлы и заголовки, схожа как бы вы делали вручную с помощью JNI.
  • Обеспечивать генерацию Ant сценариев сборки, которые собирают нативные исходники для каждой платформы.

Генерация нативного кода

Вот пример из смешивания Java/C++ в один Java исходный файл понятный для jnigen.

private static native ByteBuffer newDisposableByteBuffer (int numBytes); /*
   char* ptr = (char*)malloc(numBytes);
   return env->NewDirectByteBuffer(ptr, numBytes);
*/

private native static void copyJni (float[] src, Buffer dst, int numFloats, int offset); /*
   memcpy(dst, src + offset, numFloats << 2 );
*/

Код C++ содержится в блоке комментария после описания нативного Java метода. Со стороны Java вводятся параметры, которые будут доступны для C++ кода по их Java именам, и если возможно преобразование для ограниченного подмножества типов. Происходит следующее преобразование:

  • Примитивные типы передаются как есть, используются jint, jshort, jboolean как их типы.
  • Одномерные массивы примитивных типов преобразуются в типизированные указатели с прямым доступом. Массивы автоматически блокируются и разблокируются через JNIEnv::GetPrimitiveArrayCritical и JNIEnv::ReleasePrimitiveArrayCritical.
  • Прямые буферы конвертируются в unsigned char* указатели через JNIEnv::GetDirectBufferAddress. Следует отметить, что позиция буфера не учитывается.
  • Любой другой тип будет передан с соответствующим ему JNI типом, например обычные Java объекты будут переданы как объекты.

Вышеуказанные два jnigen нативных метода будут транслированы в следующий C++ исходный код (будет соответствующий и header файл).

JNIEXPORT jobject JNICALL Java_com_badlogic_gdx_utils_BufferUtils_newDisposableByteBuffer(JNIEnv* env, jclass clazz, jint numBytes) {
//@line:334
   char* ptr = (char*)malloc(numBytes);
   return env->NewDirectByteBuffer(ptr, numBytes);
}

JNIEXPORT void JNICALL Java_com_badlogic_gdx_utils_BufferUtils_copyJni___3FLjava_nio_Buffer_2II(JNIEnv* env, jclass clazz, jfloatArray obj_src, jobject obj_dst, jint numFloats, jint offset) {
   unsigned char* dst = (unsigned char*)env->GetDirectBufferAddress(obj_dst);
   float* src = (float*)env->GetPrimitiveArrayCritical(obj_src, 0);


//@line:348
   memcpy(dst, src + offset, numFloats << 2 );

   env->ReleasePrimitiveArrayCritical(obj_src, src, 0);
}

Как вы можете видеть в copyJni(), преобразование вставляется в верхнюю и нижнюю часть метода автоматически. Если вы вернетесь из JNI метода в другое место, отличное от конца вашего метода, то jnigen обернет вашу функцию со второй функцией, которая делает все преобразование, подобно здесь: Перевод исходников Java и C++.

Jnigen также выводит номера строк, говоря, где в исходном Java файле появился C++. Это полезно, если собираем генерируемый jnigen C++ код, так как сценарий Ant не показывает ошибки номером строк кода в Java, на которую можно перейти, нажав на строку в консоли.

Для того чтобы позволить Jnigen пройтись по исходному коду и сгенерировать C/C++ заголовки и исходные файлы, выполните следующие действия:

new NativeCodeGenerator().generate("src", "bin", "jni", new String[] {"**/*"}, null);

Укажите директорию с исходниками, директорию, содержащую скомпилированные .class файлы Java классов, файлы которые вы хотите включить и исключить. Смотрите NativeCodeGenerator для дополнительной информации.

Генерация сценария сборки

Как только были сгенерированны нативные файлы, хочется создать сценарий сборки для всех поддерживаемых платформ. В настоящий момент включена поддержка Windows (32/64-бит), Linux (32/64-бит), Mac OS X (x86, 32/64-бит), Android (arm6/arm7) and iOS (i386, arm7). Генератор сценария сборки jnigen имеет шаблонный Ant сценарий, который может быть параметризован для каждой платформы. Параметры задаются через BuiltTarget. Можно создать BuiltTarget для конкретной платформы подобным образом:

BuildTarget linux32 = BuildTarget.newDefaultTarget(TargetOS.Linux, false);

Это создает target сборку по умолчанию для Linux 32-бит. Можно добавить к BuildTarget дополнительные параметры для конкретной платформы. Повторите этот процесс для других BuildTarget.

Как только все target настроены, поместите их вместе в BuildConfig. Укажите имя shared/static библиотеки, например gdx, которая будет в итоге gdx.dll в Windows, libgdx.so в Linux и Android, libgdx.dylib в Mac OS X и libgdx.a в iOS. Так же можно указать какие файлы будут в итоге и так далее. Самый простой способ использования конфигурации выглядит следующим образом:

BuildConfig config = new BuildConfig("gdx");

Когда все target и настройки находятся в одном месте, настает время генерации Ant сценария при помощи AntScriptGenerator.

new AntScriptGenerator().generate(config, linux32, linux64, windows32, windows64, macosx, android, ios)

Запуск демо и тестов

libGDX поставляется с тонной простых и маленьких тестовых примеров и множеством демонстрационных игр. Чтобы запустить и с легкостью анализировать их, необходимо работать с исходниками libGDX.

Прежде чем начать, убедитесь, что все необходимое для работы уже установлено. Вам будет нужен C/C++ кросс-компилятор для запуска и тестирования демонстрационных примеров или работа с исходным Java кодом libGDX.

Загрузка исходников libGDX

Чтобы получить исходники и все нативные библиотеки для всех платформ, выполните следующие команды. Вы можете клонировать исходники с помощью Git GUI, как показано ниже.

git clone git://github.com/libgdx/libgdx.git
cd libgdx
ant -f fetch.xml

Этим вы получите весь исходный код из git репозитория, затем из сервера сборки загрузятся нативные файлы с помощью fetch.xml ant скрипта. Для уменьшения размера, Git репозиторий не содержит этих нативных библиотек.

Чтобы пользоваться актуальными версиями вы можете сделать следующие.

git pull
ant -f fetch.xml

Этим самым вы загрузите последние изменения из Git репозитория, а также загрузите последние нативные библиотеки с сервера сборки.

Импорт в Eclipse

Как только у вас есть исходники и нативные библиотеки, вы можете открыть Eclipse и импортировать все проекты:

  • Перейдите File -> Import.
  • Выберите General -> Existing Projects into Workspace.
  • Перейдите в libgdx директорию и убедитесь, что все проекты отмечены.
  • Нажмите кнопку Finish.

Eclipse импортирует все проекты из libgdx директории. При первом импорте обычно везде видно ошибки. Не бойтесь это всего лишь глупости Eclipse. Для решения этой проблемы выполните следующие действия:

  • Перейдите Project -> Clean.
  • Убедитесь, что выбраны все проекты и нажмите кнопку OK.
  • Выберите все проекты в package explorer и затем нажмите F5 для обновления.
  • Еще будет несколько вопросов, касающихся GWT. В Problems окне просмотра щелкните правой кнопкой мыши на каждой записи говорящей "The web.xml file does not exist", выберите Quick Fix и нажмите кнопку OK.

Теперь все готово для начала тестов или запуска демонстрационных игр.

Запуск демо и тестов

Тестовые примеры содержатся в gdx-tests проекте. Этот проект содержит только исходный код. Для запуска тестов на компьютере нужно запустить LwjglTestStarter класс, содержащийся в gdx-tests-lwjgl проекте. Для запуска тестов на Android, просто запустите gdx-tests-android проект в эмуляторе или на устройстве. Для запуска тестов в браузере запустите gdx-tests-gwt проект.

Запуск демо игр работает аналогично. Каждое демо имеет 3-4 проекта, основной проект, Desktop проект, Android проект и HTML5 проект.

Для обоих тестовых и демо примеров используются следующие шаги используются для запуска приложений.

  • Щелкните правой кнопкой мыши на один из вышеупомянутых проектов.
  • Выберите Run As -> Java Application для Desktop проекта. В следующем диалоге выберите LwjglTestStarter.
  • Выберите Run As -> Android Application для Android проект. Это приведет к запуску эмулятора и развертыванию тестового проекта на Android устройстве.
  • Выберите Run As -> Web Application для HTML5 проекта. Откроется новое окно, щелкните на URL. Вы можете получить запрос на установку GWT плагина для браузера. Обратите внимание, что приложение запущено в режиме разработки, который очень медленный. Для получения полной скорости скомпилируйте HTML проект и разверните его на веб сервере.

Для более подробного описания настройки проекта, как запускать и отлаживать libGDX проект смотрите Настройка Проекта, Запуск и Отладка