Building standalone executable on Mac: Linker command error



  • I am trying to get a Qt-based traffic simulator called "mezzo" to work on macOS 10.10.5, Qt 4.8.7, and Xcode 7.2.1. (I've also tried with Qt Creator, which results in the same issues.) This simulator has been originally developed on Windows, where it works flawlessly.

    I can successfully build a library of the traffic simulator, using the following *.proj-file (not showing the header/source files):

    TEMPLATE = lib
    CONFIG += staticlib debug
    TARGET = mezzo_lib
    DEPENDPATH += . src
    INCLUDEPATH += $(QTDIR)/include
    LIBS+=  -L$(QTDIR)/lib -lQtCore -lQtGui
    QT+= core gui
    QMAKE= $(QTDIR)/bin/qmake
    

    I fail to build a standalone version of the traffic simulator with the following *.proj-file (again not showing header/source files):

    TEMPLATE = app
    CONFIG +=  console embed_manifest_exe
    TARGET = mezzo_s
    DEPENDPATH += . ../mezzo_lib/src
    QT -=  gui
    QMAKE= $(QTDIR)/bin/qmake
    

    When trying to build the standalone executable on my system, I get the following error:

    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    

    A screenshot with some more information from Xcode may be found here:

    alt text
    (If picture does not show, please check here: https://goo.gl/photos/vcgZgsP525M7CzLX8 )

    I'd have two questions:
    (i) What could possibly cause this liker command failure and how could I fix it? Note that the error I get is not associated with any source or header file, but with the generated mezzo_s.app executable itself.

    (ii) Can I run the traffic simulator directly from within Xcode without generating an external executable? For instance, using Java on Eclipse, I could either generate a JAR standalone file and run it from the terminal, or run a program directly from within Eclipse by providing the required program arguments. The latter is what I'd like to do here as well. How would I have to change the *.proj-file accordingly? (If I had the external executable, I would launch it with the command "mezzo_s.app myNetwork.txt," with the latter being a parameter file.)

    Thanks a lot to all of you in advance!!



  • Hi, I'm just guessing but those errors look like a c++ stdlib mixup, try inserting
    CXXFLAGS = -stdlib=libc++ in your .pro file.



  • Thank you very much for the answer.

    Following your suggestion, I have modified the *.proj-file as follows:

    TEMPLATE = app
    CXXFLAGS = -stdlib=libc++
    CONFIG +=  console embed_manifest_exe
    TARGET = mezzo_s
    DEPENDPATH += . ../mezzo_lib/src
    QT -=  gui
    DEFINES += _NO_GUI _BUSES
    QMAKE= $(QTDIR)/bin/qmake
    

    However, qmake &&make still yields

    (…)
    "62 warnings generated.
    clang++ -headerpad_max_install_names -arch x86_64 -o mezzo_s.app/Contents/MacOS/mezzo_s busline.o day2day.o eventlist.o grid.o icons.o link.o linktimes.o network.o node.o od.o parameters.o pvm.o q.o Random.o route.o sdfunc.o server.o trafficsignal.o signature.o turning.o vehicle.o vissimcom.o vtypes.o passenger.o od_stops.o pass_route.o main.o   -F/Library/Frameworks -L/Library/Frameworks -framework QtCore 
    Undefined symbols for architecture x86_64:
      "insert(std::map<ODSL, Travel_time, std::less<ODSL>, std::allocator<std::pair<ODSL const, Travel_time> > >&, std::map<ODSL, Travel_time, std::less<ODSL>, std::allocator<std::pair<ODSL const, Travel_time> > >&)", referenced from:
          Network::step(double) in network.o
      "insert(std::map<ODSLL, Travel_time, std::less<ODSLL>, std::allocator<std::pair<ODSLL const, Travel_time> > >&, std::map<ODSLL, Travel_time, std::less<ODSLL>, std::allocator<std::pair<ODSLL const, Travel_time> > >&)", referenced from:
          Network::step(double) in network.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: *** [mezzo_s.app/Contents/MacOS/mezzo_s] Error 1"
    

  • Moderators

    @flurinus Did you run qmake after changing pro file and then completely rebuild your app?



  • @jsulm

    Thanks for the reply. Yes, I've completely rebuilt the projects. I have changed the .pro-file of both mezzo_lib and of mezzo_standalone, and rebuilt both projects from scratch. The error is still the same.



  • Aha, didn't see before that you're using Qt4.8.7, I don't have it but perhaps due to its age it requires the old c++ stdlib, just a guess (again :-) but you could try changing that line in your .pro file instead to:
    CXXFLAGS = -stdlib=libstdc++



  • Thank you again :-). I've tried this one as well. The result is still the same. Any further input is more than welcome ;-).

    Following the suggestion of SGaist, I've also put a copy of the code on GitHub. The problem seems to be rather Mac-specific, so it may well be that on other systems building the project does not produce any errors.

    I'd be more than happy to receive any further suggestions/comments. Thanks a lot in advance!!



  • BTW, is it possible for you to upgrade your project from Qt 4.8.7 to 5.7?



  • Thank you for the suggestion to upgrade to Qt 5.7. I have done so in the meantime. Since the simulator has only a rather simple GUI, there was not a single incompatibility when migrating from Qt 4.x to Qt 5.x. Strangely, however, the linker command error still prevails. And I did try including CXXFLAGS = -stdlib=libc++. I also cleaned the project before trying to build it.

    My configuration is now as follows: Clang (x86 64 bit), Qt 5.7.0 clang 64 bit, Qt Creator 4.1/Xcode 7.2.1, macOS 10.10.5.

    Any further hints are most highly appreciated! :-)



  • Nice! Also could you update the copy of the project on GitHub? (Or perhaps there are no changes)
    If it's a 5.7 project on Github then helping you debug those errors is easier :-)



  • Thanks a lot!! :)

    No modifications in the C++ code were necessary to make it compatible with Qt 5. However, I've cleaned up the *.pro-file, leaving away some lines that do not seem to be useful (they may be useful on Windows or with earlier versions of Qt). The accordingly updated version is on GitHub.

    One thing I've noticed is that when compiling the corresponding library (see folder mezzo_lib in the Git repository or in this thread), leaving away the line CONFIG += staticlib produces the same linker command error. Since this staticlib option only applies to libraries, adding it here does not solve the problem (it may however give some clue where the error comes from, I don't know).

    Thanks a lot in advance!!



  • Hi, interesting, if I comment out line 7537 and 7542 in network.cpp the project builds fine:
    2linest

    Easiest is probably to try to rewrite those 2 lines, I'll get back...



  • Ah, templates again (my favorite not :-(
    Anyway in file day2day.h someone edited line 107: hfile
    to remove the templates for the two insert() functions that the lines 7537 and 7542 in network.cpp use.

    So one way out of this is to add the specializations as two normal functions after the template in day2day.cpp:
    cppfile

    Then the project builds fine again (both on the Mac and on WIndows).

    Also note that this was a bit of a red herring re. clang, because those 2 link errors occur on Windows as well:

    network.obj : error LNK2019: unresolved external symbol "float __cdecl insert(class std::map<struct ODSL,struct Travel_time,struct std::less<struct ODSL>,class std::allocator<struct std::pair<struct ODSL const ,struct Travel_time> > > &,class std::map<struct ODSL,struct Travel_time,struct std::less<struct ODSL>,class std::allocator<struct std::pair<struct ODSL const ,struct Travel_time> > > &)" (?insert@@YAMAAV?$map@UODSL@@UTravel_time@@U?$less@UODSL@@@std@@V?$allocator@U?$pair@$$CBUODSL@@UTravel_time@@@std@@@4@@std@@0@Z) referenced in function "public: double __thiscall Network::step(double)" (?step@Network@@QAENN@Z)
    network.obj : error LNK2019: unresolved external symbol "float __cdecl insert(class std::map<struct ODSLL,struct Travel_time,struct std::less<struct ODSLL>,class std::allocator<struct std::pair<struct ODSLL const ,struct Travel_time> > > &,class std::map<struct ODSLL,struct Travel_time,struct std::less<struct ODSLL>,class std::allocator<struct std::pair<struct ODSLL const ,struct Travel_time> > > &)" (?insert@@YAMAAV?$map@UODSLL@@UTravel_time@@U?$less@UODSLL@@@std@@V?$allocator@U?$pair@$$CBUODSLL@@UTravel_time@@@std@@@4@@std@@0@Z) referenced in function "public: double __thiscall Network::step(double)" (?step@Network@@QAENN@Z)
    release\mezzo_s.exe : fatal error LNK1120: 2 unresolved externals
    

    (Adding those 2 functions to day2day.cpp solves it for Windows also.)

    So, in summary, it seems you got stuck with the project in the middle of a revision :-)


  • Lifetime Qt Champion

    Besides what @hskoglund found, there's also

    friend float operator/ (const Travel_time& lhs, const Travel_time& rhs);

    missing in the Travel_time struct declaration.

    On a side note, I've built the project removing the two specialized method version since they where not implemented in the first place.



  • Dear @hskoglund and @SGaist,

    Thank you very much for this great support. It has helped me so much. I had further issues with getting the transit simulator work on an actual test network, but finally succeeded yesterday evening also due to help of other colleagues. It's a good thing to know that the code now runs, which will greatly simplify my further tasks :).

    I am still a bit puzzled by the relatively unspecific kind of error (linker command error) that we were facing here, and I'll definitely keep this in mind when debugging C++ code in the future. Also, it's a bit mysterious to me how you proceeded to figure out where the error comes from in the first place, but I hope that someday I'll understand :-).

    Thanks again and best wishes, flurinus


Log in to reply
 

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