Trouble compiling using static library STK, QT Creator and qmake



  • New to the list, so hello everybody!

    I'm new to QT and I'm having trouble compiling a simple example for the STK (Synthesis Toolkit) within QT Creator.

    OS: OS X 10.9
    QT: 5.2.0

    I get the dreaded "Undefined symbols for architecture x86_64" error message. It seems it's related to qmake since I can happily build by simply invoking g++:
    @
    g++ -Wall -I../../lib/stk-4.4.4/include -I../../lib/stk-4.4.4/src/include -L../../lib/stk-4.4.4/src -DHAVE_GETTIMEOFDAY -D__MACOSX_CORE__ -D__LITTLE_ENDIAN__ -DRAWWAVE_PATH="../../lib/stk-4.4.4/rawwaves/" -o main \main.cpp -lstk -lpthread -framework IOKit -framework CoreAudio -framework CoreMIDI -framework CoreFoundation
    @

    STK is being used as a static library, and I already checked that it is x86_64.
    Any help would be greatly appreciated!

    Cheers,
    Ivan

    My pro file:
    @
    TEMPLATE = app
    CONFIG += console
    CONFIG -= app_bundle
    CONFIG -= qt

    QMAKE_CXXFLAGS += -D__MACOSX_CORE__
    QMAKE_CXXFLAGS += -D__LITTLE_ENDIAN__
    CONFIG += x86_64

    SOURCES += main.cpp

    macx: LIBS += -L$$PWD/../../lib/stk-4.4.4/src/ -lstk -lpthread -framework IOKit -framework CoreAudio -framework CoreMIDI -framework CoreFoundation

    INCLUDEPATH += $$PWD/../../lib/stk-4.4.4/include
    DEPENDPATH += $$PWD/../../lib/stk-4.4.4/include

    macx: PRE_TARGETDEPS += $$PWD/../../lib/stk-4.4.4/src/libstk.a
    @

    main.cpp:
    @
    // crtsine.cpp STK tutorial program
    #include "Stk.h"
    #include "SineWave.h"
    #include "RtAudio.h"
    using namespace stk;

    // This tick() function handles sample computation only. It will be
    // called automatically when the system needs a new buffer of audio
    // samples.
    int tick( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
    double streamTime, RtAudioStreamStatus status, void *dataPointer )
    {
    SineWave *sine = (SineWave *) dataPointer;
    register StkFloat *samples = (StkFloat *) outputBuffer;

    for ( unsigned int i=0; i<nBufferFrames; i++ )
    *samples++ = sine->tick();

    return 0;
    }

    int main()
    {
    // Set the global sample rate before creating class instances.
    Stk::setSampleRate( 44100.0 );

    SineWave sine;
    RtAudio dac;

    // Figure out how many bytes in an StkFloat and setup the RtAudio stream.
    RtAudio::StreamParameters parameters;
    parameters.deviceId = dac.getDefaultOutputDevice();
    parameters.nChannels = 1;
    RtAudioFormat format = ( sizeof(StkFloat) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
    unsigned int bufferFrames = RT_BUFFER_SIZE;
    try {
    dac.openStream( &parameters, NULL, format, (unsigned int)Stk::sampleRate(), &bufferFrames, &tick, (void *)&sine );
    }
    catch ( RtError &error ) {
    error.printMessage();
    goto cleanup;
    }

    sine.setFrequency(440.0);

    try {
    dac.startStream();
    }
    catch ( RtError &error ) {
    error.printMessage();
    goto cleanup;
    }

    // Block waiting here.
    char keyhit;
    std::cout << "\nPlaying ... press <enter> to quit.\n";
    std::cin.get( keyhit );

    // Shut down the output stream.
    try {
    dac.closeStream();
    }
    catch ( RtError &error ) {
    error.printMessage();
    }

    cleanup:

    return 0;
    }
    @


  • Moderators

    qmake is probably set to use the clang compiler. There are some minor incompatibilities between g++ and clang linkers (only the ones shipped by Apple. If you build them from source, or use them on Linux, both are 100% compatible), so it might be that it works when run with g++ mkspecs, but fails on clang mkspecs. Read the docs on QMAKESPEC variable for qmake, you problably need to use "macx-g++" one.

    Also, don't forget that the linker is an incremental one: the order in which you specify the libraries is important!



  • Hi sierdzio,
    Thanks for quick reply!
    Actually I'm using the g++ compiler (GCC x86 64 bit), on QT Creator, which I guess as a symbolic link that points to the version encapsulated in XCode's distribution.
    qmake outputs:

    /Applications/Xcode.app/Contents/Developer/usr/bin/g++ -c -pipe -D__MACOSX_CORE__ -D__LITTLE_ENDIAN__ -DHAVE_GETTIMEOFDAY -DRAWWAVE_PATH="../../lib/stk-4.4.4/rawwaves/" -g -gdwarf-2 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -mmacosx-version-min=10.6 -Wall -W -fPIE -I../../../../Development/Qt5.2.0/5.2.0-beta1/clang_64/mkspecs/macx-g++ -I../stkTest10 -I../../lib/stk-4.4.4/include -I. -o main.o ../stkTest10/main.cpp


  • Moderators

    OK, that looks good. Try adding this to .pro file:
    @
    CONFIG += static
    @

    or just pointing directly to the .a file in LIBS.



  • with absolute paths and config I get the exact same results.
    The thing is I've compiled similar code in QT. I did upgrade to 10.9, though...
    I'm really lost on why it's not working! :-)

    @
    TEMPLATE = app
    CONFIG += console
    CONFIG -= app_bundle
    CONFIG -= qt

    QMAKE_CXXFLAGS += -D__MACOSX_CORE__
    QMAKE_CXXFLAGS += -D__LITTLE_ENDIAN__
    QMAKE_CXXFLAGS += -DHAVE_GETTIMEOFDAY
    QMAKE_CXXFLAGS += -DRAWWAVE_PATH="../../lib/stk-4.4.4/rawwaves/"
    CONFIG += static
    CONFIG += x86_64

    SOURCES += main.cpp

    macx: LIBS += -L /Users/ifranco/Dropbox/Development/lib/stk-4.4.4/src/ -lstk -lpthread -framework IOKit -framework CoreAudio -framework CoreMIDI -framework CoreFoundation

    INCLUDEPATH += /Users/ifranco/Dropbox/Development/lib/stk-4.4.4/include
    DEPENDPATH += /Users/ifranco/Dropbox/Development/lib/stk-4.4.4/include

    macx: PRE_TARGETDEPS += /Users/ifranco/Dropbox/Development/lib/stk-4.4.4/src/libstk.a
    @

    same error output:

    @
    14:19:55: Running steps for project stkTest10...
    14:19:55: Configuration unchanged, skipping qmake step.
    14:19:55: Starting: "/usr/bin/make"
    /Applications/Xcode.app/Contents/Developer/usr/bin/g++ -c -pipe -D__MACOSX_CORE__ -D__LITTLE_ENDIAN__ -DHAVE_GETTIMEOFDAY -DRAWWAVE_PATH="../../lib/stk-4.4.4/rawwaves/" -g -gdwarf-2 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -mmacosx-version-min=10.6 -Wall -W -fPIE -I../../../../Development/Qt5.2.0/5.2.0-beta1/clang_64/mkspecs/macx-g++ -I../stkTest10 -I../../lib/stk-4.4.4/include -I. -o main.o ../stkTest10/main.cpp
    ../stkTest10/main.cpp:10:37: warning: unused parameter 'inputBuffer' [-Wunused-parameter]
    int tick( void outputBuffer, void inputBuffer, unsigned int nBufferFrames,
    ^
    ../stkTest10/main.cpp:11:17: warning: unused parameter 'streamTime' [-Wunused-parameter]
    double streamTime, RtAudioStreamStatus status, void dataPointer )
    ^
    ../stkTest10/main.cpp:11:49: warning: unused parameter 'status' [-Wunused-parameter]
    double streamTime, RtAudioStreamStatus status, void dataPointer )
    ^
    3 warnings generated.
    /Applications/Xcode.app/Contents/Developer/usr/bin/g++ -headerpad_max_install_names -all_load -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -mmacosx-version-min=10.6 -o stkTest10 main.o -L /Users/ifranco/Dropbox/Development/lib/stk-4.4.4/src/ -lstk -lpthread -framework IOKit -framework CoreAudio -framework CoreMIDI -framework CoreFoundation
    Undefined symbols for architecture x86_64:
    "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::find_last_of(char const
    , unsigned long, unsigned long) const", referenced from:
    stk::FileWrite::setMatFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in libstk.a(FileWrite.o)
    "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::find_first_of(char const
    , unsigned long, unsigned long) const", referenced from:
    stk::Skini::parseString(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, stk::Skini::Message&) in libstk.a(Skini.o)
    stk::Skini::tokenize(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in libstk.a(Skini.o)
    "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::find_first_not_of(char const
    , unsigned long, unsigned long) const", referenced from:
    stk::Skini::parseString(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, stk::Skini::Message&) in libstk.a(Skini.o)
    stk::Skini::tokenize(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in libstk.a(Skini.o)
    "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::find(char const
    , unsigned long, unsigned long) const", referenced from:
    ...
    @


  • Moderators

    In my experience, whenever Apple updates Xcode or Mac OS, something breaks ;) They support their ObjC stuff very nicely, but everyone else is not so important to them.

    Since now you seem to be getting missing symbols in stdlib, I guess you've hit the Apple wall :( Try switching to clang entirely, or reorder the LIBS so that CoreFoundation is first on the list. You need to experiment and find some combination that works, sadly.



  • What about installing another version of GCC. Would that be doable or am I just getting into "double configuration trouble"?
    OT: thanks for the great support!

    Cheers,
    Ivan



  • still...
    If I'm able to compile using the "fruit's" own GCC (see my initial post), shouldn't it be a qmake related issue?


  • Moderators

    You can try with MacPorts, probably. But your qmake may still be defaulting to the OS-installed compiler, so you probably would need to modify the mkspecs, or install Qt from MacPorts, too. I'd say it's all doable, but only try if you are really desperate :)


  • Moderators

    QMake only generates the Makefiles, it does not compile the stuff. It probably does it in a different way than your own GCC tries. You need to compare the linker invocations.



  • Ok, got it working. In case anybody runs into the same trouble:

    . First of all I noticed that the current Xcode version (5.0.1) ships only with the 10.8 and 10.9 sdks.

    . I don't know if this qualifies as a qmake bug, but it seems that using QMAKE_CXXFLAGS += -mmacosx-version-min is ignored by qmake. The only way I got to make it work was by directly changing mkspecs and changing QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.9.

    Cheers,
    Ivan


  • Moderators

    Wow, thanks. This indeed might come in useful :D


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.