[Qgis-developer] Some concerns about QGIS on OS X, part 1
Mac Programmer
macpgmr at fastermac.net
Sat Feb 7 20:16:59 EST 2009
Out of curiosity, has anyone actually tried the C++ examples in the
1.0 user guide, particularly on a Mac? I'm finding them pretty rough
sledding.
Chapter 14, C++ plugin example:
The SVN sources for this example looked pretty old (2006), so I just
copied and pasted step 1 into .pro, .h and .cpp files, then modified
the .pro file as best I could figure for my system. Then what? Well,
it doesn't say. After some googling, I tried running qmake and then
make - nothing happened. More googling. Okay, apparently qmake
creates an Xcode project, so I opened the .xcodeproj folder in Xcode.
From there I was able to build the library, although it ignored
the .pro file's DEST setting and also gave a couple of warnings.
However, looking at the resulting .dylib with otool -L and -h showed
that the .dylib was linked differently from the other plugin .so
files in /lib/qgis and was not a "bundle" (filetype 8). So I decided
to go back to basics and compile and link the plugin myself.
By the way, here's what I had tried for a .pro file:
QGIS_DIR = /Users/phil/Desktop/qgis-1.0.0/qgis1.0.0.app/Contents/MacOs
TEMPLATE = lib
CONFIG = qt
QT += xml qt3support
unix:LIBS += -L$$QGIS_DIR/Lib
INCLUDEPATH += $$QGIS_DIR/include/qgis
SOURCES = qgspointconverterplugin.cpp
HEADERS = qgspointconverterplugin.h
DEST = pointconverterplugin.so
DEFINES += GUI_EXPORT= CORE_EXPORT=
Here's what I came up with:
#!/bin/sh
# Force Bourne shell in case tcsh is default.
#
BASE=~/Desktop/qgis-1.0.0/qgis1.0.0.app/Contents/MacOs
INCLUDE1=$BASE/include/qgis
INCLUDE2=/Library/Frameworks/QtCore.framework/Headers
INCLUDE3=/Library/Frameworks/QtGui.framework/Headers
INCLUDES="-I$INCLUDE1 -I$INCLUDE2 -I$INCLUDE3"
LINK1=$BASE/Lib/libqgis_core.dylib
LINK2=$BASE/Lib/libqgis_gui.dylib
LINK3=$BASE/Lib/QtCore.framework/Versions/4/QtCore
LINK4=$BASE/Lib/QtGui.framework/Versions/4/QtGui
LINKS="$LINK1 $LINK2 $LINK3 $LINK4"
DEFINES="-D GUI_EXPORT= -D CORE_EXPORT="
XLINKER="-Xlinker -executable_path -Xlinker $BASE"
PLUGIN=pointconverterplugin
if [ -e "$INCLUDE1" ]
then
if [ -e "$INCLUDE2" ]
then
moc -o moc_qgs$PLUGIN.cpp qgs$PLUGIN.h
CMD="g++ -mmacosx-version-min=10.4 $DEFINES $INCLUDES $LINKS qgs
$PLUGIN.cpp -o lib$PLUGIN.so -fPIC -bundle $XLINKER"
echo executing: $CMD
$CMD
otool -L lib$PLUGIN.so
else
echo "Can't find Qt frameworks -- need to install Qt"
echo "Did not find: $INCLUDE2"
fi
else
echo "Can't find QGIS -- change location of QGIS in this script"
echo "Did not find: $INCLUDE1"
fi
This script successfully compiled both the step 1 and step 2 source
and the resulting .so loaded fine in QGIS once placed in lib/qgis.
Note that since the Qt header files are not included with QGIS, I had
to use header files from a separate installation of the Qt frameworks.
Also, something that really tripped me up for a long time was the
need to create the "moc" file. I then had to insert this in the
qgspointconverterplugin.cpp file:
#include "moc_qgspointconverterplugin.cpp"
However, when I tried the script with the step 3 source, I got an
error about a missing geos_c.h file. Searching my system for this
file didn't turn up anything, so at that point I gave up.
Question: Did the folks who wrote and compiled the C++ plugins
included with the OS X QGIS have a chance to review Chapter 14 in the
user guide?
Chapter 16, C++ application example:
This time I started with the SVN sources, but the compile
instructions on page 157 are not correct. There is no "cmake" on my
system. So back to the drawing board. This is what I came up with:
#!/bin/sh
# Force Bourne shell in case tcsh is default.
#
APP=main
QTBASE=/Library/Frameworks
FWEXT=.framework
LIB1=Core
LIB2=Gui
LIB3=Xml
QGISBASE=~/Desktop/qgis-1.0.0/qgis1.0.0.app/Contents/MacOs
BASE1=$QTBASE/Qt$LIB1$FWEXT
BASE2=$QTBASE/Qt$LIB2$FWEXT
BASE3=$QTBASE/Qt$LIB3$FWEXT
INCLUDEQG=$QGISBASE/include/qgis
INCLUDE1=$BASE1/Headers
INCLUDE2=$BASE2/Headers
INCLUDE3=$BASE3/Headers
LINKQG1=$QGISBASE/Lib/libqgis_core.dylib
LINKQG2=$QGISBASE/Lib/libqgis_gui.dylib
LINK1=$QGISBASE/Lib/Qt$LIB1$FWEXT/Versions/4/Qt$LIB1
LINK2=$QGISBASE/Lib/Qt$LIB2$FWEXT/Versions/4/Qt$LIB2
DEFINES="-D GUI_EXPORT= -D CORE_EXPORT="
INCLUDES="-I. -I$INCLUDEQG -I$INCLUDE1 -I$INCLUDE2 -I$INCLUDE3"
LINKS="$LINKQG1 $LINKQG2 $LINK1 $LINK2"
XLINKER="-Xlinker -executable_path -Xlinker $QGISBASE"
if [ -e "$LINKQG1" ]
then
CMD="g++ -mmacosx-version-min=10.4 $DEFINES $INCLUDES $LINKS
main.cpp -o $APP $XLINKER"
echo executing: $CMD
$CMD
otool -L $APP
else
# QGIS not in expected location or different version.
echo "Can't find QGIS -- check location of QGIS in this script"
echo "Did not find: $LINKQG1"
fi
The resulting compiled executable does work, but only if you create
an app bundle for it and copy the QGIS libraries and Qt frameworks
from the qgis1.0.0.app bundle, thus duplicating them on your system.
It seems like the C++ instructions in the user guide present good
examples of the directions-to-the-wedding-reception paradox, where
the directions only make sense to a local, who does not need them
since he already knows the area. Same with these examples: anyone who
can successfully compile them in short order probably doesn't need
the instructions, whereas those who struggle need much more than what
is in the user guide.
Thanks.
-Phil
More information about the Qgis-developer
mailing list