SDL3 + vcpkg on Linux: Fixing “undefined reference to SDL_IBus_Init”

What’s actually going wrong

When vcpkg builds SDL3 on Linux, it compiles support for several input backends — X11, Wayland, and IBus (an input method framework used for CJK and other non-Latin text entry). IBus is listed as a default feature in the SDL3 vcpkg port, so vcpkg enables it automatically unless you opt out.

The catch is that vcpkg warns you the host system needs libibus-1.0-dev installed before the build begins. That warning is easy to scroll past. If the package is absent, vcpkg may still complete the SDL3 build and produce a libSDL3.a archive — but the IBus-specific object files inside it contain references to symbols that were never compiled in. Static linking then exposes all of that at your link step, producing the wall of undefined reference to SDL_IBus_Init errors you’re seeing.

The fix: two steps

First, install the missing system package:

sudo apt install libibus-1.0-dev

Then clear the stale SDL3 build so vcpkg recompiles from scratch with the library now present:

vcpkg remove sdl3
vcpkg install sdl3[core,ibus,wayland,x11]

If you’re using a manifest-based workflow, delete the relevant entries under vcpkg_installed/ and re-run your cmake configure step. vcpkg will detect that SDL3 is gone and rebuild it.

The key point: vcpkg builds and caches binaries. Installing libibus-1.0-dev on your system after vcpkg already cached a build of SDL3 does nothing — you have to force a rebuild.

What “default-features” actually means in vcpkg

A feature listed under default-features in a vcpkg port is not mandatory. It is a preset — on by default, but you can turn it off. The Microsoft documentation on default features describes them as a way to give users a baseline level of functionality when they don’t specify anything. They are explicitly opt-out-able.

So ibus being a default feature means: install SDL3 without specifying features, and vcpkg includes ibus support. That’s the whole implication. You’re not locked in.

Opting out of ibus entirely

If you don’t need IBus support — most projects targeting Western locales don’t — you can leave it out. On the command line, list only the features you want:

vcpkg install "sdl3[core,wayland,x11]"

In a vcpkg.json manifest, set default-features to false on the SDL3 dependency:

{
  "dependencies": [
    {
      "name": "sdl3",
      "default-features": false,
      "features": ["core", "wayland", "x11"]
    }
  ]
}

This is the cleanest approach for a reproducible build — you declare exactly what you need and nothing extra sneaks in.

Why static linking makes this visible

With a shared library (libSDL3.so), IBus symbols get resolved at runtime by the dynamic linker. On a machine that has IBus installed systemwide, they’d be found automatically — you’d never notice the dependency. Static linking works differently. Every symbol inside libSDL3.a has to be resolved at link time by you. SDL3’s IBus code calls into libibus, so that library must appear on your linker command line.

Short version: switching from a shared to a static build surfaces every transitive dependency that was previously hidden.

This also explains why the same project might link fine for a colleague who happens to have libibus-1.0-dev installed — they never thought about it, it was just there.

Still seeing errors after installing libibus-1.0-dev?

There was a bug in the SDL3 vcpkg port where compiling with ibus enabled could produce a broken archive even when the system package was present. A fix was merged in mid-2026 (vcpkg PR #52129). If you’re pinned to an older vcpkg baseline and the undefined reference errors persist after installing the apt package and rebuilding, update your baseline in vcpkg-configuration.json to pull in that fix, then clear and rebuild SDL3.

Sources


Similar Posts