Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Qt make with arm-linux-gnueabihf cross compiler undefined reference to delete operator on libqtharfbuzz.a compilation



  • Hello! I've been trying to build Qt from source lately using the arm-linux-gnueabihf cross compiler. My target device is iMX.6.

    After some time I've managed to successfuly configure the make file with the following settings:

    qtbase/mkspecs/devices/linux-imx6-g++/qmake.conf:

    include(../common/linux_device_pre.conf)
    
    #OPENGL
    
    QMAKE_INCDIR_EGL += /home/*name*/sysroot/usr/include
    QMAKE_LIBDIR_EGL += /home/*name*/sysroot/usr/lib
    
    QMAKE_INCDIR_OPENGL_ES2 += /home/*name*/sysroot/usr/include
    QMAKE_LIBDIR_OPENGL_ES2 +=  /home/*name*/sysroot/usr/lib
    
    QMAKE_INCDIR_OPENVG += /home/*name*/sysroot/usr/include
    QMAKE_LIBDIR_OPENVG +=  /home/*name*/sysroot/usr/lib
    
    QMAKE_LIBS_EGL += -EGL
    QMAKE_LIBS_OPENGL_ES2 += -lGLESv2 -lEGL -lGAL
    QMAKE_LIBS_OPENVG += -lOpenVG - lEGL -lGAL
    
    IMX6_CFLAGS = -march=armv7-a -mfpu-neon -DLINUX=1 -DEGL_API_FB=1 -mfloat-abi=softfp
    QMAKE_CFLAGS += $$IMX6_CFLAGS
    QMAKE_CXXFLAGS += $$IMX6_CFLAGS -lstdc++ -std=c++11
    
    DISTRO_OPTS += hard-float
    
    # Prereferred eglfs backend
    EGLFS_DEVICE_INTEGRATION = eglfs_viv
    
    include(../common/linux_arm_device_post.conf)
    
    load(qt_config)
    

    And the following .configure command:

    ./confugure -opensource -confirm-license -prefix /home/name/QtARM -device linux-imx6-g++ -device-option CROSS_COMPILE=/home/name/x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf- -sysroot /home/name/sysroot --sysroot=/home/name/x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc -no-opengl -opengl es2 -nomake tests -nomake examples -no-use-gold-linker -no-pch

    This configures the make file. Then I run 'make' command and everything seems ok untill It gets to this "libqtharfbuzz.a" library which just doesn't compile for me. The only error that 'make' gives me is repeating "undefined reference to operator delete":

    ...
    .obj/qwindow.o: In function 'QWindow::~QWindow()':
    qwindow.cpp:(.text+0x4a9c): undefined reference to 'operator delete(void*, unsigned int)'
    .obj/qwindow.o: In function 'non-virtual thunk to QWindow::~QWindow()':
    qwindow.cpp:(.text+0x4ab4): undefined reference to 'operator delete(void*, unsigned int)'
    ...

    Has anyone been coming across a similar problem? I'm clueless as to what else I can do at this point.



  • Sorry for keeping you waiting. My original problem is solved. The solution was to just keep downloading all of the dependent libraries to my sysroot location and then checkin with qt's ./configure whether they get recognized.

    Another thing that made me stuck for a couple of days was the error that kept comming up during make. Something about missing libstd.h. The solution to that was changing the ../qtbase/mkspecs/common/gcc-base.conf file. Specifically changing the QMAKE_CFLAGS_ISYSTEM variable to -I (capital i).

    After that I've managed to complete my Qt build for ARMv7.

    The app that I've build still doesn't run on my board though (it complains about old libc and listdc++ and I can't update these system libs on my board because there is no internet access and I couldn't re-flash the kernel with mfgtools/imx_usb_loader/uuu and some other utilities because my board is custom and none of the instructions on the internet are working for it lol) so I'm trying to build a static Qt version just for this board to make my app into bigger executable that will hopefully not depend on these system libs that I cannot update or preload dynamically. But that's another story, not concerning the original problem discussed in this thread.



  • @Cracky said in Qt make with arm-linux-gnueabihf cross compiler undefined reference to delete operator on libqtharfbuzz.a compilation:

    what else I can do at this point.

    Could you please check file config.log (the results of ./configure command) and look for an entry like:

    test config.qtbase_gui.libraries.harfbuzz succeeded
    

    That means the requirements of the harfbuzz feature are Ok.
    If not, check the previous lines to understand what happened, very likely missing harfbuzz files in your RPi device that you need to rsync to sysroot folder in your host



  • @Pablo-J-Rogina Hello! Thank you for the reply!

    You're quite right. I've investigated my config.log the harfbuzz test has indeed failed since I don't have a harfbuzz library on my target device (in my sysroot). I've downloaded this library package from https://archlinuxarm.org/packages/arm/harfbuzz , copies the archive's contents in my corresponding sysroot folders (/sysroot/usr/bin, /sysroot/usr/include, /sysroot/usr/lib, /sysroot/usr/share). Ran the ./configure again and got the harfbuzz test failed again:

    ...
    looking for library harfbuzz
    Trying source 0 (type inline) of library harfbuzz ...
    None of [libharfbuzz.so libharfbuzz.a] found in [] and global paths.
     => source produced no result.
    test config.qtbase_gui.libraries.harfbuzz FAILED
    ...
    

    Prior to this I've changed my ./configure script slightly so that I don't overwrite my sysroot path:

    ./confugure -opensource -confirm-license -prefix /home/name/QtARM -device linux-imx6-g++ -device-option CROSS_COMPILE=/home/name/x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf- -sysroot /home/name/sysroot -no-opengl -opengl es2 -nomake tests -nomake examples -no-use-gold-linker -no-pch
    

    I've mixed the contents of x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc with my sysroot copied directly from iMX6 target device because things like crt1.o and crti.o were missing from the IMX's sysroot, so I couldn't sussessfully configure. Not quite sure if I was supposed to do it this way, but now I have one single sysroot with everything I need. However, when I add other packages to that sysroot (like harfbuzz), the qt ./configure sees the package files (.pc) but still can't find .so files.

    My libharfbuzz.so is located under ~/sysroot/usr/lib/libharfbuzz.so



  • @Cracky I think know why. The Qt configure tool detects my pkg-config program, finds the package itself, but then it searches for libs and includes in so-called 'Global lib/inc dirs' that in my case do not include the folders from sysroot. Now trying to figure out why it detects wrong folder and how to change it. From what I've managed to find, Qt configure seems to use QMAKE_DEFAULT_LIBSDIRS/INCLUDES variables, but I can't find where exactly they get declared and where I can re-direct these to the folders I need.



  • @Cracky said in Qt make with arm-linux-gnueabihf cross compiler undefined reference to delete operator on libqtharfbuzz.a compilation:

    I've mixed the contents of x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc with my sysroot copied directly from iMX6 target device ... Not quite sure if I was supposed to do it this way,

    As a rule of thumb, when cross-compiling the idea is that you install all the required libraries in your target device, and then copy (mostly with rsync command) the libraries/headers from location in the the target device (usually /usr/lib & /usr/include) to the sysroot folder in your host. That folder mimic the folder structure from your device (i.e. /path/to/sysroot/usr/include, /path/to/sysroot/usr/lib)

    That said, I know that for some devices is not easy to get all the required libraries into it (because of old/unusual Linux distro, etc.)

    iMX6 target device

    Could you provide more details about that device?
    What OS are you using?
    Is there an SDK provided by board manufacture?



  • Ok, here is what I've done:

    Like I said, I've discovered that when qt configure is looking for libraries using pkg-config, it searches for libs/includes in the "Global lib/inc dirs" paths which you can see in config.log file. For some reason, on my machine, these paths were set to a completely different compiler and ofcourse the .so files could not be found. After digging into Qt src code I've found that these global lib/inc dir paths are storred in "QMAKE_DEFAULT_LIBDIRS" and "QMAKE_DEFAULT_INCDIRS" variables. To change these, I had to change the code in ../qtbase/mkspecs/features/toolchain.prf:

    ...
    } else {
      //QMAKE_DEFAULT_INCDIRS = $$eval($${target_prefix}.INCDIRS)  //this is Qt's code that
      //QMAKE_DEFAULT_LIBDIRS = $$eval($${target_prefix}.LIBDIRS)  //detected wrong paths
      //My code start:
      QMAKE_DEFAULT_INCDIRS = /home/name/sysroot/usr/include  
      QMAKE_DEFAULT_LIBDIRS = /home/name/sysroot/usr/lib
      //My code finish
      QMAKE_DEFAULT_PATH = $$eval($${target_prefix}.PATH)
    }
    ...
    

    There is probably a nicer way of changing these path variables than just simply hardcoding them but several hours of googling have led me to nowhere and this solution I had to figure out myself.

    After I've changed these paths, qt configure has found .so files where I wanted it to be found. Generally, from this point I was able to download and add required libraries to my sysroot from the archlinuxarm.org and it started to go somewhere.

    After all dependent libraries were added, I was still left with compiler errors that looked like:

    undefined reference to  'someStupidFunction@GLIBC_some.version'
    

    I turns out that the latest Linaro's arm-linux-gnueabihf toolchain is using glibc 2.25, so any library that depends on later versions of glibc library will not compile. So, I had to download another toolchain from arm.developer.com website that is using glibc 2.30 (latest version at the moment of writing this is 2.31).

    After mixing the contents of my sysroot with my new toolchain's /libc contents and changing my ./configure script I ran the configure once again and oh my god harfbuzz test has passed.

    I haven't tried to run make yet though. Instead I'm planning to check other failed tests during configure to make sure that when I run make it doesn't just fail after 3-4 hours because some random library could not compile.

    Will keep you informed on how it goes.



  • Sorry for keeping you waiting. My original problem is solved. The solution was to just keep downloading all of the dependent libraries to my sysroot location and then checkin with qt's ./configure whether they get recognized.

    Another thing that made me stuck for a couple of days was the error that kept comming up during make. Something about missing libstd.h. The solution to that was changing the ../qtbase/mkspecs/common/gcc-base.conf file. Specifically changing the QMAKE_CFLAGS_ISYSTEM variable to -I (capital i).

    After that I've managed to complete my Qt build for ARMv7.

    The app that I've build still doesn't run on my board though (it complains about old libc and listdc++ and I can't update these system libs on my board because there is no internet access and I couldn't re-flash the kernel with mfgtools/imx_usb_loader/uuu and some other utilities because my board is custom and none of the instructions on the internet are working for it lol) so I'm trying to build a static Qt version just for this board to make my app into bigger executable that will hopefully not depend on these system libs that I cannot update or preload dynamically. But that's another story, not concerning the original problem discussed in this thread.



  • @Cracky said in Qt make with arm-linux-gnueabihf cross compiler undefined reference to delete operator on libqtharfbuzz.a compilation:

    I've managed to complete my Qt build for ARMv7.

    great! do you consider your issue solved? If so, please don't forget to mark your post as such


Log in to reply