image

Если в проекте на языке С++ используется SDL2, то обычно исполняемый файл при сборке линкуется с библиотекой динамически. Это не всегда оказывается удобным. Ваше приложение оказывается зависимым от (не)установленных / изменившихся сторонних библиотек, из-за чего в один “прекрасный” момент оно может просто оказаться неработоспособным. В настоящее время лицензия на использование библиотеки SDL2 позволяет без ограничений статически встраивать код библиотеки в Вашу программу. Этим мы сейчас и займемся.

Естественно, размер исполняемого файла при статической линковке увеличится на несколько мегабайт. Но это избавит Ваших потенциальных пользователей от необходимости делать лишние движения - искать в сети, скачивать и устанавливать дополнительные компоненты. Достаточно будет скачать только одно Ваше приложение. Согласитесь - это плюс.

Для проверки и демонстрации соберем небольшую (мультиплатформенную) утилиту, которая при помощи диалогового окна сообщит нам какая используется видео-подсистема, поддерживаемую системой версию OpenGL и GLSL. Возможность получить такие данные будет крайне полезна при разработке будущего графического приложения. Для разработки под MS-Windows нам потребуется i686-w64-mingw и библиотека SDL2.

Весь код приложения на C++ занимает несколько десятков строк. Информацию о версии OpenGL и используемом оборудовании получим при помощи встроенных в OpenGL функций glGetIntegerv() и glGetString() через библиотеку SDL2. С ее помощью мы создадим тестовое окно и необходимый контекст OpenGL. Для создания простого диалогового окна также используем функционал SDL2 (файл gl_ver_test.cpp):

/**
 * gl_ver_test.cpp
 *
 * Tool for display the name of the using video renderer module,
 * and actual versions of the OpenGL and GLSL.
 *
 * dependens: SDL2
 *
 */
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>

void fail(const char *txt)
{
	char* msg = new char[8 + strlen(txt) + strlen(SDL_GetError())];
	sprintf(msg, "\n%s:\n%s\n", txt, SDL_GetError());
	SDL_ClearError();
	if(0 > SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "ERROR", msg, NULL))
		std::cout << msg << std::endl;
	delete[] msg;
	std::exit(EXIT_FAILURE);
}

void show_opengl_version()
{
	GLint major = 0; glGetIntegerv(GL_MAJOR_VERSION, &major);
	GLint minor = 0; glGetIntegerv(GL_MINOR_VERSION, &minor);
	
	char* msg = new char[128];
	sprintf(msg, "\nVideo: %s\nOpenGL version: %i.%i\nGLSL version: %s",
		glGetString(GL_RENDERER), major, minor,
		glGetString(GL_SHADING_LANGUAGE_VERSION));

	SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION,
			"Test OpenGL", msg, NULL);

	delete[] msg;
	return;
}

int main(int argc, char* argv[])
{
	if(SDL_Init(SDL_INIT_EVERYTHING)) fail("Can't init SDL");

	SDL_Window *win = SDL_CreateWindow("",0,0,0,0,SDL_WINDOW_HIDDEN | 
SDL_WINDOW_OPENGL);
	if(!win) fail("Can't create SDL window");
	if(!SDL_GL_CreateContext(win)) fail("Can't create OpenGL context");

	show_opengl_version();
	SDL_DestroyWindow(win);

	SDL_Quit();
	std::exit(EXIT_SUCCESS);
}

Чтобы все корректно скомпилировать, воспользуемся утилитой “make”. Для ее работы надо подготовить рабочий файл параметров, в котором указываются пути поиска библиотек, используемые модули и порядок сборки проекта. Перечень необходимых модулей перечислить по памяти практически невозможно. Да это и не не требуется - в файле i686-w64-mingw32/bin/sdl2-config в конце в секции --static-libs есть перечень всех модулей которые необходимо подключить. Их и укажем в файле параметров Makefile:

#
# Makefile for MS-Windows
#
APP=bin\MSWindows\check_ogl_ver.exe
exec_prefix=D:\mingw32\i686-w64-mingw32

#static link
#CPPFLAGS=
LDLIBS=-L$(exec_prefix)\lib -lmingw32 -lSDL2main -lSDL2  -mwindows \
		-Wl,--no-undefined -lm -ldinput8 -ldxguid -ldxerr8 -luser32 \
		-lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion \
		-luuid -static-libgcc -lopengl32 -static

all: check_ogl_ver runapp

Осталось скомпилировать программу командой make -f Makefile и наслаждаться результатом.

В make-файле под Linux не используется статическая компиляция SDL2. Причина идеологического характера - в Линуксе принято делать так, чтобы каждая программа выполняла только свои функции. Но при желании Вы можете подкорректировать make-файл для получения через sdl2-config параметров для статической линковки файла.