JUCE 6.1.3 Undefined symbol _kIOMainPortDefault

Hello,
I just bumped JUCE from 6.1.2 to 6.1.3 and have a new linker error:

[build] Undefined symbols for architecture x86_64:
[build]   "_kIOMainPortDefault", referenced from:
[build]       juce::(anonymous namespace)::getAppleRemoteDevice()::$_10::operator()() const in libjuce_common.a(juce_gui_extra.mm.o)

The error was apparently introduced in this commit. I suspect this is not really a JUCE problem, but maybe someone else will have encountered this.

I’m using clang 13.0.0_2 fresh from homebrew. Here is the (edited) link command that fails:

/usr/local/Cellar/llvm/13.0.0_2/bin/clang++ -g 
 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.0.sdk 
 -mmacosx-version-min=11.6 
 -Wl,-search_paths_first -Wl,-headerpad_max_install_names  app/CMakeFiles/app.dir
 -framework  OpenGL  -framework  CoreAudioKit  -framework  DiscRecording  
 -framework  WebKit  -framework  Carbon  -framework  QuartzCore  
 -framework  CoreAudio  -framework  CoreMIDI  -framework  AudioToolbox
 -framework  Accelerate  -framework  Cocoa  -framework  Foundation  
 -framework  IOKit
 [... all my translation units...]
 -o my_app

The problem disappears if I switch to Apple Clang 13.0.0 (same link arguments but running /usr/bin/clang++).

Can you provide some more information about your build to help track this down - what deployment target do you have set? And which macOS SDK are you building against? Are you able to reproduce this with a basic JUCE GUI application or are you building a plug-in?

I’ll try to bake a minimal example of this later today, but in the meantime: macOS SDK is 12.0 (as per the command line above), with option macosx-version-min=11.6. In case it’s relevant: I am building a macOS GUI app, not in the standard way but by linking against a static lib that contains JUCE modules:

juce::juce_opengl
juce::juce_dsp
juce::juce_audio_utils
juce::juce_audio_plugin_client

and their dependencies.

Could you please try deleting this line? JUCE/juce_mac_AppleRemote.mm at develop · juce-framework/JUCE · GitHub

Without this line, I get the same linker error as above, plus an additional warning:

warning: 'kIOMainPortDefault' is only available on macOS 12.0 or newer [-Wunguarded-availability-new]
note: enclose 'kIOMainPortDefault' in an @available check to silence this warning

Thanks. That was a bit of a long shot as it’s really not clear what’s going wrong here. Something in the newer compiler not finding a symbol in the same set of frameworks? Sorry we can’t be more helpful.

I will try to reproduce it minimally (not today as previously mentioned, but soon hopefully). Could you give me a bit more context as to when this constant is used? What should I use in my minimal example to require access to it?

I’ve just tried the same compiler invocation on an x86_64 12.0.1 macOS, with the following test app:

#import <IOKit/IOKitLib.h>

#include <iostream>

int main()
{
   #if defined (MAC_OS_VERSION_12_0) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_12_0
    std::cout << "MAC_OS_VERSION_12_0\n";
    if (@available (macOS 12.0, *))
    {
        std::cout << "kIOMainPortDefault\n";
        return kIOMainPortDefault;
    }
   #endif

    std::cout << "kIOMasterPortDefault\n";
    return kIOMasterPortDefault;
}

That builds and links correctly for me, with

MAC_OS_VERSION_12_0
kIOMainPortDefault

printed when I run.

Hi @t0m, sorry for the late reply, here is a bit more info.

Calling kikoo.mm your test app above, here is are some raw findings:

$CLANG kikoo.mm fails at link time for both $CLANG=/usr/bin/clang++ (Xcode’s latest clang) and $CLANG=/usr/local/Cellar/llvm/13.0.0_2/bin/clang++ (Homebrew’s clang).

Undefined symbols for architecture x86_64:
  "_kIOMainPortDefault", referenced from:
      _main in kikoo-a29ff3.o
  "_kIOMasterPortDefault", referenced from:
      _main in kikoo-a29ff3.o
ld: symbol(s) not found for architecture x86_64

That’s expected I guess. Adding -framework IOKit to the command lines above solves the issue in both cases (linking succeeds).

Now compiling through this simple CMakeLists.txt :

juce_add_gui_app(kikoo)
target_sources(kikoo PRIVATE kikoo.mm)
target_link_libraries(kikoo 
  PRIVATE
    juce::juce_gui_extra
    juce::juce_recommended_lto_flags
    juce::juce_recommended_warning_flags
    juce::juce_recommended_config_flags
)

With Xcode’s clang selected, linking succeeds. Linking command line:

/usr/bin/clang++ -O2 -g -DNDEBUG -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names  kikoo/CMakeFiles/kikoo.dir/kikoo.mm.o kikoo/CMakeFiles/kikoo.dir/__/extern/JUCE/modules/juce_gui_extra/juce_gui_extra.mm.o kikoo/CMakeFiles/kikoo.dir/__/extern/JUCE/modules/juce_gui_basics/juce_gui_basics.mm.o kikoo/CMakeFiles/kikoo.dir/__/extern/JUCE/modules/juce_graphics/juce_graphics.mm.o kikoo/CMakeFiles/kikoo.dir/__/extern/JUCE/modules/juce_events/juce_events.mm.o kikoo/CMakeFiles/kikoo.dir/__/extern/JUCE/modules/juce_core/juce_core.mm.o kikoo/CMakeFiles/kikoo.dir/__/extern/JUCE/modules/juce_data_structures/juce_data_structures.mm.o -o kikoo/kikoo_artefacts/RelWithDebInfo/kikoo.app/Contents/MacOS/kikoo  -framework  WebKit  -framework  Carbon  -framework  QuartzCore  -framework  Cocoa  -framework  Foundation  -framework  IOKit

Now when Homebrew’s clang is selected, linking fails as above. The command line is exactly the same, except for the executable path obviously (/usr/local/Cellar/llvm/13.0.0_2/bin/clang++).

I realize this is quite a raw lot of info, and probably beyond the scope of JUCE per se…
Can you reproduce this at all?

I tried using CMake 3.22.1 and Homebrew clang version 13.0.0 on both an macOS 12.1 ARM and x86_64 Mac, using the Makefiles exporter and VERBOSE=1 make.

JUCE develop branch tip.

cmake_minimum_required(VERSION 3.15)

project(kikoo VERSION 1.0.0 LANGUAGES C CXX)

add_subdirectory(JUCE)

juce_add_gui_app(kikoo)
target_sources(kikoo PRIVATE kikoo.mm)
target_link_libraries(kikoo 
  PRIVATE
    juce::juce_gui_extra
    juce::juce_recommended_lto_flags
    juce::juce_recommended_warning_flags
    juce::juce_recommended_config_flags
)

ARM link line:

/opt/homebrew/opt/llvm/bin/clang++  -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/kikoo.dir/kikoo.mm.o CMakeFiles/kikoo.dir/JUCE-dev/modules/juce_gui_extra/juce_gui_extra.mm.o CMakeFiles/kikoo.dir/JUCE-dev/modules/juce_gui_basics/juce_gui_basics.mm.o CMakeFiles/kikoo.dir/JUCE-dev/modules/juce_graphics/juce_graphics.mm.o CMakeFiles/kikoo.dir/JUCE-dev/modules/juce_events/juce_events.mm.o CMakeFiles/kikoo.dir/JUCE-dev/modules/juce_core/juce_core.mm.o CMakeFiles/kikoo.dir/JUCE-dev/modules/juce_data_structures/juce_data_structures.mm.o -o kikoo_artefacts/kikoo.app/Contents/MacOS/kikoo  -framework WebKit -framework Carbon -framework QuartzCore -framework Cocoa -framework Foundation -framework IOKit

x86_64 link line:

/usr/local/Cellar/llvm/13.0.0_2/bin/clang++  -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX12.1.sdk -mmacosx-version-min=12.0 -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/kikoo.dir/kikoo.mm.o CMakeFiles/kikoo.dir/JUCE/modules/juce_gui_extra/juce_gui_extra.mm.o CMakeFiles/kikoo.dir/JUCE/modules/juce_gui_basics/juce_gui_basics.mm.o CMakeFiles/kikoo.dir/JUCE/modules/juce_graphics/juce_graphics.mm.o CMakeFiles/kikoo.dir/JUCE/modules/juce_events/juce_events.mm.o CMakeFiles/kikoo.dir/JUCE/modules/juce_core/juce_core.mm.o CMakeFiles/kikoo.dir/JUCE/modules/juce_data_structures/juce_data_structures.mm.o -o kikoo_artefacts/kikoo.app/Contents/MacOS/kikoo  -framework WebKit -framework Carbon -framework QuartzCore -framework Cocoa -framework Foundation -framework IOKit

Unfortunately both links were successful, so more digging is required.