Error building iOS for device in Release mode

Hey all. I’m getting an error when building my iOS project, but only in specific circumstances. Specifically, if I build in Debug or Release for the Simulator (running iOS 11), I have no problems. If I build in Debug mode for my iPhone SE (iOS 11), no problems. If I build in Release mode for my iPhone SE, I get the following build error:

Aligned allocation function of type 'void *(std::size_t, std::align_val_t)' is only available on iOS 11 or newer.
and
Aligned deallocation function of type 'void (void *, std::align_val_t) noexcept' is only available on iOS 11 or newer.

Coming from the following block in juce_Singleton.h:

    Type* getWithoutChecking()
    {
        if (instance == nullptr)
        {
            auto newObject = new Type(); // I think it's the `new` right here causing the problem
            instance = newObject;
        }

        return instance;
    }

I can get around the problem and successfully build in Release mode for my device if I set the iOS Deployment Target option in Projucer to 11.0 for my Release configuration, but I find it interesting that this is only happening when I try to build for my device, and not when I build for Simulator. Also, ideally, I would like to support more than iOS 11+.

What are my options here? Is this a bugfix in JUCE? Or a constraint on my end that I just have to deal with? Thanks!

Edit: For reference, I am building against JUCE master@06c3674.
Edit: More info, seems to be stemming from the ContentSharer here– https://github.com/WeAreROLI/JUCE/blob/master/modules/juce_gui_basics/filebrowser/juce_ContentSharer.h#L41

I get the same error over here when trying to build and test on my iPhone 6s here. it happens for these functions for me in JUCE 4.3.1:

#if JUCE_COMPILER_SUPPORTS_LAMBDAS
void AudioPluginFormat::createPluginInstanceAsync (const PluginDescription& description,
                                                   double initialSampleRate,
                                                   int initialBufferSize,
                                                   std::function<void (AudioPluginInstance*, const String&)> f)
{
    struct CallbackInvoker  : public AudioPluginFormat::InstantiationCompletionCallback
    {
        CallbackInvoker (std::function<void (AudioPluginInstance*, const String&)> inCompletion)
            : completion (inCompletion)
        {}

        void completionCallback (AudioPluginInstance* instance, const String& error) override
        {
            completion (instance, error);
        }

        std::function<void (AudioPluginInstance*, const String&)> completion;
    };

    createPluginInstanceAsync (description, initialSampleRate, initialBufferSize, new CallbackInvoker (f));
}
#endif

the new CallbackInvoker() is the culprit here ^

#if JUCE_COMPILER_SUPPORTS_LAMBDAS
void AudioPluginFormatManager::createPluginInstanceAsync (const PluginDescription& description,
                                                          double initialSampleRate,
                                                          int initialBufferSize,
                                                          std::function<void (AudioPluginInstance*, const String&)> f)
{
    String error;

    if (AudioPluginFormat* format = findFormatForDescription (description, error))
        return format->createPluginInstanceAsync (description, initialSampleRate, initialBufferSize, f);

    (new PluginFormatManagerHelpers::ErrorLambdaOnMessageThread (error, f))->post();
}
#endif

the new PluginFormatManagerHelpers is the culprit here ^

FWIW, Facebook also has this problem on iOS:

https://github.com/facebook/rocksdb/issues/4064

This problem is solved for me when I manually change the target to iOS 11 in Xcode. however, it makes me wonder how I’m supposed to target devices that don’t have iOS 11 installed yet.

Hmm. I’m struggling to reproduce this.

Could you please provide a project that shows this behaviour on JUCE’s develop branch?

I had to tell ProJucer to use C++17, LLVM libc++. the folks in #iphonedev on FreeNode said its because aligned allocation is a new thing in c++17, so it’s understandable that there is minimal hardware support, especially on iOS.

do you still need a project that does this?

Can’t you just pass -fno-aligned-allocation to the compiler if you want to support older hardware?

3 Likes

Sir, you are a WIZARD! Thank you! now I can support all the way back to iOS 9. awesome!