2015-08-05 4 views
1

Я создаю программу SDL2/C++, которая должна быть переносимой на компьютеры Windows, Mac и Linux, у которых может не быть установлен SDL.Межплатформенное статическое связывание SDL2

Я читал, что статическое связывание - это решение, но я не очень хорошо разбираюсь и не знаю, как статическую ссылку.

Моя программа полагается только на SDL2, GLU и OpenGL. Я компилирую C++ с помощью MinGW (в Windows 8.1) или gcc (на Ubuntu 14.04) - обе эти ОС имеют встроенный SDL.

Вот мой текущий Makefile, полученный из образца Makefile вверенного мне профессор шахты:

# Executable/file name 
EXE=experiment 

# MinGW 
ifeq "$(OS)" "Windows_NT" 
CFLG=-O3 -Wall -DUSEGLEW 
LIBS= -lSDL2 -lglu32 -lopengl32 
CLEAN=del *.exe *.o *.a 
else 
# OSX 
ifeq "$(shell uname)" "Darwin" 
CFLG=-O3 -Wall -Wno-deprecated-declarations 
LIBS=-framework SDL2 -framework OpenGL 
# Linux\Unix\Solaris 
else 
CFLG=-O3 -Wall 
LIBS= `sdl2-config --cflags --libs` -lGLU -lGL -lm 
endif 
# OSX\Linux\Unix\Solaris 
CLEAN=rm -f $(EXE) *.o *.a 
endif 

# Dependencies 
$(EXE).o: $(EXE).cpp FORCE 


.c.o: 
    gcc -c -o [email protected] $(CFLG) $< 
.cpp.o: 
    g++ -std=c++11 -c -o [email protected] $(CFLG) $< 

# Link 
$(EXE):$(EXE).o 
    g++ -std=c++11 -O3 -o [email protected] $^ $(LIBS) 

# Clean 
clean: 
    $(CLEAN) 

# Force 
FORCE: 

ответ

1

Чтобы связать со статической библиотекой вы либо указать путь к библиотеке файлу

gcc -o out_bin your_object_files.o path/to/lib.a -lfoo

или попросить линкер использовать статическую версию с флагом-линкером -Bstatic. Обычно вам нужно сбросить привязку назад к динамической для остальных библиотек, например. для статического SDL2 и GLU, но динамического GL:

gcc -o out_bin your_object_files -Wl,-Bstatic -lSDL2 -lGLU -Wl,-Bdynamic -lGL

Это, конечно, означает, что статические варианты библиотек присутствуют в библиотеке список поиска пути (.a ЛИЭСА для GCC на все указанные платформы, хотя MSVC использует .lib для статического библиотеки).

Однако вы обычно не хотите этого делать вообще. Обычно программное обеспечение зависит от некоторых библиотек (широко распространенных в Linux, с пакетами и списками зависимостей) или привозит с собой необходимые библиотеки. Вы можете просто распределить динамическую библиотеку SDL с вашей программой и загрузить ее с помощью LD_LIBRARY_PATH или относительного rpath.

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

+0

Спасибо! Но похоже, что -Bstatic не имеет желаемого эффекта (он все еще ищет SDL2.dll во время выполнения). Удаление «B» и запятых, кажется, исправить это, но затем оно дает множество неопределенных ссылок. Я видел другое решение, которое при связывании статически нужно связать вручную со всем, что ссылается на SDL (-lmingw32 -lSDL2main -lSDL2 -mwindows -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -static-libgcc). Это компиляция без ошибок, но программа не работает. – user258887

+0

Он просто работает тихо в фоновом режиме, не открывая окна. Нужно ли динамически связывать некоторые из этих новых библиотек? Я связываю их все статически, за исключением -lopengl32 и -lm. – user258887

+0

Я понял, что программа зависает при попытке использовать printf() и getline() для stdio вместо фактической печати или получения. Это происходит только при статической привязке. Есть ли что-то особенное в отношении статической связи с stdio? – user258887

0

Это не было связано непосредственно со статическим связыванием. При статической привязке мне пришлось включить все библиотеки зависимостей SDL. Оказывается, наличие -mwindows приводит к сбою связи консоли.

Смежные вопросы