Audio doesn't work with brew's sdl2

I’ve built one of my projects with homebrew on Gentoo Linux, but it seems the sdl2 library shipped by homebrew can’t open any audio devices. Can someone build and run this test program so I can see if that’s just me or a more general problem?

#include <SDL.h>
#include <SDL_audio.h>
#include <stdio.h>
#include <string.h>

int main()
{
    if (SDL_InitSubSystem(SDL_INIT_AUDIO) != 0) {
        fprintf(stderr, "SDL init error: %s\n", SDL_GetError());
        return 1;
    }
    
    printf("audio device count: %d\n", SDL_GetNumAudioDevices(0));
    
    SDL_AudioSpec requestedSpec = {0};
    requestedSpec.freq = 44100;
    requestedSpec.format = AUDIO_S16SYS;
    requestedSpec.channels = 2;
    requestedSpec.samples = 4096;
    
    SDL_ClearError();
    if (SDL_OpenAudio(&requestedSpec, NULL) != 0) {
        fprintf(stderr, "failed to open audio device: %s\n", SDL_GetError());
        return 1;
    }
    puts("audio device opened successfully");
    return 0;
}

Compile it with:

gcc $(pkg-config --cflags sdl2) sdltest.c $(pkg-config --libs sdl2) -o sdltest

and run it with:

./sdltest

Post the output here.

I’m getting this, which means the homebrew provided sdl2 library is for some reason unable to find any audio devices:

audio device count: 0
failed to open audio device: No such audio device

I can confirm that the bottled SDL2 triggers the same error on Ubuntu 19.10, but SDL2 built from source works just fine:

$ ./sdltest 
audio device count: 1
audio device opened successfully

Try:

brew rm --ignore-dependencies sdl2
brew install -s sdl2

then recompile and run your test program.

That’s annoying. Sounds like the ./configure script is doing some auto-detection at build time that’s not finding the necessary audio libraries or devices and failing to enable audio. See https://github.com/Homebrew/linuxbrew-core/blob/9a136e8cbff5b1ddd6dce5b947411102b06e66c2/Formula/sdl2.rb#L52-L53
To troubleshoot, I’d suggest building from source in a Docker container (using the homebrew/brew Docker image) and comparing the resulting configure logs (stdout and config.log) to those that you get when compiling on your local machine.
Best of luck!

OK, here’s the logs from an Ubuntu 19.10 build: https://gist.github.com/gromgit/5917abe5d7d2b72df800f65fda3a2611

And here’s the logs from a Homebrew container build: https://gist.github.com/gromgit/050a77b70fcff92bc42dbf37aabd822c

@sjackman, it looks like you hit the nail on the head. From a diff of 01.configure:

$ diff ubuntu-19.10/01.configure docker-brew/01.configure
...
289,293c289,291
< checking for libasound headers version >= 1.0.11... found.
< checking for snd_ctl_open in -lasound... yes
< -- dynamic libasound -> libasound.so.2
< checking for PULSEAUDIO... yes
< -- dynamic libpulse-simple -> libpulse-simple.so.0
---
> checking for libasound headers version >= 1.0.11... not present.
> checking for snd_ctl_open in -lasound... no
> checking for PULSEAUDIO... no
...
401,402c396,397
< Audio drivers   : disk dummy oss alsa(dynamic) pulse(dynamic)
< Video drivers   : dummy x11(dynamic) opengl_es2 vulkan
---
> Audio drivers   : disk dummy oss
> Video drivers   : dummy x11 opengl_es2 vulkan

However, I think it’s actually a problem with configure not being able to find pkg-config:

107,109c108,109
< checking for windres... windres
< checking for pkg-config... /usr/bin/pkg-config
< checking pkg-config is at least version 0.9.0... yes
---
> checking for windres... no
> checking for pkg-config... no

Note that SDL2 configure on Ubuntu 19.10 found and used the system pkg-config, even though I’d installed the Homebrew version and ensured it was first in my $PATH:

ubuntu-19.10$ type -ap pkg-config
/home/linuxbrew/.linuxbrew/bin/pkg-config
/usr/bin/pkg-config
/usr/bin/X11/pkg-config

So even after a manual brew install pkg-config in the container, it took a patch to super.rb to get things working:

diff --git a/Library/Homebrew/extend/ENV/super.rb b/Library/Homebrew/extend/ENV/super.rb
index 2aa440689..c8a9cccc4 100644
--- a/Library/Homebrew/extend/ENV/super.rb
+++ b/Library/Homebrew/extend/ENV/super.rb
@@ -44,6 +44,7 @@ module Superenv
     self["HOMEBREW_ENV"] = "super"
     self["MAKEFLAGS"] ||= "-j#{determine_make_jobs}"
     self["PATH"] = determine_path
+    self["PKG_CONFIG"] = DevelopmentTools.locate("pkg-config")
     self["PKG_CONFIG_PATH"] = determine_pkg_config_path
     self["PKG_CONFIG_LIBDIR"] = determine_pkg_config_libdir
     self["HOMEBREW_CCCFG"] = determine_cccfg

Once I did that, brew install -s sdl2 found Pulseaudio:

docker-brew$ cat ~/.cache/Homebrew/Logs/sdl2/01.configure
...
checking pkg-config is at least version 0.9.0... yes
...
checking for PULSEAUDIO... yes
-- dynamic libpulse-simple -> libpulse-simple.so.0
...
Audio drivers   : disk dummy oss pulse(dynamic)

Of course, this being a container, running @realnc’s test program still doesn’t find any audio devices, but at least the build logs now say We Have Audio.

Summary

  • Add PKG_CONFIG to superenv (why was this left out, when PKG_CONFIG_PATH and PKG_CONFIG_LIBDIR are explicitly set?), or /usr/bin/pkg-config to container image
  • Add pkg-config as an sdl2 build dependency
1 Like

That should also fix the path issue without needing to modify Superenv.
Does pulseaudio need to be added as a dependency?

Please do open a PR once you get it working!

Done, https://github.com/Homebrew/linuxbrew-core/pull/19767

It turns out:

was the only issue, as pulseaudio was already a declared dependency.

Also, TIL it’s not enough to install pkg-config via Homebrew. I wonder how many other bottle builds are missing functionality because pkg-config wasn’t declared as a build dependency, despite the underlying libs being properly depended upon.

EDIT: To be clear, I understand the need for superenv’s extreme sanitization. It just bites folks who don’t understand Homebrew internals in weird and unexpected ways.

Woohoo! Glad to hear that you got it working, and thanks for the PR!