[SOLVED] OS.X Cmake Juce (Undefined symbols for architecture x86_64)


#1

Hi,

I'm familiar with c++ but I don't know how to configure a project because I just worked on projects that have already been configured or used tools doing the job for me.

I would like to do this step by mylself. 

And of course I'm facing some problems ! I'm stuck in the mud for several days !

I want to make an app using Juce (and after Qt).

I tyied IntroJuicer. Worked fine. It made me a beatiful Xcode Project I can start with.

But as I said, I want to understand how to configure a project by myself !

So I would like to use CMake to build my application.

I've found two tutorials:

  • https://github.com/nclack/cmake-juce (for osx)
  • http://www.juce.com/forum/topic/how-i-use-cmake-juce (for linux)

And in the two cases I always get that error:


Linking CXX executable main
Undefined symbols for architecture x86_64:
  "_AudioHardwareServiceGetPropertyData", referenced from:
      juce::SystemVol::getGain() in libjuce.a(juce_audio_devices.cpp.o)
      juce::SystemVol::isMuted() in libjuce.a(juce_audio_devices.cpp.o)
      juce::SystemVol::SystemVol(unsigned int) in libjuce.a(juce_audio_devices.cpp.o)
  "_AudioHardwareServiceHasProperty", referenced from:
      juce::SystemVol::SystemVol(unsigned int) in libjuce.a(juce_audio_devices.cpp.o)
  "_AudioHardwareServiceIsPropertySettable", referenced from:
      juce::SystemVol::canSetVolume() in libjuce.a(juce_audio_devices.cpp.o)
  "_AudioHardwareServiceSetPropertyData", referenced from:
      juce::SystemVol::setGain(float) in libjuce.a(juce_audio_devices.cpp.o)
      juce::SystemVol::setMuted(bool) in libjuce.a(juce_audio_devices.cpp.o)
  "_vDSP_vadd", referenced from:
      juce::FloatVectorOperations::add(float*, float const*, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vaddD", referenced from:
      juce::FloatVectorOperations::add(double*, double const*, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vclr", referenced from:
      juce::FloatVectorOperations::clear(float*, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vclrD", referenced from:
      juce::FloatVectorOperations::clear(double*, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vfill", referenced from:
      juce::FloatVectorOperations::fill(float*, float, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vfillD", referenced from:
      juce::FloatVectorOperations::fill(double*, double, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vmul", referenced from:
      juce::FloatVectorOperations::multiply(float*, float const*, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vmulD", referenced from:
      juce::FloatVectorOperations::multiply(double*, double const*, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vneg", referenced from:
      juce::FloatVectorOperations::negate(float*, float const*, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vnegD", referenced from:
      juce::FloatVectorOperations::negate(double*, double const*, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vsmul", referenced from:
      juce::FloatVectorOperations::multiply(float*, float, int) in libjuce.a(juce_audio_basics.cpp.o)
      juce::FloatVectorOperations::copyWithMultiply(float*, float const*, float, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vsmulD", referenced from:
      juce::FloatVectorOperations::copyWithMultiply(double*, double const*, double, int) in libjuce.a(juce_audio_basics.cpp.o)
      juce::FloatVectorOperations::multiply(double*, double, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vsub", referenced from:
      juce::FloatVectorOperations::subtract(float*, float const*, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vsubD", referenced from:
      juce::FloatVectorOperations::subtract(double*, double const*, int) in libjuce.a(juce_audio_basics.cpp.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [src-main/main] Error 1
make[1]: *** [src-main/CMakeFiles/main.dir/all] Error 2
make: *** [all] Error 2

Ater reading dozen of threads on various forums, I finally mixed and adapted the two tutorials together... Of course, I get the same error...

Here is my project:

/CMakeLists.txt

/lib/

-----/juce/

----------Appconfig.h

----------JuceHeader.h

----------modules/

---------------juce_audio_basics/

--------------------modules files...

---------------juce_audio_devices/

--------------------modules files...

---------------juce_audio_formats/

--------------------modules files...

---------------juce_core/

--------------------modules files...

---------------juce_data_structures/

--------------------modules files...

---------------juce_events/

--------------------modules files...

/src-juce/

-----CMakeLists.txt

/src-main/

-----CMakeLists.txt

-----Main.cpp

 

/CMakeLists.txt:


cmake_minimum_required(VERSION 2.8)
INCLUDE_DIRECTORIES ( BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/lib/juce )
ADD_SUBDIRECTORY ( src-juce )
ADD_SUBDIRECTORY ( src-main )

/src-juce/CMakeLists.txt:

SET( CMAKE_CXX_FLAGS "-std=c++0x")

set_directory_properties(PROPERTIES
  COMPILE_DEFINITIONS         NDEBUG
  COMPILE_DEFINITIONS_DEBUG   DEBUG
  COMPILE_DEFINITIONS_RELEASE NDEBUG
)

SET(JUCE_LIBRARIES
    "-framework Carbon"
    "-framework Cocoa"
    "-framework CoreFoundation"
    "-framework CoreAudio"
    "-framework CoreMidi"
    "-framework QuartzCore"
    "-framework IOKit"
    "-framework AGL"
    "-lobjc")

SET(EXTRA_FLAGS "-x objective-c++")

SET ( JUCE_SOURCE
        ${CMAKE_HOME_DIRECTORY}/lib/juce/modules/juce_core/juce_core.cpp
        ${CMAKE_HOME_DIRECTORY}/lib/juce/modules/juce_data_structures/juce_data_structures.cpp
        ${CMAKE_HOME_DIRECTORY}/lib/juce/modules/juce_events/juce_events.cpp
        ${CMAKE_HOME_DIRECTORY}/lib/juce/modules/juce_audio_basics/juce_audio_basics.cpp
        ${CMAKE_HOME_DIRECTORY}/lib/juce/modules/juce_audio_devices/juce_audio_devices.cpp
        ${CMAKE_HOME_DIRECTORY}/lib/juce/modules/juce_audio_formats/juce_audio_formats.cpp
    )

ADD_LIBRARY ( juce STATIC ${JUCE_SOURCE} )
TARGET_LINK_LIBRARIES ( juce ${CMAKE_THREAD_LIBS_INIT} ${JUCE_LIBRARIES} )
set_target_properties(juce PROPERTIES COMPILE_FLAGS ${EXTRA_FLAGS})

/src-main/CMakeLists.txt:


SET( CMAKE_CXX_FLAGS "-std=c++0x")
FILE ( GLOB_RECURSE MAIN_SOURCE *.cpp )
LIST ( SORT MAIN_SOURCE )
ADD_EXECUTABLE ( main ${MAIN_SOURCE} )
TARGET_LINK_LIBRARIES ( main juce )

/src-main/Main.cpp:


#include <iostream>

#include "../lib/juce/JuceHeader.h"

int main(int argc, char *argv[]) {
    std::cout << "Bonjour" << std::endl;
    File audioFile("/path/to/myfile.wav");
    WavAudioFormat format;
    
    FileInputStream *fileInputStream = new FileInputStream(audioFile);;
    ScopedPointer<juce::AudioFormatReader> reader(format.createReaderFor(fileInputStream,false));
    
    AudioFormatReaderSource readerSource(reader, false);
    AudioTransportSource transportSource;
    transportSource.setSource(&readerSource);
    
    std::cout << transportSource.getLengthInSeconds() << std::endl;
    
    AudioSourcePlayer sourcePlayer;
    sourcePlayer.setSource(&transportSource);
    
    AudioDeviceManager deviceManager;
    deviceManager.initialiseWithDefaultDevices(0, 2);
    deviceManager.addAudioCallback(&sourcePlayer);
    
    transportSource.start();
    
    while (! transportSource.hasStreamFinished()) {
        
    }
    
    std::cout << transportSource.isPlaying() << std::endl;
  return 0;
}

I can't figure out what's wrong !

Any idea ?

Many thanks !!!

---FatMaxX

PS : please pardon my lack of knowledge and my english.


#2

Are you familiar with cmake? Why do you like to start with Juce and switching to Qt later???

I also use cmake for other projects (Qt projects) and was thinking about to use it for Juce projects too, but Juce is more easy without cmake and manage the things for you and generate projects for each OS and also for free IDE's like CodeBlocks.

Just my opinion, but do not waste your time with this idea...


#3

Are you familiar with cmake?

A friend quickly introduice me to cmake and I read some doc...

Why do you like to start with Juce and switching to Qt later???

Sorry, I was not clear. I want to use Juce (audio/midi) and Qt (graphical) but I would like to configure juce first. I'll see how to link Qt later.

Juce is more easy without cmake and manage the things for you

Indeed, the IntroJuicer is a very helpful tool !!! But I can't see how it works....

I would like to learn how to link a lib, juce in this case, with my c++ code to be sure to well understand the whole process.

In school we never see how it works behind. We always have already configured project to work on.

I'm now in intership in a reseach center and I've already losted some (personal) precious time to try to get this thing working. Of course I'll finally use the IntroJuicer if I'm not able to use cmake but I'll appreciate if someone have some time to explain what's wrong...

Using a tool to automatically configure a project is great when you know how it works behind.


For now, some errors have been solved by adding the AudioToolbox framework in the juce CMakeLists. It still can't find vDSP_*:


Linking CXX executable main
Undefined symbols for architecture x86_64:
  "_vDSP_vadd", referenced from:
      juce::FloatVectorOperations::add(float*, float const*, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vaddD", referenced from:
      juce::FloatVectorOperations::add(double*, double const*, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vclr", referenced from:
      juce::FloatVectorOperations::clear(float*, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vclrD", referenced from:
      juce::FloatVectorOperations::clear(double*, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vfill", referenced from:
      juce::FloatVectorOperations::fill(float*, float, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vfillD", referenced from:
      juce::FloatVectorOperations::fill(double*, double, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vmul", referenced from:
      juce::FloatVectorOperations::multiply(float*, float const*, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vmulD", referenced from:
      juce::FloatVectorOperations::multiply(double*, double const*, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vneg", referenced from:
      juce::FloatVectorOperations::negate(float*, float const*, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vnegD", referenced from:
      juce::FloatVectorOperations::negate(double*, double const*, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vsmul", referenced from:
      juce::FloatVectorOperations::multiply(float*, float, int) in libjuce.a(juce_audio_basics.cpp.o)
      juce::FloatVectorOperations::copyWithMultiply(float*, float const*, float, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vsmulD", referenced from:
      juce::FloatVectorOperations::copyWithMultiply(double*, double const*, double, int) in libjuce.a(juce_audio_basics.cpp.o)
      juce::FloatVectorOperations::multiply(double*, double, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vsub", referenced from:
      juce::FloatVectorOperations::subtract(float*, float const*, int) in libjuce.a(juce_audio_basics.cpp.o)
  "_vDSP_vsubD", referenced from:
      juce::FloatVectorOperations::subtract(double*, double const*, int) in libjuce.a(juce_audio_basics.cpp.o)
ld: symbol(s) not found for architecture x86_64

Any help would be appreciated !

Thank you for your time.

---FM


#4

Hi,

What was wrong was not difficult to find. The linker said it can't find vDSP classes : I missed the Accelerate framework (Umbrella framework for vector-optimized operations), see https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/OSX_Technology_Overview/SystemFrameworks/SystemFrameworks.html.

For my project (read/write audio/midi) I just depend the following frameworks:

  • Cocoa
  • CoreAudio
  • CoreMidi
  • AudioToolbox
  • Accelerate

​So here is the working /src-juce/CMakeLists.txt


SET(JUCE_LIBRARIES
    "-framework Cocoa"
    "-framework CoreAudio"
    "-framework CoreMidi"
    "-framework AudioToolbox"
    "-framework Accelerate"
    "-lobjc")
SET(EXTRA_FLAGS "-x objective-c++")

SET ( JUCE_SOURCE
        ${CMAKE_HOME_DIRECTORY}/lib/juce/modules/juce_core/juce_core.cpp
        ${CMAKE_HOME_DIRECTORY}/lib/juce/modules/juce_data_structures/juce_data_structures.cpp
        ${CMAKE_HOME_DIRECTORY}/lib/juce/modules/juce_events/juce_events.cpp
        ${CMAKE_HOME_DIRECTORY}/lib/juce/modules/juce_audio_basics/juce_audio_basics.cpp
        ${CMAKE_HOME_DIRECTORY}/lib/juce/modules/juce_audio_devices/juce_audio_devices.cpp
        ${CMAKE_HOME_DIRECTORY}/lib/juce/modules/juce_audio_formats/juce_audio_formats.cpp
    )
ADD_LIBRARY ( juce STATIC ${JUCE_SOURCE} )
TARGET_LINK_LIBRARIES ( juce ${CMAKE_THREAD_LIBS_INIT} ${JUCE_LIBRARIES} )
set_target_properties(juce PROPERTIES COMPILE_FLAGS ${EXTRA_FLAGS})

You can use the IntroJucer to see which frameworks you need. Once you've configured your project with the IntroJucer, open the Xcode project, go on Your project (click on it's name in the lateral bar) --> Build phases --> Link binaries with libraries.

Ciao.