0

I am trying to install the emzed python package for LC/MS analysis. This package is dependent on PyQt4 and PyQWT. I have installed everything but have not been able to build PyQWT. I have jumped through so many errors and I have been stuck on this linking error for a while.

I have tried modifying the makefile (Qwt_version_info.mak) to pass it include directories. I do not know how to specify the appropriate linking library to get his too compile (the QTextStream, etc)

$  make -f qwt_version_info.mak 
Are we linking yet?1
Are we linking yet?2
Are we linking yet?3
Are we linking yet?4
Are we linking yet?5
g++ -v -headerpad_max_install_names -o qwt_version_info.app/Contents/MacOS/qwt_version_info qwt_version_info.o      
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
 "/Library/Developer/CommandLineTools/usr/bin/ld" -demangle -lto_library /Library/Developer/CommandLineTools/usr/lib/libLTO.dylib -dynamic -arch x86_64 -headerpad_max_install_names -macosx_version_min 10.9.0 -o qwt_version_info.app/Contents/MacOS/qwt_version_info qwt_version_info.o -lc++ -lSystem /Library/Developer/CommandLineTools/usr/lib/clang/10.0.1/lib/darwin/libclang_rt.osx.a
Undefined symbols for architecture x86_64:
  "hex(QTextStream&)", referenced from:
      _main in qwt_version_info.o
  "QArrayData::deallocate(QArrayData*, unsigned long, unsigned long)", referenced from:
      QTypedArrayData<unsigned short>::deallocate(QArrayData*) in qwt_version_info.o
  "QTextStream::QTextStream(QIODevice*)", referenced from:
      _main in qwt_version_info.o
  "QTextStream::~QTextStream()", referenced from:
      _main in qwt_version_info.o
  "QTextStream::operator<<(char const*)", referenced from:
      _main in qwt_version_info.o
  "QTextStream::operator<<(int)", referenced from:
      _main in qwt_version_info.o
  "QFile::open(QFlags<QIODevice::OpenModeFlag>)", referenced from:
      _main in qwt_version_info.o
  "QFile::QFile(QString const&)", referenced from:
      _main in qwt_version_info.o
  "QFile::~QFile()", referenced from:
      _main in qwt_version_info.o
  "QString::fromAscii_helper(char const*, int)", referenced from:
      QString::QString(char const*) in qwt_version_info.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: *** [qwt_version_info.app/Contents/MacOS/qwt_version_info] Error 1

This is the makefile.

1591 $  cat qwt_version_info.mak 
#############################################################################
# Makefile for building: qwt_version_info.app/Contents/MacOS/qwt_version_info
# Generated by qmake (2.01a) (Qt 4.8.7) on: Tue Aug 13 11:31:21 2019
# Project:  qwt_version_info.pro
# Template: app
# Command: /usr/local/opt/qt@4/bin/qmake -spec /usr/local/etc/qt4/mkspecs/macx-g++ -o qwt_version_info.mak qwt_version_info.pro
#############################################################################

####### Compiler, tools and options

CC            = gcc
CXX           = g++
DEFINES       = 
CFLAGS        = -pipe $(DEFINES)
CXXFLAGS      = -pipe -std=c++11 $(DEFINES)
INCPATH       = -I/usr/local/etc/qt4/mkspecs/macx-g++ -I. -I../qwt-5.2/src -I/usr/local/Cellar/qt@4/4.8.7_5/lib/QtCore.framework/Versions/4/Headers -I/usr/local/Cellar/sip/4.19.8_12/include -I/Users/Danny/.virtualenvs/emzed2.7/lib/python2.7/site-packages/numpy/core/include
LINK          = g++
LFLAGS        = -headerpad_max_install_names
LIBS          = $(SUBLIBS)    
AR            = ar cq
RANLIB        = ranlib -s
QMAKE         = /usr/local/opt/qt@4/bin/qmake
TAR           = tar -cf
COMPRESS      = gzip -9f
COPY          = cp -f
SED           = sed
COPY_FILE     = cp -f
COPY_DIR      = cp -f -R
STRIP         = 
INSTALL_FILE  = $(COPY_FILE)
INSTALL_DIR   = $(COPY_DIR)
INSTALL_PROGRAM = $(COPY_FILE)
DEL_FILE      = rm -f
SYMLINK       = ln -f -s
DEL_DIR       = rmdir
MOVE          = mv -f
CHK_DIR_EXISTS= test -d
MKDIR         = mkdir -p
export MACOSX_DEPLOYMENT_TARGET = 10.9

####### Output directory

OBJECTS_DIR   = ./

####### Files

SOURCES       = qwt_version_info.cpp 
OBJECTS       = qwt_version_info.o
DIST          = /usr/local/Cellar/qt@4/4.8.7_5/etc/qt4/mkspecs/common/unix.conf \
        /usr/local/Cellar/qt@4/4.8.7_5/etc/qt4/mkspecs/common/mac.conf \
        /usr/local/Cellar/qt@4/4.8.7_5/etc/qt4/mkspecs/common/gcc-base.conf \
        /usr/local/Cellar/qt@4/4.8.7_5/etc/qt4/mkspecs/common/gcc-base-macx.conf \
        /usr/local/Cellar/qt@4/4.8.7_5/etc/qt4/mkspecs/common/g++-base.conf \
        /usr/local/Cellar/qt@4/4.8.7_5/etc/qt4/mkspecs/common/g++-macx.conf \
        qwt_version_info.pro
QMAKE_TARGET  = qwt_version_info
DESTDIR       = 
TARGET        = qwt_version_info.app/Contents/MacOS/qwt_version_info

first: all
####### Implicit rules

.SUFFIXES: .o .c .cpp .cc .cxx .C

.cpp.o:
    $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"

.cc.o:
    $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"

.cxx.o:
    $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"

.C.o:
    $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"

.c.o:
    $(CC) -c $(CFLAGS) $(INCPATH) -o "$@" "$<"

####### Build rules

all: qwt_version_info.mak qwt_version_info.app/Contents/PkgInfo qwt_version_info.app/Contents/Resources/empty.lproj $(TARGET)

$(TARGET):  $(OBJECTS)  
    @$(CHK_DIR_EXISTS) qwt_version_info.app/Contents/MacOS/ || $(MKDIR) qwt_version_info.app/Contents/MacOS/ 
    $(LINK) -v $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS)

$(info Are we linking yet?1)

qwt_version_info.mak: qwt_version_info.pro  /usr/local/etc/qt4/mkspecs/macx-g++/qmake.conf /usr/local/Cellar/qt@4/4.8.7_5/etc/qt4/mkspecs/common/unix.conf \
        /usr/local/etc/qt4/mkspecs/common/mac.conf \
        /usr/local/Cellar/qt@4/4.8.7_5/etc/qt4/mkspecs/common/gcc-base.conf \
        /usr/local/etc/qt4/mkspecs/common/gcc-base-macx.conf \
        /usr/local/Cellar/qt@4/4.8.7_5/etc/qt4/mkspecs/common/g++-base.conf \
        /usr/local/etc/qt4/mkspecs/common/g++-macx.conf
    $(QMAKE) -spec /usr/local/etc/qt4/mkspecs/macx-g++ -o qwt_version_info.mak qwt_version_info.pro
/usr/local/Cellar/qt@4/4.8.7_5/etc/qt4/mkspecs/common/unix.conf:
/usr/local/etc/qt4/mkspecs/common/mac.conf:
/usr/local/Cellar/qt@4/4.8.7_5/etc/qt4/mkspecs/common/gcc-base.conf:
/usr/local/etc/qt4/mkspecs/common/gcc-base-macx.conf:
/usr/local/Cellar/qt@4/4.8.7_5/etc/qt4/mkspecs/common/g++-base.conf:
/usr/local/etc/qt4/mkspecs/common/g++-macx.conf:
qmake:  FORCE
    @$(QMAKE) -spec /usr/local/etc/qt4/mkspecs/macx-g++ -o qwt_version_info.mak qwt_version_info.pro


$(info Are we linking yet?2)

qwt_version_info.app/Contents/PkgInfo: 
    @$(CHK_DIR_EXISTS) qwt_version_info.app/Contents || $(MKDIR) qwt_version_info.app/Contents 
    @$(DEL_FILE) qwt_version_info.app/Contents/PkgInfo
    @echo "APPL????" >qwt_version_info.app/Contents/PkgInfo
qwt_version_info.app/Contents/Resources/empty.lproj: 
    @$(CHK_DIR_EXISTS) qwt_version_info.app/Contents/Resources || $(MKDIR) qwt_version_info.app/Contents/Resources 
    @touch qwt_version_info.app/Contents/Resources/empty.lproj

: 
    @$(DEL_FILE) 
    @sed -e "s,@SHORT_VERSION@,1.0,g" -e "s,@TYPEINFO@,????,g" -e "s,@ICON@,,g" -e "s,@EXECUTABLE@,qwt_version_info,g" -e "s,@TYPEINFO@,????,g"  >
dist: 
    @$(CHK_DIR_EXISTS) .tmp/qwt_version_info1.0.0 || $(MKDIR) .tmp/qwt_version_info1.0.0 
    $(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/qwt_version_info1.0.0/ && (cd `dirname .tmp/qwt_version_info1.0.0` && $(TAR) qwt_version_info1.0.0.tar qwt_version_info1.0.0 && $(COMPRESS) qwt_version_info1.0.0.tar) && $(MOVE) `dirname .tmp/qwt_version_info1.0.0`/qwt_version_info1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/qwt_version_info1.0.0

$(info Are we linking yet?3)

clean:compiler_clean 
    -$(DEL_FILE) $(OBJECTS)
    -$(DEL_FILE) *~ core *.core


####### Sub-libraries

distclean: clean
    -$(DEL_FILE) -r qwt_version_info.app
    -$(DEL_FILE) qwt_version_info.mak


compiler_clean: 

####### Compile

$(info Are we linking yet?4)
qwt_version_info.o: qwt_version_info.cpp 
    $(CXX) -c $(CXXFLAGS) $(INCPATH) -o qwt_version_info.o qwt_version_info.cpp

$(info Are we linking yet?5)
####### Install

install:   FORCE

uninstall:   FORCE

FORCE:

Any help is much appreciated.

Update: under /usr/local/Cellar/qt@4/4.8.7_5/lib/QtCore.framework I found a binary called QtCore. I renamed it libQtCore.so and when I linked it with this binary this is my new error message:

$ g++ -v -headerpad_max_install_names -o qwt_version_info.app/Contents/MacOS/qwt_version_info qwt_version_info.o  -L/usr/local/Cellar/qt@4/4.8.7_5/lib/QtCore.framework -lQtCore

 "/Library/Developer/CommandLineTools/usr/bin/ld" -demangle -lto_library /Library/Developer/CommandLineTools/usr/lib/libLTO.dylib -dynamic -arch x86_64 -headerpad_max_install_names -macosx_version_min 10.14.0 -o qwt_version_info.app/Contents/MacOS/qwt_version_info -L/usr/local/Cellar/qt@4/4.8.7_5/lib/QtCore.framework qwt_version_info.o -lQtCore -lc++ -lSystem /Library/Developer/CommandLineTools/usr/lib/clang/10.0.1/lib/darwin/libclang_rt.osx.a
Undefined symbols for architecture x86_64:
  "QArrayData::deallocate(QArrayData*, unsigned long, unsigned long)", referenced from:
      QTypedArrayData<unsigned short>::deallocate(QArrayData*) in qwt_version_info.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Now I just need help finding where the library binary for theQArrayData symbols is found. I have not been able to find anything helpful on google.

Danny Diaz
  • 375
  • 1
  • 4
  • 12
  • Is this all of the output? `$(CXX) -c $(CXXFLAGS) $(INCPATH) -o qwt_version_info.o qwt_version_info.cpp` looks like it expands to: `g++ -v -headerpad_max_install_names -o qwt_version_info.app/Contents/MacOS/qwt_version_info qwt_version_info.o` but looking at the variables set in the top of the makefile I would expect it to be different. Also I don't see *any* of your `are we linking yet` info/debug lines - these would be printed when the makefile gets parsed (makefile first parses the file, printing any info lines, and then runs the rules). Can you provide more info on what is going on here? – code_fodder Aug 15 '19 at 06:12
  • I placed all of "are we linking" in after running the makefile.They all print at the very top of the output. I did not know that make first parses the file and then runs the rules. Now it makes a lot of sense why they all print at the top of the output. I have edited the post to reflect exactly the output I get when I run the makefile posted above. – Danny Diaz Aug 15 '19 at 14:24
  • Ah I see now. So the line we see at the start of your trace just after all the `Are we linking yet...` is this line: `$(LINK) -v $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS)`. Which kind of implies that $(OBJECTS) is empty or the object is already built (the file `qwt_version_info.o` exists already). Next there are no link flags, set I think this is what you want to add to? which libraries do you need to link to - because we can add them to `$(LINK)` or `$(SUBLIBS)` which is used to make up `$(LINK)` – code_fodder Aug 15 '19 at 16:09
  • Im pretty sure what is missing is some library in Qt4 I just don't know how to find the right one or how to search for the symbols that are missing. Im still trying to wrap my head around linking. – Danny Diaz Aug 15 '19 at 21:43

1 Answers1

1

This may not be the complete answer yet, but its too large to put into a comment.

So lets focus on the single line here:

g++ -v -headerpad_max_install_names -o qwt_version_info.app/Contents/MacOS/qwt_version_info qwt_version_info.o      

Now you are getting undefined references to things like: QByteArray and QTextStream. These all live in the library (IIRC) qtxcore or qtxcored (debug) where the x is the qt version. So I imagine for you it is libqt4core.so or libqt4cored.so.

So we need two bits of information, we need to know where this is install and which type (debug or release) you have.

The libraries are usually somewhere in /usr/lib/... and you will find libqt5core[d].so somewhere in there (IIRC /usr/lib/qt4/ - but that is a bit of a guess).

Lets assume you have the debug libraries - but both may well be there, then we can link that library in to your linker line:

Note: just run this line manually to start with and then we will add it to your makefile.

g++ -v -headerpad_max_install_names -o qwt_version_info.app/Contents/MacOS/qwt_version_info qwt_version_info.o -L/usr/lib/qt4 -lqt4cored

Here you can see that we have added a path to where the library is (-L...) and the library itself (-l...).

Now this will enable your linker to find QByteArray etc... but then you will probably have a few more things you are missing depending what bits of Qt you are using. Here is a list of other possible libs you may need to add:

libQt4Gui.so
libQt4Core.so
libQt4DBus.so
libQt4PrintSupport.so
libQt4Widgets.so
libQt4Network.so
libQt4XcbQpa.so
libQt4Svg.so
libicui18n.so
libicuuc.so
libicudata.so

Note: I got this list from another question I was answering a long while back so it may need editing and you may or may-not want to use the debug version (e.g. libQt5Gui.so -> libQt5Guid.so). The list is in no particular order.

So you could end up with:

g++ -v -headerpad_max_install_names -o qwt_version_info.app/Contents/MacOS/qwt_version_info qwt_version_info.o -L/usr/lib/qt4 -lqt4cored -licudata -licuuc ... etc...

Get this line working and then we can see about adding it to your makefile - adding the libs/paths is trivial.

code_fodder
  • 15,263
  • 17
  • 90
  • 167
  • So i can't seem to find libQt4Core.so on my computer. I ran ```find /usr/ -name "libQt4Core.so" -print``` and I got nothing back. I was able to find a QtCore.so file under /usr/local/Cellar/pyqt@4/4.12.1_1/lib/python2.7/site-packages/PyQt4. When I pass this directory with the -L flag and -lQtCore I get a linking error. ```ld: library not found for -lQtCore``` This is the command I ran: ```g++ -v -headerpad_max_install_names -o qwt_version_info.app/Contents/MacOS/qwt_version_info qwt_version_info.o -L/usr/local/Cellar/pyqt@4/4.12.1_1/lib/python2.7/site-packages/PyQt4 -lQtCore``` – Danny Diaz Aug 16 '19 at 16:53
  • I made a copy of QtCore.so and named it libQtCore.so and that just returns the same error message I got when I originally posted the question. – Danny Diaz Aug 16 '19 at 16:57
  • Here are all the libraries in the site-packages/PyQt4 directory ```uic __init__.py Qt.so QtCore.so QtDeclarative.so QtDesigner.so QtGui.so QtHelp.so QtMultimedia.so QtNetwork.so QtOpenGL.so QtScript.so QtScriptTools.so QtSql.so QtSvg.so QtTest.so QtWebKit.so QtXml.so QtXmlPatterns.so pyqtconfig.py``` – Danny Diaz Aug 16 '19 at 17:05
  • I updated the initial post with the progress I have made. – Danny Diaz Aug 16 '19 at 17:31
  • Ok hang on - I think you are getting into a bit of a mess, it looks like you are mixing static and shared objects - which you can do, but you have to be careful. Also I don't know exactly what that file is - if it does not start with lib I would be very suspicious of it. It seems more likely that you don't have qt or pyqt installed properly?! - it could be under `/opt`. You can use `-l:QtCore.so` to specify the none-standard library name. Also to mix static and shared libraries you need to use -static and -shared see here for an example:... – code_fodder Aug 16 '19 at 18:53
  • https://stackoverflow.com/questions/5438891/mixing-static-libraries-and-shared-libraries – code_fodder Aug 16 '19 at 18:53
  • My libraries for qt5 are here: `/usr/lib/x86_64-linux-gnu/libQt5Core.so.5`, obviously pyqt4 may have different names – code_fodder Aug 16 '19 at 19:17
  • So I got it to compile! but It still does not show up anywhere in my directory for me to use it when I run make install. What I did was use ```-L/usr/local/Frameworks/QtCore.framework/Versions/Current/ -lQtCore ```. I hardcoded this into the makefile at the appropriate line: ``` $(LINK) -v $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS) -L/usr/local/Frameworks/QtCore.framework/Versions/Current/ -lQtCore```. Now when I run make I just get ```make: Nothing to be done for `install'.``` I can't find the built binary anywhere in my filesystem and I am even more confused on what is going on. – Danny Diaz Aug 17 '19 at 15:33
  • The value of `$(TARGET)` is `qwt_version_info.app/Contents/MacOS/qwt_version_info` so I guess it will be called that. If you want it to be called something else change the variable TARGET. – code_fodder Aug 17 '19 at 15:44
  • I would like to thank you for your help! turns out I don even need this stupid library to build. I ended up just taking one of the directories in the package and symlinking it to PyQt4 and it was able to then pull the source code files to successfully link all the dependencies for emzed! I would have not been able to do this without your help on knowing where to look for stuff in my filesystem! I also learned a lot about linking software and dynamic libraries. – Danny Diaz Aug 17 '19 at 17:47
  • no worries, yeah it can be confusing. if you question is finished/answered feel free to click the tick to other users know the question is answered : ) – code_fodder Aug 17 '19 at 18:04
  • What do you mean click the tick? – Danny Diaz Aug 17 '19 at 19:08
  • there is a little tick to accept an answer it near the up/down vote buttons. it marks the question as answered : ) – code_fodder Aug 17 '19 at 19:19