Qt 4.8 Cross Compile for Embedded Linux using Linaro Toolchain from Windows

10,659

- Hi, phil999,
Cortex-A Series Programmer’s Guide Version: 2.0
at http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0013a/index.html

From the document, it is known that
-mfpu=vfp specifies that the target has VFP hardware. (As does specifying the option -mfpu=neon.)
So, according to your C_FLAGS, option "-mfpu=vfp" equates with option"-mfpu=neon", the difference in Linaro may lie between option "-mfloat-abi=softfp" and option "-mfloat-abi=hard".

From the errors provided,

This error happens after many complaints like: *.so uses VFP register arguments, *obj does not


it seems that lib files are compiled with "-mfloat-abi=hard", which is recognized by "uses VFP register arguments".

'Cause if option "-mfloat-abi=softfp" is used for compiling lib files, floating-point arguments will be passed in R0-R3 and in stack space;
Option "-mfloat-abi=hard" must be spicified, once passing floating-point arguments in VFP or NEON floating-point registers.

So, in order to link with those lib files compiled with "-mfloat-abi=hard", you should also compile QT with "-mfloat-abi=hard", or, there will be some similar complaints as you encountered.

Besides, from the readme in gcc-linaro-arm-linux-gnueabihf-2012.06-20120625_win32\gcc-linaro-arm-linux-gnueabihf-2012.06-20120625_win32\share\doc\gcc-linaro-arm-linux-gnueabihf

Some points in readme are as follows

Target compatibility


The arm-linux-gnueabihf version targets the Linaro Evaluation Build 12.05 flavour of Ubuntu 12.04 "Precise Pangolin". The default configuration is:

  • Runs on all Cortex-A profile devices
  • Tuned for the Cortex-A9
  • Thumb-2
  • 'hard float' calling convention
  • Uses the VFPv3-D16 FPU
  • Multiarch and multilib enabled
  • EGLIBC 2.15
  • A GCC 4.7 series libgcc and libstdc++

To use softfp or hard

Two points:
1. Using float-abi with "softfp", it is backward compatibility with older softfp ABI codes.
2. with "-mfloat-abi=hard", it is more efficient, but is not backward compatibility with softfp abi codes.

More details will be found in "18.2 VFP support in GCC" and "15.1.1 VFP and NEON register usage" in Cortex-A Series Programmer’s Guide Version: 2.0 listed at the beginning.

Thanks.

Share:
10,659
PhilBot
Author by

PhilBot

The ship stays where it is and the engines move the universe around it.

Updated on June 29, 2022

Comments

  • PhilBot
    PhilBot almost 2 years

    I am trying to use the 2012.06 version of the Linaro Toolchain Windows Binary ( https://launchpad.net/linaro-toolchain-binaries/trunk/ ) to cross-compile the Qt 4.8 source to target an embedded Linux ARM Cortex-8 board. I was able to do this with the CodeSourcery toolchain mentioned in this post --> http://c2143.blogspot.com/?view=classic. But the target board software was built with the Linaro toolchain and so I am working towards that end.

    I have patched the mkspec mentioned in the post above to look like this:

    #
    # qmake configuration for building with arm-none-linux-gnueabi-g++
    #
    include(../common/unix.conf)
    include(../common/gcc-base-unix.conf)
    include(../common/g++-unix.conf)
    include(../common/qws.conf)
    
    MAKEFILE_GENERATOR      = MINGW
    CONFIG                 += no_import_libs no_generated_target_info
    # modifications to g++.conf
    QMAKE_CC                = arm-linux-gnueabihf-gcc
    QMAKE_CXX               = arm-linux-gnueabihf-g++
    QMAKE_LINK              = arm-linux-gnueabihf-g++
    QMAKE_LINK_SHLIB        = arm-linux-gnueabihf-g++
    QMAKE_LIB               = arm-linux-gnueabihf-ar
    QMAKE_AR                = arm-linux-gnueabihf-ar cqs
    QMAKE_OBJCOPY           = arm-linux-gnueabihf-objcopy
    QMAKE_STRIP             = arm-linux-gnueabihf-strip
    QMAKE_RUN_CC            = $(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src
    QMAKE_RUN_CC_IMP        = $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
    QMAKE_RUN_CXX           = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src
    QMAKE_RUN_CXX_IMP       = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
    QMAKE_INCDIR            =
    QMAKE_INCDIR_QT         = $$[QT_INSTALL_HEADERS]
    QMAKE_LIBDIR_QT         = $$[QT_INSTALL_LIBS]
    QMAKE_MOC               = $$[QT_INSTALL_BINS]\\moc.exe
    QMAKE_UIC               = $$[QT_INSTALL_BINS]\\uic.exe
    QMAKE_IDC               = $$[QT_INSTALL_BINS]\\idc.exe
    QMAKE_COPY              = copy /y
    QMAKE_COPY_DIR          = xcopy /s /q /y /i
    QMAKE_MOVE              = move
    QMAKE_DEL_FILE          = del
    QMAKE_MKDIR             = mkdir
    QMAKE_DEL_DIR           = rmdir
    QMAKE_CHK_DIR_EXISTS    = if not exist
    QMAKE_IDL               = midl
    QMAKE_ZIP               = zip -r -9
    CODESOURCERY_ARM_CFLAGS = -march=armv7-a -mtune=cortex-a8 -mthumb -mfpu=vfp -mfloat-abi=softfp -Wa,-mimplicit-it=thumb -marm -mthumb-interwork
    #modifications to gcc-base.conf
    QMAKE_CFLAGS           += $$CODESOURCERY_ARM_CFLAGS
    QMAKE_CXXFLAGS         += $$CODESOURCERY_ARM_CFLAGS
    QMAKE_LIBS             += -lrt -lpthread -ldl
    QMAKE_LFLAGS           += $${QMAKE_LFLAGS_RPATH}$$[QT_INSTALL_LIBS]
    !isEmpty(TARGET_QTDIR) {
        QMAKE_LFLAGS       += $${QMAKE_LFLAGS_RPATH}$${TARGET_QTDIR}/lib
    }
    !isEmpty(TARGET_SYSROOT) {
        QMAKE_LFLAGS       += $${QMAKE_LFLAGS_RPATH}$${TARGET_SYSROOT}/lib:$${TARGET_SYSROOT}/usr/lib
        QMAKE_LFLAGS       += -Wl,--dynamic-linker=$${TARGET_SYSROOT}/lib/ld-linux.so.3
    }
    load(qt_config)
    

    When I run mingw32-make on the top level Makefile in order to produce the Qt libraries for the ARM board it compiles for a while but inevitably errors with:

    collect2.exe: error: ld returned 1 exit status
    mingw32-make[1]: *** [..\..\lib\libQtCore.so] Error 1
    mingw32-make[1]: Leaving directory `C:/Users/user/Desktop/qt_creator_toolchain...
    mingw32-make: *** [sub-corelib-make_default-ordered] Error 2
    

    This error happens after many complaints like:

    *.so uses VFP register arguments, *obj does not
    

    I've researched that error and have tried to pass each of the following options to my mkespec and rebuild with the same error:

    -mfloat-abi=softfp
    -mfloat-abi=soft
    -mfloat-abi=hard
    

    I am clearly not understanding why the '-mfloat-abi=softfp' option works fine with the CodeSourcery Windows toolchain but not Linaro. The rest of the compiler flags are shown in the mkspec above.

    Does anybody have any insight or thoughts on how to make this work? Thanks in advance.

    UPDATE:

    It turns out if I modify my C_FLAGS in the mkspec from this:

    -march=armv7-a -mtune=cortex-a8 -mthumb -mfpu=vfp -mfloat-abi=softfp -Wa,-mimplicit-it=thumb -marm -mthumb-interwork
    

    to this:

    -march=armv7-a -mtune=cortex-a8 -mthumb -mfpu=neon -mfloat-abi=hard -Wa,-mimplicit-it=thumb -marm -mthumb-interwork
    

    Then I can finally successfully compile Qt. How will this affect my performance / or ability to run a Qt App on the Board? Why can't I do softfp with Linaro but I can with CodeSourcery?