How to import a JUCE static library on an iOS project? (part #2)

Thanks to the Projucer, I created this very basic project, just to understand how to generate a static library for iOS and how to import it on an iOS project.

The library project can be found here.

I managed to generate the library and locate the .a file. By running lipo -info libJuceDemo.a , I can see that it’s a non fat file, targeting the arm64 architecture.

Now I’m trying to import it on an iOS project, and here is what I did:

  • I created a CPP group, then a Juce group, and copied all the necessary files init it, as you can see here:
    image

  • If I go to Runner > Targets > General > Frameworks, Libraries, and Embedded Content , I can see that libJuceDemo.a is here, as expected

  • Then I went to Runner > Project > Build Settings > Search Paths , and for Header Search Paths , I added $SRCROOT/Runner/CPP/Juce and $SRCROOT/../../../../JUCE/modules (where is JUCE installed, basically)

Now when I try to compile and run my iOS app, I get a very long error message, that ends with:

symbol(s) not found for architecture arm64

And I have a whole bunch of error like this:

Undefined symbols for architecture arm64:
      "_MIDIOutputPortCreate", referenced from:
          juce::AudioDeviceManager::setDefaultMidiOutputDevice(juce::String const&) in Runner_lto.o

even though I build my library targeting the arm64 architecture…

What did I miss?

Thanks.

That looks like a linker error. Are those errors only coming from JUCE methods or also from your code?

Can you confirm that libJuceDemo.a exists where Xcode is expecting to find it?

BTW it might be better to keep the conversation in one post rather than keep creating new posts.

Yes libJuceDemo.a is at the expected location (I manage to make my project work with that library, before I call any function of the JUCE framework).

Apparently, since JUCE depends on many iOS frameworks, I might need to import the needed frameworks in the parent project (like CoreMIDI for example).

Could you confirm that? How can I achieve that?

Thanks.

Yes that could well be the issue.

You need to link to the relevant frameworks in your parent project when adding a static library.

You can search for the missing function names in the Apple docs, that is one way to find the associated framework. Below is a list of the frameworks I think JUCE currently relies on (I don’t currently have access to relevant projects to confirm, corrections welcome!)

CoreAudio
AudioToolbox
CoreFoundation
Foundation
accelerate
CoreMIDI
CoreServices
CoreGraphics
libc++.tbd

Thank you very much.

Let’s take the CoreAudio framework for example, how to add it in my parent project?
I haven’t managed yet to find any documentation on that.

Also, I went to Targets > Build Phases > Link Binary With Libraries, clicked on the + button, search for CoreAudio.framework, added it, but nothing changed…

In Xcode, go to the General tab in your target. Scroll down to “Frameworks, Libraries Embedded Content”. Click the [+] icon

1 Like

Still the same errors, nothing changes…

As you can see here your missing function is from CoreMIDI not CoreAudio. Try adding CoreMIDI and see if that fixes that particular linker error.

1 Like

Yep, good catch!
Thank you very much!!!
I’ll continue trying fixing the remaining errors.

OK so I have one last error, that I don’t understand:

Undefined symbols for architecture arm64:
      "juce::this_will_fail_to_link_if_some_of_your_compile_units_are_built_in_debug_mode::this_will_fail_to_link_if_some_of_your_compile_units_are_built_in_debug_mode()", referenced from:
          __GLOBAL__sub_I_NativeLib.cpp in NativeLib.o
    ld: symbol(s) not found for architecture arm64

Which is weird since I built my library in release mode…

Search is your friend: Manually linking to JUCE sources without PROJUCER - #2 by rtavakko

OK but I still don’t get it: in the JUCE source code, I can read: “if you have two cpp files, and one includes the juce headers with debug enabled, and another does so without that, …”

What does “includes the juce headers with debug enabled” mean?
Does it have something to do with the #ifndef instruction?

I finally managed to make it work!

So here is what I was missing, in the parent project:

  • go to Targets > Build Settings > Apple Clang - Preprocessing
  • in Preprocessor Macros, for all non-debug configurations, add NDEBUG=1 and _NDEBUG=1

Now it compiles and run.

1 Like