Fixing linking issues with VitaSDK
One of the most common issues developers have while working with VitaSDK is compilation failing on the linking stage. When that happens, you see something like this in the terminal output:
1
2
3
4
5
6
7
/usr/local/vitasdk/bin/../lib/gcc/arm-vita-eabi/10.3.0/../../../../arm-vita-eabi/bin/ld: /usr/local/vitasdk/arm-vita-eabi/lib/libSDL.a(SDL_vitaaudio.o): in function `VITAAUD_CloseAudio':
(.text+0x112): undefined reference to `sceAudioOutReleasePort'
/usr/local/vitasdk/bin/../lib/gcc/arm-vita-eabi/10.3.0/../../../../arm-vita-eabi/bin/ld: /usr/local/vitasdk/arm-vita-eabi/lib/libSDL.a(SDL_vitaaudio.o): in function `VITAAUD_PlayAudio':
(.text+0x15c): undefined reference to `sceAudioOutSetVolume'
/usr/local/vitasdk/bin/../lib/gcc/arm-vita-eabi/10.3.0/../../../../arm-vita-eabi/bin/ld: (.text+0x168): undefined reference to `sceAudioOutOutput'
/usr/local/vitasdk/bin/../lib/gcc/arm-vita-eabi/10.3.0/../../../../arm-vita-eabi/bin/ld: /usr/local/vitasdk/arm-vita-eabi/lib/libSDL.a(SDL_vitaaudio.o): in function `VITAAUD_OpenAudio':
(.text+0x202): undefined reference to `sceAudioOutOpenPort'
You can easily Google what this means exactly if you don’t know. Here I just want to share two tips specific to the Vita development.
1. Check your linking order
With VitaSDK, the order in which you link libraries matters. It goes from left to right (or top to bottom if you’re looking at a typical CMakeLists). That means that you have to put your dependant libraries on the left, and the ones that satisfy those dependencies on the right.
Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Correct: VitaGL depends on VitaShark, which depends
# on SceShaccCgExt, which depends on SceShaccCg; also, SceGxm.
target_link_libraries(${CMAKE_PROJECT_NAME}
vitaGL
vitashark
SceShaccCgExt
SceShaccCg_stub
SceGxm_stub )
# Incorrect: VitaGL depends on VitaShark,
# so VitaGL must precede VitaShark on the list.
target_link_libraries(${CMAKE_PROJECT_NAME}
vitashark
vitaGL
SceShaccCgExt
SceShaccCg_stub
SceGxm_stub )
2. Find the missing symbol
If it’s not about the order, you’re probably not linking the library you need at all. I have a tiny handy script to help with finding what that library is called.
Go to your $VITASDK/bin/
, create a vita-find-symbol
file and make it executable:
1
2
3
cd $VITASDK/bin/
touch vita-find-symbol
chmod +x vita-find-symbol
Using your text editor of choice, put the following content into the file we just created:
1
2
3
#!/bin/bash
for lib in $(find $VITASDK/arm-vita-eabi/lib -name \*.a) ; do arm-vita-eabi-nm --defined-only -A $lib 2> /dev/null | grep "$@" | grep -v " U " ; done
Now you can use the vita-find-symbol
command to quickly find out what you forgot to link. For example, when you’re getting the following error:
1
arm-vita-eabi/bin/ld: (.text+0x168): undefined reference to `sceAudioOutOutput'
If you run vita-find-symbol sceAudioOutOutput
, you’ll see this:
1
2
3
4
5
~$ vita-find-symbol sceAudioOutOutput
/opt/vitasdk/arm-vita-eabi/lib/libSceAudio_stub_weak.a:SceAudio_SceAudio_sceAudioOutOutput.wo:00000001 a GEN_WEAK_EXPORTS
/opt/vitasdk/arm-vita-eabi/lib/libSceAudio_stub_weak.a:SceAudio_SceAudio_sceAudioOutOutput.wo:00000000 T sceAudioOutOutput
/opt/vitasdk/arm-vita-eabi/lib/libSceAudio_stub.a:SceAudio_SceAudio_sceAudioOutOutput.o:00000000 a GEN_WEAK_EXPORTS
/opt/vitasdk/arm-vita-eabi/lib/libSceAudio_stub.a:SceAudio_SceAudio_sceAudioOutOutput.o:00000000 T sceAudioOutOutput
Which means that you should adjust your CMakeLists/Makefile to include SceAudio_stub
:
1
target_link_libraries(${CMAKE_PROJECT_NAME} <...> SceAudio_stub)