PDA

View Full Version : gfortran + Qt works for X11/Linux but not for minGW under windows XP



cjtsai
7th April 2010, 02:38
gfortran works perfectly with Qt under Fedora12. But it does not work properly with minGW/Msys under windows XP.

Here is the modified example from qt/examples/opengl/grabber

f90main.f

program f90main
!-------------------------------------------------------
! Apr-05-2010 V1.0.0 Apr-05-2004 File: f90main.f
!-------------------------------------------------------

implicit none

integer (2) :: i,iargc
integer (4) :: Narg
character (80) :: Farg(5)

!---get fortran command-line arguments
Narg = iargc()
do i=1,Narg
call getarg (i,Farg(i))
end do

call Qtmain (Narg,Farg)

END program f90main

qtmain.cpp

/************************************************** ****
Apr-05-2010 V1.0.0 Apr-05-2010 File: qtmain.cpp
************************************************** ****/

#include <QApplication>

#include "mainwindow.h"

extern "C" {

MainWindow *qt ;

void qtmain_ (int *argc, char *argv[]) {

QApplication app(*argc, argv);
MainWindow mainWin;
qt = &mainWin;
mainWin.show();
app.exec();
}
}

makefile for minGW/Msys under windows XP

prog = f90main

F90 = gfortran
F90FLAGS = -m32 -O2 -ffree-line-length-0 -ffree-form

LINK = gfortran

f90Objects = f90main.o

Qt = /mingw/Qt/4.6.2

CC = gcc
CXX = g++
DEFINES = -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_EVAL -DQT_DLL -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -DQT_
NEEDS_QMAIN
CFLAGS = -m32 -O2 -Wall $(DEFINES)
CXXFLAGS = -m32 -O2 -frtti -fexceptions -mthreads -Wall $(DEFINES)
INCPATH = -I'c:/minGW/Qt/4.6.2/include/QtCore' -I'c:/minGW/Qt/4.6.2/include/QtGui' -I'c:/minGW/Qt/4.6.2/include/QtOpenGL' -I'c:/minGW/Qt/4.6.2/i
nclude' \
-I'c:/minGW/Qt/4.6.2/include/ActiveQt' -I'tmp/moc/release_shared' -I'c:/minGW/Qt/4.6.2/mkspecs/win32-g++'

LFLAGS = -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -Wl,-s -mthreads -Wl -Wl,-subsystem,windows
LIBS = -L'c:/minGW/Qt/4.6.2/lib' -lstdc++ -lopengl32 -lglu32 -lgdi32 -luser32 -lmingw32 -lqtmain -lQtOpenGL4 -lQtGui4 -lQtCore4

####### Files
SOURCES = qtmain.cpp glwidget.cpp mainwindow.cpp moc_glwidget.cpp moc_mainwindow.cpp
OBJECTS = qtmain.o glwidget.o mainwindow.o moc_glwidget.o moc_mainwindow.o
TARGET = $(prog).exe

MOC = $(Qt)/bin/moc

####### Implicit rules
.SUFFIXES: .o .c .cpp .cc .cxx .C .f .h

.f.o:
$(F90) -c $(F90FLAGS) $(F90INCPATH) -o $@ $<

.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
$(TARGET): $(f90Objects) $(OBJECTS)
$(LINK) $(LFLAGS) -o $(TARGET) $(f90Objects) $(OBJECTS) $(LIBS)

####### moc
moc_glwidget.cpp: glwidget.h
$(MOC) $(DEFINES) $(INCPATH) glwidget.h -o moc_glwidget.cpp

moc_mainwindow.cpp: mainwindow.h
$(MOC) $(DEFINES) $(INCPATH) mainwindow.h -o moc_mainwindow.cpp

moc_glwidget.o: moc_glwidget.cpp mainwindow.h
moc_window.o: moc_window.cpp mainwindow.h

all: $(TARGET)

clean:
rm *.o
rm moc*.cpp

For GNU Fortran (GCC) 4.4.3 under fedora12 with Qt 4.6.2, it works fine. But with GNU Fortran (GCC) 4.4.0 and GNU make 3.81 with Qt 4.6.2 under minGW/Msys/windows XP, it gave the errors:


c:/minGW/Qt/4.6.2/lib/libqtmain.a(qtmain_win.o):qtmain_win.cpp:(.text+0x 131): undefined reference to `qMain(int, char**)'
collect2: ld returned 1 exit status
make: *** [f90main.exe] Error 1

Is there a walk-around solution for this problem?
Thanks

cjtsai
7th April 2010, 19:13
After searching web for solution, it turned out the error was caused by a missing main() routine under the minGW/MSYS environment.

If the 'qtmain.cpp' is replaced by


/************************************************** ****
Apr-05-2010 V1.0.0 Apr-05-2010 File: qtmain.cpp
************************************************** ****/

#include <QApplication>

#include "mainwindow.h"
#include <iostream>
#include <string.h>

using namespace std;

int main (int argc, char *argv[]) {

QApplication app(argc, argv);
MainWindow mainWin;
mainWin.show();
return app.exec();
}

extern "C" {

void qtmain_ () {
int argc = 0;
char argv[0][0];
main (argc,(char**)argv);
}

}

the compilation went through. However, the f90 main program 'f90main.f' was never executed since the entry point go directly to main() while running 'f90main.exe'.

Now the question is why under minGW/MSYS Qt requires a main() routine?
Is it a bug or the nature of windows system?
Also, is it a way to instruct GNU loader 'ld' to start from Fortran's main program?

Thanks.