2016-09-30 3 views
0

SDL2와 GLEW를 사용하는 OpenGl 응용 프로그램을 컴파일하려고 시도하고 있는데, 원래 컴파일 된 곳이 아닌 모든 버전의 Linux에서 실행될 수 있습니다. 이렇게하기 위해, 나는 어떤 것도 작동하지 않는 몇 가지 것을 시도했다.Linux에서 SDL2 및 GLEW 응용 프로그램을 정적으로 컴파일하려면 어떻게해야합니까?

각 라이브러리의 웹 사이트 다운로드에서 GLEW 및 SDL의 압축을 푼 루트 디렉토리에 make를 실행하여 생성 된 .a 파일에 직접 연결을 시도했습니다. 이것은 다음과 같은 오류 발생 : 나는 건물을 시도

/usr/bin/ld: /opt/SDL2-2.0.4/build/.libs/libSDL2.a(SDL_syssem.o): undefined reference to symbol '[email protected]@GLIBC_2.2.5' 
//lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line 

을 나는 어떤 점 I에서,하지만 -static를 추가 (pkg-config --libs sdl2pkg-config --libs glew와) 크로스 플랫폼 기능을 제외하고 잘 작동 동적 링크 라이브러리와 마찬가지로 다음과 같은 오류를 얻을 :

/usr/bin/ld: cannot find -lGLEW 
/usr/bin/ld: cannot find -lGL 

내 정적으로 컴파일 GLEW 라이브러리를 가리 키도록 이전 시나리오를 변경할 때, 나는 많은 SDL 기능에서 다음과 같이 정의되지 않은 참조 오류와 함께 OpenGL을 함수에 대한 정의되지 않은 참조 오류를 얻을. -lGL을 추가해도 아무 것도 바뀌지 않습니다.

/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_dynapi.o): In function `SDL_InitDynamicAPI': 
/usr/bin/ld: cannot find -lasound 
/usr/bin/ld: cannot find -lpulse-simple 
/usr/bin/ld: cannot find -lpulse 
/usr/bin/ld: cannot find -lsndio 
/usr/bin/ld: cannot find -lwayland-egl 
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libwayland-cursor.a(libwayland_cursor_la-xcursor.o): In function `XcursorImagesDestroy': 
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libXcursor.a(file.o):(.text+0x7d0): first defined here 
/usr/bin/ld: cannot find -lGLEW 
/usr/bin/ld: cannot find -lGL 
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libX11.a(GetDflt.o): In function `GetHomeDir.part.0': 
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libX11.a(GetDflt.o): In function `GetHomeDir.part.0': 
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libX11.a(xim_trans.o): In function `_XimXTransSocketINETConnect': 
collect2: error: ld returned 1 exit status 

참고 : 나는 모든 라이브러리 pkg-config --libs --static <library name>를 사용하려고하면

/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_dynapi.o): In function `SDL_InitDynamicAPI': 
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_dynapi.o): In function `SDL_InitDynamicAPI': 
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_dynapi.o): In function `SDL_InitDynamicAPI': 
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_LoadObject_REAL': 
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_LoadObject_REAL': 
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_LoadFunction_REAL': 
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_LoadFunction_REAL': 
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_LoadFunction_REAL': 
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_UnloadObject_REAL': 

, 나는 다음과 같은 오류가 출력의 모든 위의 명령에서 g++ -o /path/to/outputExecutable <list of object files>.o <libraries as described above>

주 : 나는하지 않음 이 질문은 스택 교환 네트워크에 관한 다른 질문과 중복되는 것이라고 생각합니다. 왜냐하면 저는 약 1 개월 반 동안 이것을 알아 내려고 노력했기 때문에이 질문들을 매우 많이 보았습니다. 비록 문제가 근본 문제와 다르다.

참고 : 이것은 닫힌 소스 응용 프로그램이므로 동적 연결은 옵션이 아니므로 사용자가 자신의 시스템에 바이너리를 빌드 할 수 있도록 소스 코드를 배포해야합니다.

참고 : 현재 g ++를 통해 Linux로 컴파일하려고하지만 mingw를 사용하여이 응용 프로그램을 Windows 용으로도 배포하려고합니다. 거기에서 작동하는 조언은 Linux 전용 조언보다 바람직하지만, 여기서 끝낼 부분에서 그 부분을 파악할 수 없는지 다른 질문을 할 수 있습니다.

참고 : 저는 우분투 16.04 LTS x64를 사용하여 컴파일하고 있습니다.

이 질문에 대한 답변을 미리 보내 주셔서 감사합니다. 죄송하지만, 가능한 한 많은 정보를 제공하고 싶었습니다. 나는 어떤 대답을 기대합니다!

+1

"나는 우분투 16.04 LTS x64를 사용하여 컴파일하고 있습니다." 아냐, 데비안 구시대에서 모든 것을 다시 빌드하고 구축해야한다. – genpfault

답변

3

이전 Loki 게임은 전체 정적 연결을 수행했습니다. 아마도 더 이상 가치가 없으며 외부 라이브러리를 사용하면 훨씬 어려울 것입니다.

라이브러리는 종종 자체 라이브러리가 필요하지 않습니다. 동적 라이브러리에는 종속성 정보가 내장되어 있지만 정적 라이브러리는 .o 파일의 아카이브 일뿐입니다. 추가 라이브러리를 사용해야하는 이유를 설명하는 섹션 첫 번째 오류는 libSDL2.a가 해결할 수없는 기호 [email protected]@GLIBC_2.2.5 (sem_getvalue 함수, glibc 버전으로 표시됨)을 사용한다는 것입니다. 이는 대부분 -lpthread을 링커 플래그에 추가하지 않았기 때문일 수 있습니다.(libSDL.so은 다른 버전의 pthrtead의 일부 버전에 따라 달라 지므로 직접 사용하지 않으면 수동으로 연결하지 않아도됩니다.)

GLEW는 정적 연결에 문제가 없어야합니다. 당신은 점점 더 구체적인 오류에 대해 알아야합니다. 아마도 라이브러리 순서가 잘못되어 링커가 GL 함수를 해결할 수 없기 때문일 수 있습니다. 실제 연결 선과 일부 '정의되지 않은 참조'오류를보다 구체적으로 확인해야합니다.

pkg-config--static 플래그가 당신에게 종속성 목록을 제공해야한다 (예를 들어 -lpthread 많은 다른 사람의 사이에서 sdl2-config --static-libs의 출력에 있어야합니다)하지만, 주어진 라이브러리와 정적 링크를 생성 자체로하지 않습니다. 정적 링크를 요청하려면 정적 실행 파일 (하드!)을 생성하는 -static gcc 플래그와 -Bstatic링커 플래그가 있습니다. 그러면 정적 라이브러리를 정적 버전으로 사용하여 일부 정적 라이브러리와 일부 동적 라이브러리를 사용할 수 있습니다. -Bdynamic은 동적 라이브러리를 사용하라는 요구에 부응합니다. 예 : 정적 인 SDL과 GLEW를 사용하지만 동적 인 GL 연결 라인은 (직접 연결하지 않고 gc를 사용하는 경우) gcc ${OBJECT_FILES} -Wl,-Bstatic -lSDL2 -lGLEW -Wl,-Bdynamic -lGL -lpthread -ldl -lm <everything else SDL2 requires - query with sdl2-config>과 비슷해야합니다. 두 가지 이유가있을 수 있습니다

귀하의 /usr/bin/ld: cannot find -lasound 라인 - 정적 링크 또는 개발 라이브러리가 설치되지 않은 사실과 관련 (예는 libasound2-dev, libpulse-dev, ... - 적어도 그들은 데비안에, 그것은 가능성 우분투이다라는 것을 다른 이름을 가짐). '사용자'라이브러리에는 일반적으로 예 : libasound.so.2하지만 링커는이 라이브러리에 버전이 있으므로이 라이브러리를 찾지 않습니다. 개발 패키지에는 헤더와 심볼릭 링크 libasound.so -> libasound.so.2이 포함되어 있습니다. 링커가 사용할 방법을 알고 있습니다. SDL2를 통해 간접적으로 사용하는 경우 - 필요하지 않습니다. 공유 SDL2에 이미 버전 관리 라이브러리에 대한 링크가 있습니다.

그러나 그렇게하는 데는 작은 점이있을 수 있습니다. 여러분은 소프트웨어와 함께 requred 공유 라이브러리를 배포하고 rpath 또는 LD_LIBRARY_PATH 환경 변수 (마야, 스팀 등 ... - 요즘 거의 모든 사람들이 이것을하고 있음)를 통해 사용할 수 있습니다. 또한 정적 인 SDL2 사용자라도 SDL2를 자체적으로 재정의 할 수 있습니다 (이것은 SDL2에서 의도적으로 구현 된 기능입니다). 버그가 있거나 아주 다른 환경에서 소프트웨어가 더 이상 업데이트를 얻지 못하면 공유 라이브러리를 교체하여 문제가 해결 될 수 있습니다. 원래 SDL2가 X11 만 지원한다면 사람들이 당신의 프로그램을 wayland 또는 mir에서 돌릴 수 있겠습니까?

in such a way that it will run on any version of Linux it may find itself -- not just where it was originally compiled은 훨씬 복잡하고 솔직히 거의 비현실적입니다 (아주 작은 프로그램이 있고 좋은 전진/후진 호환성을 가진 매우 제한된 라이브러리 세트 만 사용하지 않으면 어렵습니다). 큰 문제 중 하나는 glibc입니다. 일반적으로 glibc의 가능한 가장 낮은 버전을 사용하여 프로그램을 컴파일하는 것이 좋습니다.

요약하면 가능하지만별로 도움이되지 않습니다.

+0

언급 한 이유로 좋은 생각 인 것 같은 .so 파일을 내 응용 프로그램과 함께 배포 할 때 포함시킬 라이브러리와 포함 할 라이브러리가 무엇인지 어떻게 알 수 있습니까? 예를 들어, 모든 SDL의 종속성을 포함해야합니까? 그렇다면 어떻게 그것들 모두의 목록을 찾을 수 있습니까? 또한 libstdC++에 정적으로 링크해야합니까? [this] (https://insanecoding.blogspot.com/2012/07/creating-portable-linux-binaries.html) 문서가 권장합니다 (단순히 내 자신을 배포하면 작동하지 않을 수 있습니다. 사용자 버전을 덮어 쓸 수 없기 때문에)? – john01dav

+1

[ldd] (https://linux.die.net/man/1/ldd)를 사용하여 의존성 목록을 얻을 수 있습니다 (실행 파일과 공유 라이브러리 모두에서 작동합니다). 재귀 적으로 작동하므로 실행 파일을 얻으면 완전한 목록이됩니다.'libc','libm','libdl'과'libpthread'는 존재할 가능성이 매우 높습니다 만, glibc 버전에는 의미가 있습니다 (genpfault의 코멘트 주소 - 이것이 가능한 가장 낮은 glibc의 의미 였지만 확장하는 것을 잊었습니다 더욱이). 그런 다음 몇 가지 비판적인 사고 방식을 적용해야합니다. 프로그램이 그래픽 모드에서만 작동한다면'libX11'을 가져 오는 것이 약간의 포인트입니다. – keltar

관련 문제