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)
This post is licensed under CC BY 4.0 by the author.

Trending Tags