Building and Configuring LyX/Qt on Cygwin
This document is a summary of the steps to build and configure LyX on
windows using the cygwin environment. This is not for the fainthearted
or the impatient. I took me about a week to figure all the details
(with the help of several people, including Georg Baum, Ruurd, Did
Bar-David, and my wife Orith). But I use LyX a lot (on Linux up to now)
so it was well worth the effort.
- Install cygwin, including X11
- Install gcc version 2.95.3 (get it here).
This is NOT the version that comes with cygwin, which is currently
3.3.1. Versions 3.3.1 and 3.3.2 generate a few object files that do not
link properly. The problem looks like a g++ bug, but I am not sure.
2.95.3 works fine.
- Install stlport. The
version of the C++ standard libraries that comes with gcc 2.95.3 is
defective (this is a known bug). Stlport is a complete C++ standard
library.
- Install Qt 3.x. I used 3.3.0, which is the most recent now,
but older versions should work. Configuring Qt is a bit tricky.
The reason is that the Qt distribution comes with configuration files
for many platforms, including cygwin on Windows. However, the
prepackaged configuration is designed for a native build, not for an
X11 build. Since the native-build files are not distributed with the
free version of Qt, you can't use the preconfigured cygwin-g++ build.
What you must do instead is modify the build files so that they force
Qt to build an X11 library under cygwin.
In addition to the X11 issue, there are two other issues under
cygwin. One is dynamic vs. static libraries. Cygwin uses an
unusual naming scheme for dynamic libraries, a .dll.a extension, which
is unlike the usual Unix/Linux naming scheme, which uses an .so extension with a
suffix that indicates a version. Qt expect the usual Unix naming
convension, and as a consequence, I wasn't able to build a dynamic
library. That is why the configuration setup below uses a -static flag. This is probably
less of an issue under Windows since there aren't likely to be so many
programs using Qt under cygwin simultenesouly. If you run many Qt
programs at the same time, as you do when you use KDE under Linux, for
example, then the dynamic library saves a lot of memory. If you only
use Qt to run LyX, the difference is minor.
The last significant issue is the set of modules that can or cannot be
built. I disabled most of the Qt modules that I thought were not
essential for LyX to reduce build problems. One module that proved
particularly difficult is the network module. Cygwin is missing the DNS
header files, so the network module cannot be built. The network module
is also used intenally by some Qt tools, so their build breaks. This
includes Qt Assistant. This does not interfere with LyX, but the Qt
build is incomplete. This issue is the reason for the -DQT_NO_DNS flag.
OK, here are the detailed instructions.
- use gcc-2 and g++-2 in mkspecs/cygwin-g++/qmake.def
- add -fnative-struct to CFLAGS in the same file. This ensures
that the library links properly with LyX. Qt can be built without this
flag, but not with lyx. Maybe deleting the option in both will also
work, but is seems safer to use it.
- hardcode Q_WS_X11 and Q_OS_UNIX, to override the cygwin
defaults in src/tools/qglobal.h. Add this after the Q_WS_* and Q_OS are
set:
#undef Q_WS_WIN32
#undef Q_WS_WIN
#undef Q_OS_WIN32
#undef Q_OS_WIN64
#undef Q_OS_WIN
#define Q_WS_X11
#define Q_OS_UNIX
- delete #include <windows.h> from
mkspecs/cygwin-g++/qplatformdef.h.
- add dll.a to the allowed dll extensions in
config.tests\x11\xfreetype.test. This is only necessary if you want to
use Xft an freetype (highly recommended to get high-quality text
display).
EXTENSIONS="a so sl dll.a"
- cd to the Qt main library and invoke the following script,
which configures the build. Change the paths below to where you
installed freetype, if they are not in the default location.
export QTDIR=$PWD
./configure -platform
cygwin-g++ \
-static \
-freetype -xft
-I/opt/freetype-2.1.5/include -L/opt/freetype-2.1.5/lib \
-no-stl \
-no-thread -no-nis
-no-cups -no-largefile \
-qt-zlib \
-qt-gif \
-qt-imgfmt-png
-qt-libpng \
-qt-imgfmt-jpeg
-qt-libjpeg \
-qt-imgfmt-mng
-qt-libmng \
-no-g++-exceptions
-no-exceptions \
-disable-opengl
-disable-sql -disable-network \
-no-style-cde
-no-style-motif -no-style-motifplus \
-no-style-platinum
-no-style-sgi \
-no-sm \
-DQT_NO_DNS
- Type "make". The build will break when Qt will try to build Qt
Assistant, due to the DNS issue. But at this time the library has been
successfully built. You can go to one of the example libraries, type
make, and run the example (make sure X is running).
- That's it, Qt is ready.
- Now we build LyX. Basically, all you need is to configure the
library propely.
- Before we can configure LyX, we have to fix the configure
script a bit. After the line that defines the various possible Qt
library names (-lqt, -lqt3, -lqt-mt, and so on), change the original
definition of the variable LIBS to
LIBS="$LIBS $libname -lX11
-lXext -lXrandr -lXrender -lXcursor"
This is required because Qt is a static library that does
not indicate which DLL's it needs.
- Run the following configure setup script, after changing the
paths appropriately:
- ./configure \
--prefix=/opt/lyx-1.3.3 \
-with-frontend=qt \
--with-qt-dir=/home/stoledo/qt-x11-free-3.3.0 \
QTDIR=/home/stoledo/qt-x11-free-3.3.0 \
CXX=g++-2 \
CC=gcc-2 \
CPP=cpp-2 \
CXXFLAGS="-O -DCXX_GLOBAL_CSTD -nostdinc++ -fno-exceptions
-ftemplate-depth-64 -I/home/stoledo/STLport-4.6.1/stlport" \
LDFLAGS="-L/home/stoledo/STLport-4.6.1/lib -lstlport_cygwin -lm"
- Type "make". It will halt three times on minor syntactic errors
(multiple definitions of symbols), once for std::i_forgot and twice for
std::atoi. Just comment these out and restart. I am not sure whether
this problem is due to g++ 2.95 vs g++ 3, or due to stlport.
- This is still not enough. The make process will also die when
it will try to retrieve all the symbols from the Qt dll, which does not
exist. When it does, just type make again.
- The make process will die again at the very end, when it tries
to link lyx.exe. The link command in the makefile is flawed. Move to
the src directory and issue the following link command:
g++-2 -nostdlib -v \
/usr/lib/crt0.o \
-o lyx.exe BufferView.o \
BufferView_pimpl.o Bullet.o Chktex.o CutAndPaste.o DepTable.o \
FloatList.o Floating.o FuncStatus.o InsetList.o LColor.o LaTeX.o \
LaTeXFeatures.o LyXAction.o MenuBackend.o paragraph_funcs.o \
ParagraphList.o ParagraphParameters.o Spacing.o TextCache.o Thesaurus.o
\
ToolbarDefaults.o boost.o boost-inst.o box.o buffer.o bufferlist.o \
bufferparams.o bufferview_funcs.o chset.o converter.o counters.o
debug.o encoding.o \
exporter.o gettext.o factory.o funcrequest.o importer.o intl.o
iterators.o kbmap.o \
kbsequence.o language.o lastfiles.o lengthcommon.o lyx_cb.o lyx_main.o
lyx_sty.o \
lyxcursor.o lyxfont.o lyxfind.o lyxfunc.o lyxgluelength.o lyxlayout.o
lyxlength.o \
lyxlex.o lyxlex_pimpl.o lyxrc.o lyxrow.o lyxserver.o lyxtextclass.o \
lyxtextclasslist.o lyxvc.o main.o paragraph.o paragraph_pimpl.o
ispell.o pspell.o \
sgml.o tabular.o tabular-old.o tabular_funcs.o tex-accent.o
tex-strings.o texrow.o \
text.o text2.o text3.o toc.o trans.o trans_mgr.o undo.o undo_funcs.o
vc-backend.o \
version.o vspace.o \
mathed/.libs/libmathed.a \
insets/.libs/libinsets.a \
frontends/.libs/libfrontends.a \
graphics/.libs/libgraphics.a \
support/.libs/libsupport.a \
../boost/libs/regex/src/.libs/libboostregex.a \
../boost/libs/signals/src/.libs/libboostsignals.a \
-L/home/stoledo/STLport-4.6.1/lib -lstlport_cygwin \
.libs/libimp-cygintl-2.a .libs/libimp-cygiconv-2.a \
-lSM -lICE \
-L$QTDIR/lib -lqt \
-L/opt/freetype-2.1.5/lib -lfreetype \
-L/usr/X11R6/lib -lXft -lfontconfig -lXrender -lXrandr -lXcursor -lXext
-lX11 -ldl \
-lgcc \
-lcygwin -luser32 -lkernel32 -ladvapi32 -lshell32
- Hopefully, that's it. Type "make install" and you should be all
set.
- A few more details: I use the cygwin ghostscript and gv, but the
native Win32 TeX package fpTeX, which comes as part of TeXLive 2003.
LyX can use it very well. I had trouble with the cygwin teTeX.
- I had some problems with ImageMagick, the software that LyX uses
to convert EPS and other graphic formats to bitmaps that it can display
on the screen. I had two versions installed, but non worked. One
was the Win32 version, which called the Win32 GhostScript 8. It failed.
I didn't test too much and installed instead the cygwin port, which
uses the cygwin GhostScript, which is version 7. It was defective
because it searched for its configuration files (with a .mgk suffix) in
the wrong place. A symbolic link fixed that, but it still failed to
convert EPS to PPM. A bit of testing showed that the problem was that
LyX invokes it with a command that looks like convert -depth 8 eps:epsfilename.eps
ppm:ppmfilename.ppm. For some reason, the eps: prefix causes
convert.exe to add some binary junk to the EPS file, which causes
GhostScript to fail. I finally fixed that by putting the following
script in .lyx/scripts/convertDefault.sh:
#! /bin/sh
# The default converter if no
other has been defined by the user from the
# Conversion->Converter
tab of the Preferences dialog.
#
# The user can also redefine
this default converter, placing their
# replacement in
~/.lyx/scripts
#
# converts an image from $1
to $2 format
sourcefile="`echo $1 | sed
's/eps://'`" # this fixes the
problem
/opt/ImageMagick-5.5.7/bin/convert
-depth 8 "$sourcefile" $2 # use
your actual path
if [ $? -ne 0 ]; then
exit $?
fi
# It appears that convert
succeeded, but we know better than to trust it ;-)
# convert is passed strings
in the form "FMT:FILENAME", so use the ':' to
# delimit the two parts.
FILE=`echo $2 | cut -d ':' -f
2`
# FSTATUS == 0 is the file
exists and == 1 if it does not.
FSTATUS=0
test -f $FILE || FSTATUS=1
exit $FSTATUS
This fixed it. Eventually, I installed ImageMagick from the sources,
which resolved the configuration file problems. That is why I have the
full path to convert in the script
- I think that this is it. Enjoy (I do).