2

I have a Qt C++ Project.

System
Windows XP
QtCreator and QtSDK newest
C++
MinGW/gcc/g++

For performance reasons I need some functions to be done in assembly. My Project is mainly Qt and c++ but I need to link my C++ code to some assembly I wrote. I have an assembly *.o file but I can't access my assembly function from my c++ code. I complied the assembly calc.o file with nasm.

Simplified example.

PRO FILE

QT       += core
QT       -= gui

TARGET = Test_asm
CONFIG   += console
CONFIG   -= app_bundle

TEMPLATE = app
LIBS += C:/Users/David/Test_asm/calc.o

SOURCES += main.cpp

MAIN.CPP

#include <QtCore/QCoreApplication>
#include <QTextStream>

extern "C" int five();

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QTextStream qout(stdout);

    int f = five();

    qout << "five: " << f << endl;

    return a.exec();
}

ERROR

main.cpp:11: undefined reference to `five'
collect2: ld returned 1 exit status

TRY #1 - Karlphillip's way (Does not work on Windows)

 Directory of C:\x

16/03/2012  03:09 PM    <DIR>          .
16/03/2012  03:09 PM    <DIR>          ..
16/03/2012  03:07 PM                82 calc.pro
16/03/2012  03:10 PM               178 calc.S
16/03/2012  03:10 PM               164 main.c
               3 File(s)            424 bytes
               2 Dir(s)  78,905,851,904 bytes free

C:\x>qmake

C:\x>make
'make' is not recognized as an internal or external command,
operable program or batch file.

C:\x>mingw32-make
mingw32-make -f Makefile.Debug
mingw32-make[1]: Entering directory `C:/x'
gcc -c -g -Wall -DUNICODE -DQT_LARGEFILE_SUPPORT -I"..\QtSDK\Desktop\Qt\4.7.3\mi
ngw\mkspecs\default" -o debug\main.o main.c
gcc -c -g -Wall -DUNICODE -DQT_LARGEFILE_SUPPORT -I"..\QtSDK\Desktop\Qt\4.7.3\mi
ngw\mkspecs\default" -o debug\calc.o calc.S
g++ -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-rel
oc -Wl,-subsystem,console -mthreads -Wl -o debug\calc.exe debug/main.o debug/cal
c.o
debug/main.o: In function `main':
C:\x/main.c:9: undefined reference to `helloasm'
collect2: ld returned 1 exit status
mingw32-make[1]: *** [debug\calc.exe] Error 1
mingw32-make[1]: Leaving directory `C:/x'
mingw32-make: *** [debug] Error 2
L123
  • 139
  • 4
  • 14

4 Answers4

2

The best way that I found to work with assembly in QT Creator, it was to configure the .pro file. I added the nasm compiler to .pro file and some flags. You can change these flags if you need it. But with this configuration works well for me

example.pro

QMAKE_EXTRA_COMPILERS += nasm
NASMEXTRAFLAGS = -f elf64 -g -F dwarf
OTHER_FILES += $$NASM_SOURCES
nasm.output = ${QMAKE_FILE_BASE}.o
nasm.commands = nasm $$NASMEXTRAFLAGS -o ${QMAKE_FILE_BASE}.o ${QMAKE_FILE_NAME}
nasm.input = NASM_SOURCES

Finishing, you have to assign to NASM_SOURCES variable all the ASM files, in my case it was just one and it called arregloAsm.asm

NASM_SOURCES += arregloAsm.asm

I hope that all this works for you too!

Community
  • 1
  • 1
0

I first did what was mentioned earlier:

testasm.pro

QT += core
QT -= gui

CONFIG += c++11

TARGET = testasm
CONFIG += console
CONFIG -= app_bundle

TEMPLATE = app

SOURCES += main.cpp

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

QMAKE_EXTRA_COMPILERS += nasm
NASMEXTRAFLAGS = -f elf64 -g -F dwarf
OTHER_FILES += $$NASM_SOURCES
nasm.output = ${QMAKE_FILE_BASE}.o
nasm.commands = nasm $$NASMEXTRAFLAGS -o ${QMAKE_FILE_BASE}.o ${QMAKE_FILE_NAME}
nasm.input = NASM_SOURCES

NASM_SOURCES += test.asm

main.cpp

#include <QCoreApplication>

extern "C" void test();

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    test();
    return a.exec();
}

test.asm

global test

bits 64
section .text

test:
    mov rax,0
    ret

In the menu Build click build all and the application should be abel to run. It's a empty terminal in this example but on my system it works. I was looking for a solution and thanks to this post, I finally have one. Just remember to add

extern "C" void test();

to your main.cpp file. Notice "C" in the line because that was my biggest error. (In case of language errors: I'm no native English speaker, if you like please correct the text)

Agguro
  • 348
  • 3
  • 11
0

Same thing as before:

calc.S:

.data
hello:
    .string "Hello World\n"

.globl  helloasm
helloasm:
    movl $4, %eax
    movl $1, %ebx
    movl $hello,%ecx
    movl $12,%edx
    int $0x80

    ret

main.c:

#include <stdio.h>

void helloasm();

int main()
{
    printf("* Calling ASM function:\n");

    helloasm();

    printf("* Done!\n");

    return 0;
}

calc.pro:

TEMPLATE = app
CONFIG += console
CONFIG -= qt

SOURCES += main.c \
    calc.S

After putting all these files within the same directory, execute:

qmake
make

to verify the output:

$ ./calc 
* Calling ASM function:
Hello World
* Done!
Community
  • 1
  • 1
karlphillip
  • 92,053
  • 36
  • 243
  • 426
  • Thanks, I really do appreciate your help but (1) I need c++ not C (2) even with C it didn't work. Once again, I am on WindowXP 32bit, your on Linux. Maybe it is a Mingw thing? – L123 Mar 16 '12 at 19:14
  • Look at the top of this page for errors. I can't post errors in a comment because the formating breaks and not enough chars. – L123 Mar 16 '12 at 19:20
  • Change the order of the declarations in the .pro file, let `main.c` be the last entry. Not sure that has something to do with it. – karlphillip Mar 16 '12 at 19:26
  • Thanks, same error. It does compile if I remove all the lines that have anything to do with the assembly file. – L123 Mar 16 '12 at 19:39
0

Why didn't you add calc.o to your sources?

Joshua
  • 40,822
  • 8
  • 72
  • 132
  • I added it in LIBS because it is a compiled file, not a source file. Adding it to sources gives the same error. – L123 Mar 16 '12 at 19:56