PDA

View Full Version : qmake to build both 32-bit and 64-bit



lni
8th December 2006, 19:19
Hi,

I have a project file, say, foo.pro

How do I do to make it automatically build both 32-bit and 64-bit in one go?

That is, I want to type "qmake; gmake" then it builds 32-bit, after done, it then builds 64-bit automatically.

I know how to do it manually, or using a script by doing "QMAKESPEC=linux-g++-64 qmake; gmake", and "QMAKESPEC=linux-g++-32 qmake; gmake"

But I want qmake to do it for me. I want to create a *.pro file, where I can do like:

TEMPLATE = subdirs
SUBDIRS = foo.pro bar.pro
SOME-OTHER-FLAGS-FOR-32-BIT-AND-64-BIT-IN-ONE-GO

Then when I do "qmake; gmake", it make both 32-bit and 64-bit for me!

My machine is Linux 64-bit, but we have to maintain both 32-bit and 64-bit applications...My Qt is 4.2.2...

Many thanks.

jacek
8th December 2006, 19:51
How about something like this:

./foo.pro:

TEMPLATE = subdirs
SUBDIRS = build32 build64

./src/src.pri:

TEMPLATE = app
SOURCES += ...
HEADERS += ...
...

./build32/foo32.pro:


include(../src/src.pri)
QMAKESPEC=linux-g++-32
...

./build64/foo64.pro:


include(../src/src.pri)
QMAKESPEC=linux-g++-64
...

lni
8th December 2006, 20:18
Thank yoy Jacek.

The approach is very good!

However, it seems that the qmake ignores the "QMAKESPEC=linux-g++-32" or "QMAKESPEC=linux-g++-64" setting.

It builds 32-bit in both cases, ignoring the QMAKESPEC setting. Can we set the QMAKESPEC inside the pro file?

Thanks

lni

jacek
8th December 2006, 20:32
It builds 32-bit in both cases, ignoring the QMAKESPEC setting. Can we set the QMAKESPEC inside the pro file?
Yes, you can set it in a .pro file, but the docs suggest that you should change QMAKESPEC environment variable instead.

I think that the problem is that you use the same versions of Qt libraries for both builds, instead of using 64-bit ones when building 64-bit version of your application.

You can always replace foo.pro with an ordinary Makefile, like:
all: foo32 foo64

foo32:
QMAKESPEC=linux-g++-32 make -C ./build32

foo64:
QMAKESPEC=linux-g++-64 make -C ./build64

.PHONY: all foo32 foo64(or something more sophisticated).

lni
8th December 2006, 21:12
Thanks,

I wish not to use makefile, but apparently, that is the only solution at the moment.

Yes, I have to use same version qmake to build both, otherwise I have to maintain two build systems separately by switching QTDIR pointing to 32 and 64.

But qmake should support QMAKESPEC in the pro file....

jacek
8th December 2006, 22:08
But qmake should support QMAKESPEC in the pro file....
Maybe you have to tweak $QTDIR/mkspecs/linux-g++/qmake.conf and $QTDIR/mkspecs/linux-g++-64/qmake.conf so that one points to 32-bit Qt and the latter to 64-bit one? Because now, even if you change QMAKESPEC, qmake will use libraries from $QTDIR and these are either 32-bit or 64-bit, but not both at the same time.

lni
8th December 2006, 22:42
Because now, even if you change QMAKESPEC, qmake will use libraries from $QTDIR and these are either 32-bit or 64-bit, but not both at the same time.

I think I can do like

for 32:
CONFIG -= qt
LIBS += the-32-bit-libaries

for 64:
CONFIG -= qt
LIBS += the-64-bit-libaries

The "CONFIG -= qt" is to tell qmake not to go with the qt configuration's makespec.

No? qmake should not tie to the qt configuration. It is a tool on top of gmake, but if it ties to the qt configuration, then it become useless tool when you have to build both 32-bit and 64-bit, which is the case in most companies...

jacek
9th December 2006, 20:41
The "CONFIG -= qt" is to tell qmake not to go with the qt configuration's makespec.
There are a lot of settings in qmake.conf that qmake needs to know, so it will read it anyway.

"CONFIG += qt" in short means: "link with Qt", but if you take a look at $QTDIR/mkspecs/features/qt.prf, you'll see this isn't that easy to reproduce just by setting some variables in a .pro file.


qmake should not tie to the qt configuration. It is a tool on top of gmake, but if it ties to the qt configuration, then it become useless tool when you have to build both 32-bit and 64-bit
If that's a common problem, then maybe Trolltech support has some ready made solution for this?

If you don't want that additional Makefile and there are no other ideas, you can also consider using other build systems:
CMake (http://www.cmake.org/HTML/Index.html),
Scons (http://www.scons.org/wiki/Qt4Tool),
Waf (ex-bksys) (http://freehackers.org/~tnagy/bksys.html).
With CMake it should be doable using just one CMakeLists.txt file --- it's just a matter of resetting some variables. I don't know much about the other two build systems, but they're are similar to CMake.

lni
12th December 2006, 19:35
I think I got it to work. You may need to treak for the QTDIR setting...

Fortran support also included. Comments are welcome!


For FORTRAN support (config.for)

CONFIG += f90

CONFIG(debug, debug|release) {
F90_CFLAGS = -g -O0
} else {
F90_CFLAGS = -O2
}

intel {
F90 = g77
}

isEmpty( F90 ) {
F90 = g77
}

ff90.input = F90_SOURCES
ff90.output = ${OBJECTS_DIR}${QMAKE_FILE_BASE}.o
ff90.commands = $$F90 -c $$F90_CFLAGS $$QMAKE_LFLAGS ${QMAKE_FILE_NAME} \
-o ${QMAKE_FILE_OUT} \
${INCPATH}
QMAKE_EXTRA_UNIX_COMPILERS += ff90


Support both 64-bit and 32-bit - config.h


# turn on the compiler warning
CONFIG += warn_on

#global definition
DEFINES = INT INTR3 QT3_SUPPORT

# global include file paths
MOC_DIR = .moc
UI_DIR = .ui
OBJECTS_DIR = .obj

# just a message
CONFIG(debug, debug|release) {
message(Building in debug mode.)
} else {
message(Building in release mode. Ignoring debug if it is available.)
}

contains( TARGET_BIT, m64 ) {
message(Building 64 bit )
QTDIR = /apps/qt64-422
BITS = 64
QMAKE_CFLAGS = -m64
QMAKE_CXXFLAGS = -m64
QMAKE_LFLAGS = -m64
}

contains( TARGET_BIT, m32 ) {
message(Building 32 bit )
QTDIR = /apps/qt32-422
BITS =
QMAKE_CFLAGS = -m32
QMAKE_CXXFLAGS = -m32
QMAKE_LFLAGS = -m32
}

!isEmpty( TARGET_BIT ) {
message( TARGET_BIT = $$TARGET_BIT )
CONFIG -= qt
CONFIG += moc
INCLUDEPATH += \
$$QTDIR/include/QtCore \
$$QTDIR/include/QtGui \
$$QTDIR/include/QtNetwork \
$$QTDIR/include/Qt3Support \
$$QTDIR/include

LIBS += $$QTDIR/lib -lQtCore -lQtGui -lQtNetwork -lQt3Support
} else {
message( Build in default )
INCLUDEPATH += ${QTDIR}/include/Qt3Support
}

# FORTRAN configuration file
exists( $$PWD/config.for ) {
include( $$PWD/config.for )
} else {
include( $(MAKE_ROOT)/bin/config.for )
}

LANGUAGE = C++ C

Fortran example - fortran.f


subroutine blah

return
end


C example - cfile.c


void foo()
{
}


C++ example - c++file.cpp


void bar()
{
}


Examples.pro


TEMPLATE = subdirs

DIRLIST = build32 build64

for( dir, DIRLIST ): exists( $$dir ): exists( $$dir/*.pro ): SUBDIRS += $$dir


build32/build32.pro


TARGET_BIT = m32
include ( ../common.pri )


build64/build64.pro


TARGET_BIT = m64
include ( ../common.pri )


common.pri - path needs to be reset to fit your system


################################################## ####################
# Automatically generated by qmake (2.01a) Thu Nov 16 15:23:45 2006
################################################## ####################

TEMPLATE = app

# Input
SOURCES += c++file.cpp cfile.c main.cpp
F90_SOURCES += fortran.f

TARGET = Examples

# if there is local config file, use it
exists( ../bin/config.h ) {
message(Use local config.h)
include( ../bin/config.h )
} else {
message(Use baseline's config.h)
include( $(MAKE_ROOT)/bin/config.h )
}