Remove outdated, unmaintained build system. Still one to go ;-)

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@40780 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Georg Baum 2012-02-19 13:13:05 +00:00
parent 1585015805
commit 360b94ee35
11 changed files with 6 additions and 7229 deletions

View File

@ -1,357 +0,0 @@
=========================
Building LyX with SCons
=========================
July, 2006
The GNU Build System (autoconf, automake and make) has been used to build
and distribute lyx. These de facto *nix tools are readily available and
widely supported on the *nix systems, but not so under windows. They are
not necessarily easy to use and maintain (at least to non-m4 experts)
either. Because of these, a scons (http://www.scons.org) build system has
been set up as an alternative way to build lyx. As of writing, this system
only supports the qt4 frontend.
This file is organized as follows:
1. General usage of scons
2. *nix systems (Linux, Solaris and Mac OSX)
3. Windows/mingw
4. Windows/cygwin
5. Windows/msvc
6. Tips and hints
7. Troubleshooting
1. General usage of scons
=========================
Prerequisites:
--------------
* Python:
Python >= 2.6.0 is required to run scons, while LyX itself requires
Python >= 2.4.0 for scripts such as configure.py. Python is widely
available on non-windows systems. Windows users can download and
install python from http://www.python.org.
* SCons:
scons >= 1.1.0 is needed. You can either use a full system-wide scons
distribution or a light-weight one (called scons-local) installed along
with the lyx source tree. Both variants of scons are freely available
from http://www.scons.org. Note that LyX source may ship with scons-base
in the near future.
* Other libraries:
These include zlib (required), qt4 (required), gettext
(optional), boost (optional), aspell (optional) and Aiksaurus
(optional). Please refer to the system-specific sections regarding the
availability and installation of them.
Start scons:
------------
The scons system resides under development/scons. You can invoke it from
either development/scons by, for example:
> cd development/scons
> scons frontend=qt4 qt_dir=d:/qt4 -j3 lyx
or from any other directory and use -f option to point to the SConstruct
file:
> mkdir build
> cd build
> scons -f ../development/scons/SConstruct frontend=qt4 all
If you are tired of typing development/scons/SConstruct, you can link
development/scons/SConstruct to the top source directory and use this
SConstruct file.
There are three types of command line options:
* key=value are user options. They are used to tell scons which
frontend to use, whether or not use included boost libraries etc.
You can use 'scons -h' to list all of the options.
* parameters start with - or -- are scons options. Useful ones include
-j3 (with three threads) and --config=force (force reconfiguration).
* others options are targets, which are lyx objects to build.
User Options:
-------------
Here I only list important options that you will likely use. Full option
list with detailed description and default value can be displayed using
command 'scons -h'.
Components to use/build:
* frontend=qt4: qt4 is the only option right now.
* mode=debug/release: lyx will be built under the debug or release
directory, with different default build options.
* boost=included/system/auto: whether or not use included boost, system
boost, or try to detect system boost first. Note that boost=included
is safer if system boost has a different version from the included
one.
* gettext=included/system/auto
* nls=yes/no whether or not enable natural language support.
* spell=aspell/auto: spell engine
Paths: Most of them will be probed if not specified.
* qt_dir: top level directory of qt (with at least subdirectory bin
containing commands uic and moc)
* qt_lib_path: path to the qt library, use only if there is no
$qt_dir/lib
* qt_inc_path: path to qt include directory, use only if there is no
$qt_dir/include
* extra_inc_path, extra_inc_path1, extra_lib_path, extra_lib_path1:
additional paths to other libraries
* extra_bin_path: a convenient way to add an extra path to $PATH
Convenience options:
* load_option=yes/no/opt1,opt2/-opt1,opt2: if true, load previously saved
command line options so you can run 'scons install' directly after a
long 'scons all' building command. You can load selected options using
load_option=opt1,opt2,... or exclude options using the - version of it.
Note that the option 'bundle' is not reloaded.
* rebuild=target1,target2... By default, scons will exam all components
when you build lyx. You can free scons from some hard work and save
yourself some time by telling scons to rebuild only specified
component(s). rebuild=no, none, yes or all can be used as well.
* log_file: a log file of executed commands, default to scons_lyx.log
Installation options:
* prefix: directory where lyx will be installed
* exec_dir: directory where lyx binaries will be installed.
Default to $prefix/bin
* DESTDIR: if specified, install to this directory instead of $prefix.
* version_suffix=yes/no/something : if specified, this suffix will be
appended to the user data directory.
* win_installer: if specified under windows, and if 'installer' target
is given, generate NSIS installer specifed as win_installer which can
be a full path name. The default is lyx-version-timestamp-Installer.exe
for a development version, and lyx-version-Installer.exe for a released
version.
Compiler choice and flags:
* use_vc: use msvc instead of mingw g++ under windows
* optimization: optimization flag to use (e.g. -O2)
* CC, LINK, CPP, CXX, CCFLAGS, LINKFLAGS etc: compiler commands and
flags. Setting CCFLAGS etc will replace default flags. These variables
can be set as environment variables as well.
Targets:
--------
You can specify one or more of the following targets:
Static libraries (names correspond to their directories):
boost, intl, support, mathed, insets, frontends, graphics,
controllers, client, qt4, lyxbase
Programs:
tex2lyx, client, lyx, all = tex2lyx + client + lyx
Installation:
po, install = all + po, installer (windows only, need NSIS)
Misc:
msvs_projects, update_po
Your built targets are put into $build_dir, which is debug (mode=debug),
release (mode=release) or any name specified via build_dir=name. The
directory structure is:
$build_dir
- common: most of the intermediate files, mostly object files
- libs: all static libraries
- executables: lyxclient, tex2lyx, lyx
MSVS projects will be put to development/scons (and you should invoke
scons from there for this target).
update_po is similar to 'cd po; make update-po' but does not generate
.gmo files, which is the task of the install target. Note that this
target is the only target that changes files (po/*.po in this case)
of the lyx source tree.
A typical working sequence:
---------------------------
> cd development/scons
> scons frontend=qt4 qt_dir=/path/to/qt4
(build lyx, and all needed libraries...)
> scons all -j3
(build lyx, client and tex2lyx, options like qt_dir will be carried
over here)
> scons rebuild=lyxbase
(working on LyX.cpp, so only need to rebuild lyxbase)
> scons
(build again, only lyxbase will be rebuilt)
> scons prefix=/usr/site DESTDIR=/install/dir
(lyx is built for /usr/site, but install to /install/dir)
2. *nix systems (Linux, Solaris and Mac OSX)
============================================
Proper use of extra_inc_path, qt_dir etc should solve most of the
problems.
3. Windows/mingw
================
* install mingw with the following packages:
binutils-2.16.91-...tar.gz
gcc-core-3.4.5-...tar.gz
gcc-g++-3.4.5-...tar.gz
mingw-runtime-3.9.tar.gz
mingw-utils-0.3.tar.gz
MSYS-1.0.11-...exe
msysDTK-1.0.1.exe
w32api-3.6.tar.gz
* install the latest Qt official "open source" binary package for
Windows/Mingw (required)
* install mingw/zlib (required):
Download zlib binaries and developer files (zlib-1.2.3-bin.zip and
zlib-1.2.3-lib.zip) from http://gnuwin32.sourceforge.net/packages/zlib.htm .
* install iconv (optional):
Download libiconv from http://gnuwin32.sourceforge.net/packages/libiconv.htm
The complete package (without source) is recommended.
You may also try the windows binary (libiconv-x.x.x.bin.woe32.zip) of
iconv from one of the GNU mirrors listed in http://www.gnu.org/prep/ftp.html.
* install gettext (optional):
Download gettext from http://gnuwin32.sourceforge.net/packages/gettext.htm
The complete package (without source) is recommended.
You may also try the windows binary (gettext-runtime-x.x.x.bin.woe32.zip
and gettext-tools-x.x.x.bin.woe32.zip) from one of the GNU mirrors
(e.g. http://mirrors.usc.edu/pub/gnu/gettext/).
* install aspell (optional):
LyX uses aspell 0.60.4 and there is no, as of now, official windows
version. If you do not want to compile aspell from source by yourself,
your best bet is using Abdel's lyx 1.5.0svn experimental package located
at http://wiki.lyx.org/Windows/LyX150Experimental. The link to his
pre-built aspell package is http://younes.a.free.fr/Lyx-15-experimental
* install aiksaurus (optional):
Try to build aiksaurus from source (both mingw or msvc should work),
or look for pre-built package from the lyx 1.5.0svn experimental page.
* Open a mingw xterm, and start scons as usual.
Note: gettext, iconv and zlib are usually decompressed to c:/mingw so no
extra_inc_path etc is needed.
4. Windows/cygwin
=================
To build lyx for cygwin, you should
* install (using the cygwin setup program) at least the following
packages and all other packages pulled in by dependencies:
aspell gzip libiconv libQtGui4
aspell-dev gettext libpng libQtGui4-devel
gcc gettext-devel libQtCore4 pkg-config
gcc4 libintl8 libQtCore4-devel python
* install aiksaurus (http://aiksaurus.sourceforge.net/, optional):
There is no cygwin package for aiksaurus, so you should build it from
source. However, aiksaurus builds smoothly on cygwin.
* run scons as you would do under linux.
Note: cygwin/qt does not follow the usual $qt_dir/include, $qt_dir/bin,
$qt_dir/lib directory structure. For example, cygwin/qt4 uses directories
/usr/include/qt4, /usr/lib/qt4/bin and /usr/lib/qt4/lib. If these
directories can not be detected automatically, use options, for example,
qt_dir=/usr/lib/qt4 qt_inc_path=/usr/include/qt4
5. Windows/msvc
===============
To build lyx with msvc, you should
* install msvc
It is recommended that you use MSVC2005 Express edition which is
freely available from microsoft.
* get windows platform SDK
Please follow the link in the MSVC webpage to download and configure.
It is important that you add SDK paths to %INCLUDE% and %LIB% in, e.g.,
C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\vsvars32.bat.
If you plan to use the MSVS IDE, you should also update the Visual C++
directories in VCProjectEngine.dll.express.config, as suggested in
http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk/.
* build qt4
- download qt4 source from trolltech (not the binary version, which
only works with mingw)
- get q../free patch for qt4
- compile qt4 as instructed
* download and install the official zlib library from www.zlib.org.
* optionally install iconv, gettext, aspell, aiksaurus following
the mingw instructions.
* start from msvc command prompt, use the use_vc option to build lyx.
You may need to use extra_inc_path etc to point to zlib paths.
* you can use the msvs_projects target to obtain msvc project files
for each lyx component.
- go to development/scons (important)
- run
> scons [other options] msvs_projects
Note that
- The resulting project files will use scons to build lyx
- All command line options, including rebuild, can be used as usual
(when msvs invoke scons).
- To use the msvc debugger, you have to use mode=debug (default).
6. Tips and hints
=================
* Using external boost libraries (install boost libraries and use
option boost=system) can speed up scons' starting time a lot, since
the boost headers will then be considered as system headers and will
not be included in the dependency tree.
7. Troubleshooting
==================
When you get an error:
Q. Some path is not found.
A, Try options such as extra_inc_path, extra_lib_path.
Q. A test fails (failed to find zlib etc).
A. Have a look at config.log.
Q. I get a linking error.
A. Get the command sequence from scons_lyx.log and see what could
have gone wrong. You usually only need to tweak the last linking
command.
Q. Still can not figure it out.
A. Send an email to lyx-devel mailing list.
Q. Feeling too impatient/adventurous to wait for list response.
A. Read SConstruct and SConscript and see what went wrong. Trust me, they
are much easier to decipher than the autoconf/m4 files.

View File

@ -20,7 +20,7 @@ SUBDIRS = config development intl po $(BOOST) src sourcedoc lib \
EXTRA_DIST = ANNOUNCE INSTALL.autoconf RELEASE-NOTES UPGRADING \
INSTALL.Win32 INSTALL.MacOSX INSTALL.scons INSTALL.cmake \
INSTALL.Win32 INSTALL.MacOSX INSTALL.cmake \
README.Win32 README.Cygwin README.localization lyx.1in \
autogen.sh

View File

@ -15,27 +15,13 @@ To build lyx, you will need to install the following cygwin packages
gcc gettext-devel libQtCore4 pkg-config
gcc4 libintl8 libQtCore4-devel python
Two building systems can be used to build lyx on cygwin: the traditional
autotools (autoconf, automake, make etc), and a scons build system.
The former is the preferred method and it does not differ from building lyx
on any typical posix system, so you are referred to the INSTALL file.
Currently only the traditional autotools (autoconf, automake, make etc)
build system is recommended to build LyX on cygwin. It does not differ
from building lyx on any typical posix system, so you are referred to the
INSTALL file.
Note that it is not advisable using the cmake build system on cygwin for
the reasons explained here: http://www.cmake.org/Bug/view.php?id=10122
If you prefer using scons, you will have to install it separately, as it
is not available as a cygwin package, and then build lyx with the command
> python scons.py -f development/scons/SConstruct mode=release install
Optionally, you can install to a DESTDIR using a command similar to
> python scons.py -f development/scons/SConstruct mode=release DESTDIR=./test install
For more details about the use of scons, please refer to INSTALL.scons.
However, be aware that scons is not fully supported on cygwin and you may
be missing some features (reverse dvi/pdf search, for example) and some
cygwin-specific ancillary programs that you get when building with autotools.
When lyx is built as outlined above, it will be a X-Window application,
so you will need a X-server for running it. It is possible to build lyx
as a cygwin application but using the native Windows GDI backend instead

View File

@ -127,10 +127,6 @@ Win32/packaging/AltInstaller/specials/PDFViewWin/PDFViewWin.res \
Win32/packaging/AltInstaller/specials/AspellRepositories.txt \
Win32/packaging/AltInstaller/specials/AspellDictionaryNames.txt \
Win32/pdfview/pdfview.nsi \
scons/qt4.py \
scons/scons_manifest.py \
scons/SConstruct \
scons/scons_utils.py \
Win32/packaging/installer/lyx.nsi.cmake \
Win32/packaging/installer/settings.nsh.cmake \
Win32/vld/cmake/CMakeLists.txt \

View File

@ -1,5 +1,5 @@
# this script compiles the three different installer variants at once
# this is necessary when the installer should e.g. be built by SCons or CMake
# this is necessary when the installer should e.g. be built by CMake
SetCompressor /SOLID lzma

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
call scons install prefix=..\..\build-msvc use_vc=yes spell=hunspell frontend=qt4 mode=release version_suffix=21 gettext=system nls=yes extra_inc_path=..\..\lyx-windows-deps-msvc2010\include extra_lib_path=..\..\lyx-windows-deps-msvc2010\lib extra_bin_path=..\..\lyx-windows-deps-msvc2010\bin qt_dir=..\..\..\..\Qt

View File

@ -1,2 +0,0 @@
call scons install prefix=..\..\build-msvc use_vc=yes frontend=qt4 mode=debug version_suffix=20 gettext=system nls=yes extra_inc_path=..\..\lyx-windows-deps-msvc2008\include extra_lib_path=..\..\lyx-windows-deps-msvc2008\lib extra_bin_path=..\..\lyx-windows-deps-msvc2008\bin qt_dir=..\..\lyx-windows-deps-msvc2008\qt-4
call scons msvs_projects

View File

@ -1,373 +0,0 @@
import re
import os.path
import SCons.Defaults
import SCons.Tool
import SCons.Util
class ToolQtWarning(SCons.Warnings.Warning):
pass
class GeneratedMocFileNotIncluded(ToolQtWarning):
pass
class QtdirNotFound(ToolQtWarning):
pass
SCons.Warnings.enableWarningClass(ToolQtWarning)
qrcinclude_re = re.compile(r'<file>([^<]*)</file>', re.M)
header_extensions = [".h", ".hxx", ".hpp", ".hh"]
if SCons.Util.case_sensitive_suffixes('.h', '.H'):
header_extensions.append('.H')
#cplusplus = __import__('c++', globals(), locals(), ['Scons.Tools'])
#cxx_suffixes = cplusplus.CXXSuffixes
cxx_suffixes = [".C", ".c", ".cxx", ".cpp", ".cc"]
def _checkMocIncluded(target, source, env):
moc = target[0]
cpp = source[0]
# looks like cpp.includes is cleared before the build stage :-(
# not really sure about the path transformations (moc.cwd? cpp.cwd?) :-/
path = SCons.Defaults.CScan.path_function(env, moc.cwd)
includes = SCons.Defaults.CScan(cpp, env, path)
if not moc in includes:
SCons.Warnings.warn(
GeneratedMocFileNotIncluded,
"Generated moc file '%s' is not included by '%s'" %
(str(moc), str(cpp)))
def _find_file(filename, paths, node_factory):
retval = None
for dir in paths:
node = node_factory(filename, dir)
if node.rexists():
return node
return None
class _Automoc:
"""
Callable class, which works as an emitter for Programs, SharedLibraries and
StaticLibraries.
"""
def __init__(self, objBuilderName):
self.objBuilderName = objBuilderName
def __call__(self, target, source, env):
"""
Smart autoscan function. Gets the list of objects for the Program
or Lib. Adds objects and builders for the special qt files.
"""
try:
if int(env.subst('$QT_AUTOSCAN')) == 0:
return target, source
except ValueError:
pass
try:
debug = int(env.subst('$QT_DEBUG'))
except ValueError:
debug = 0
# some shortcuts used in the scanner
FS = SCons.Node.FS.default_fs
splitext = SCons.Util.splitext
objBuilder = getattr(env, self.objBuilderName)
# some regular expressions:
# Q_OBJECT detection
q_object_search = re.compile(r'[^A-Za-z0-9]Q_OBJECT[^A-Za-z0-9]')
# cxx and c comment 'eater'
#comment = re.compile(r'(//.*)|(/\*(([^*])|(\*[^/]))*\*/)')
# CW: something must be wrong with the regexp. See also bug #998222
# CURRENTLY THERE IS NO TEST CASE FOR THAT
# The following is kind of hacky to get builders working properly (FIXME)
objBuilderEnv = objBuilder.env
objBuilder.env = env
mocBuilderEnv = env.Moc4.env
env.Moc4.env = env
# make a deep copy for the result; MocH objects will be appended
out_sources = source[:]
for obj in source:
if not obj.has_builder():
# binary obj file provided
if debug:
print "scons: qt: '%s' seems to be a binary. Discarded." % str(obj)
continue
cpp = obj.sources[0]
if not splitext(str(cpp))[1] in cxx_suffixes:
if debug:
print "scons: qt: '%s' is no cxx file. Discarded." % str(cpp)
# c or fortran source
continue
#cpp_contents = comment.sub('', cpp.get_contents())
cpp_contents = cpp.get_contents()
h=None
for h_ext in header_extensions:
# try to find the header file in the corresponding source
# directory
hname = splitext(cpp.name)[0] + h_ext
h = _find_file(hname,
(cpp.get_dir(),),
FS.File)
if h:
if debug:
print "scons: qt: Scanning '%s' (header of '%s')" % (str(h), str(cpp))
#h_contents = comment.sub('', h.get_contents())
h_contents = h.get_contents()
break
if not h and debug:
print "scons: qt: no header for '%s'." % (str(cpp))
if h and q_object_search.search(h_contents):
# h file with the Q_OBJECT macro found -> add moc_cpp
moc_cpp = env.Moc4(h)
moc_o = objBuilder(moc_cpp)
out_sources.append(moc_o)
#moc_cpp.target_scanner = SCons.Defaults.CScan
if debug:
print "scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(h), str(moc_cpp))
if cpp and q_object_search.search(cpp_contents):
# cpp file with Q_OBJECT macro found -> add moc
# (to be included in cpp)
moc = env.Moc4(cpp)
env.Ignore(moc, moc)
if debug:
print "scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(cpp), str(moc))
#moc.source_scanner = SCons.Defaults.CScan
# restore the original env attributes (FIXME)
objBuilder.env = objBuilderEnv
env.Moc4.env = mocBuilderEnv
return (target, out_sources)
AutomocShared = _Automoc('SharedObject')
AutomocStatic = _Automoc('StaticObject')
def _detect(env):
"""Not really safe, but fast method to detect the QT library"""
QTDIR = env.get('QTDIR',None)
if QTDIR!=None : return QTDIR
QTDIR = os.environ.get('QTDIR',None)
if QTDIR!=None : return QTDIR
moc = env.WhereIs('moc-qt4') or env.WhereIs('moc')
if moc:
SCons.Warnings.warn(
QtdirNotFound,
"QTDIR variable is not defined, using moc executable as a hint (QTDIR=%s)" % QTDIR)
return os.path.dirname(os.path.dirname(moc))
SCons.Warnings.warn(
QtdirNotFound,
"Could not detect qt, using empty QTDIR")
return None
def generate(env):
"""Add Builders and construction variables for qt to an Environment."""
print "Loading qt4 tool..."
def locateQt4Command(env, command, qtdir) :
fullpath1 = os.path.join(qtdir,'bin',command +'-qt4')
if os.access(fullpath1, os.X_OK) or \
os.access(fullpath1+".exe", os.X_OK):
return fullpath1
fullpath2 = os.path.join(qtdir,'bin',command)
if os.access(fullpath2, os.X_OK) or \
os.access(fullpath2+".exe", os.X_OK):
return fullpath2
fullpath = env.Detect([command+'-qt4', command])
if not (fullpath is None) : return fullpath
raise "Qt4 command '" + command + "' not found. Tried: " + fullpath1 + " and "+ fullpath2
CLVar = SCons.Util.CLVar
Action = SCons.Action.Action
Builder = SCons.Builder.Builder
splitext = SCons.Util.splitext
# the basics
env['QTDIR'] = _detect(env)
env['QT4_MOC'] = locateQt4Command(env,'moc', env['QTDIR'])
env['QT4_UIC'] = locateQt4Command(env,'uic', env['QTDIR'])
env['QT4_RCC'] = locateQt4Command(env,'rcc', env['QTDIR'])
env['QT4_LUPDATE'] = locateQt4Command(env,'lupdate', env['QTDIR'])
env['QT4_LRELEASE'] = locateQt4Command(env,'lrelease', env['QTDIR'])
# Should the qt tool try to figure out, which sources are to be moc'ed ?
env['QT4_AUTOSCAN'] = 1
# Some QT specific flags. I don't expect someone wants to
# manipulate those ...
env['QT4_UICDECLFLAGS'] = CLVar('')
env['QT4_MOCFROMHFLAGS'] = CLVar('')
env['QT4_MOCFROMCXXFLAGS'] = CLVar('-i')
env['QT4_QRCFLAGS'] = '-name Resources'
# suffixes/prefixes for the headers / sources to generate
env['QT4_MOCHPREFIX'] = ''
env['QT4_MOCHSUFFIX'] = '$CXXFILESUFFIX'
env['QT4_MOCCXXPREFIX'] = 'moc_'
env['QT4_MOCCXXSUFFIX'] = '.moc'
env['QT4_UISUFFIX'] = '.ui'
env['QT4_UICDECLPREFIX'] = 'ui_'
env['QT4_UICDECLSUFFIX'] = '.h'
env['QT4_QRCSUFFIX'] = '.qrc',
env['QT4_QRCCXXSUFFIX'] = '$CXXFILESUFFIX'
env['QT4_QRCCXXPREFIX'] = 'qrc_'
env['QT4_LIB'] = '' # KLUDGE to avoid linking qt3 library
# Translation builder
tsbuilder = Builder(
action ='$QT4_LUPDATE $SOURCES -ts $TARGETS',
multi=1
)
env.Append( BUILDERS = { 'Ts': tsbuilder } )
qmbuilder = Builder(
action =[
'$QT4_LRELEASE $SOURCE',
],
src_suffix = '.ts',
suffix = '.qm',
single_source = True
)
env.Append( BUILDERS = { 'Qm': qmbuilder } )
# Resource builder
def scanResources(node, env, path, arg):
contents = node.get_contents()
includes = qrcinclude_re.findall(contents)
return includes
qrcscanner = env.Scanner(name = 'qrcfile',
function = scanResources,
argument = None,
skeys = ['.qrc'])
qrcbuilder = Builder(
action ='$QT4_RCC $QT4_QRCFLAGS $SOURCE -o $TARGET',
source_scanner = qrcscanner,
src_suffix = '$QT4_QRCSUFFIX',
suffix = '$QT4_QRCCXXSUFFIX',
prefix = '$QT4_QRCCXXPREFIX',
single_source = True
)
env.Append( BUILDERS = { 'Qrc': qrcbuilder } )
# Interface builder
#env['QT4_UIC4COM'] = [
# CLVar('$QT4_UIC $QT4_UICDECLFLAGS -o ${TARGETS[0]} $SOURCE'),
# ]
env['QT4_UIC4COM'] = '$QT4_UIC $QT4_UICDECLFLAGS -o $TARGET $SOURCE'
uic4builder = Builder(
action='$QT4_UIC4COM',
src_suffix='$QT4_UISUFFIX',
suffix='$QT4_UICDECLSUFFIX',
prefix='$QT4_UICDECLPREFIX',
single_source = True
)
env.Append( BUILDERS = { 'Uic4': uic4builder } )
# Metaobject builder
env['QT4_MOCFROMHCOM'] = (
'$QT4_MOC $QT4_MOCFROMHFLAGS -o ${TARGETS[0]} $SOURCE')
env['QT4_MOCFROMCXXCOM'] = [
CLVar('$QT4_MOC $QT4_MOCFROMCXXFLAGS -o ${TARGETS[0]} $SOURCE'),
Action(_checkMocIncluded,None)]
mocBld = Builder(action={}, prefix={}, suffix={})
for h in header_extensions:
mocBld.add_action(h, '$QT4_MOCFROMHCOM')
mocBld.prefix[h] = '$QT4_MOCHPREFIX'
mocBld.suffix[h] = '$QT4_MOCHSUFFIX'
for cxx in cxx_suffixes:
mocBld.add_action(cxx, '$QT4_MOCFROMCXXCOM')
mocBld.prefix[cxx] = '$QT4_MOCCXXPREFIX'
mocBld.suffix[cxx] = '$QT4_MOCCXXSUFFIX'
env.Append( BUILDERS = { 'Moc4': mocBld } )
# er... no idea what that was for
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
static_obj.src_builder.append('Uic4')
shared_obj.src_builder.append('Uic4')
# We use the emitters of Program / StaticLibrary / SharedLibrary
# to scan for moc'able files
# We can't refer to the builders directly, we have to fetch them
# as Environment attributes because that sets them up to be called
# correctly later by our emitter.
env.AppendUnique(PROGEMITTER =[AutomocStatic],
SHLIBEMITTER=[AutomocShared],
LIBEMITTER =[AutomocStatic],
# Of course, we need to link against the qt libraries
CPPPATH=[os.path.join('$QTDIR', 'include')],
LIBPATH=[os.path.join('$QTDIR', 'lib')],
LIBS=['$QT4_LIB'])
import new
method = new.instancemethod(enable_modules, env, SCons.Environment)
env.EnableQt4Modules=method
def enable_modules(self, modules, debug=False) :
import sys
validModules = [
'QtCore',
'QtGui',
'QtOpenGL',
'Qt3Support',
# The next modules have not been tested yet so, please
# maybe they require additional work on non Linux platforms
'QtSql',
'QtNetwork',
'QtSvg',
'QtTest',
'QtXml',
'QtUiTools',
]
pclessModules = [
'QtUiTools',
'QtUiTools_debug',
]
invalidModules=[]
for module in modules:
if module not in validModules :
invalidModules.append(module)
if invalidModules :
raise "Modules %s are not Qt4 modules. Valid Qt4 modules are: %s"% \
(str(invalidModules),str(validModules))
# TODO: Check whether we should add QT_CORE_LIB, QT_XML_LIB, QT_NETWORK_LIB...
if 'QtGui' in modules:
self.AppendUnique(CPPFLAGS='-DQT_GUI_LIB')
if sys.platform == "linux2" :
if debug : modules = [module+"_debug" for module in modules]
for module in modules :
if module in pclessModules :
# self.AppendUnique(LIBS=[module])
self.AppendUnique(LIBPATH=[os.path.join(self["QTDIR"],"lib",module)])
self.AppendUnique(CPPPATH=[os.path.join(self["QTDIR"],"include","qt4",module)])
modules.remove(module)
self.ParseConfig('PKG_CONFIG_PATH=%s/lib:%s/lib/pkgconfig pkg-config %s --libs --cflags'%
(
self['QTDIR'], self['QTDIR'],
' '.join(modules)))
return
if sys.platform == "win32" :
if debug : debugSuffix = 'd'
else : debugSuffix = ''
self.AppendUnique(LIBS=[lib+'4'+debugSuffix for lib in modules])
if 'QtOpenGL' in modules:
self.AppendUnique(LIBS=['opengl32'])
self.AppendUnique(CPPPATH=[ '$QTDIR/include/'+module
for module in modules])
self.AppendUnique(LIBPATH=['$QTDIR/lib'])
def exists(env):
return _detect(env)

File diff suppressed because it is too large Load Diff

View File

@ -1,909 +0,0 @@
# vi:filetype=python:expandtab:tabstop=4:shiftwidth=4
#
# file scons_utils.py
#
# This file is part of LyX, the document processor.
# Licence details can be found in the file COPYING.
#
# \author Bo Peng
# Full author contact details are available in file CREDITS.
#
# This file defines all the utility functions for the
# scons-based build system of lyx
#
import os, sys, re, shutil, glob
from SCons.Util import *
def getVerFromConfigure(path):
''' get lyx version from the AC_INIT line of configure.ac,
packed major and minor version numbers from the lyx version,
and LYX_DATE from an AC_SUBST line.
'''
try:
config = open(os.path.join(path, 'configure.ac'))
except:
print "Can not open configure.ac. "
return 'x.x.x'
# find a line like follows
# AC_INIT(LyX,1.4.4svn,[lyx-devel@lists.lyx.org],[lyx])
ver_pat = re.compile('AC_INIT\([^,]+,([^,]+),')
date_pat = re.compile('AC_SUBST\(LYX_DATE, \["(.*)"\]\)')
majmin_pat = re.compile('(\d+)\.(\d+)\..*')
version = 'x.x.x'
majmin = 'xx'
date = 'Not released'
for line in config.readlines():
if ver_pat.match(line):
(version,) = ver_pat.match(line).groups()
majmin_match = majmin_pat.match(version)
majmin = majmin_match.group(1) + majmin_match.group(2)
if date_pat.match(line):
(date,) = date_pat.match(line).groups()
if version != 'x.x.x' and date != 'Not released':
break
return version.strip(), majmin.strip(), date.strip()
def relativePath(path, base):
'''return relative path from base, which is usually top source dir'''
# full pathname of path
path1 = os.path.normpath(os.path.realpath(path)).split(os.sep)
path2 = os.path.normpath(os.path.realpath(base)).split(os.sep)
if path1[:len(path2)] != path2:
print "Path %s is not under top source directory" % path
if len(path2) == len(path1):
return ''
path3 = os.path.join(*path1[len(path2):]);
# replace all \ by / such that we get the same comments on Windows and *nix
path3 = path3.replace('\\', '/')
return path3
def isSubDir(path, base):
'''Whether or not path is a subdirectory of base'''
path1 = os.path.normpath(os.path.realpath(path)).split(os.sep)
path2 = os.path.normpath(os.path.realpath(base)).split(os.sep)
return len(path2) <= len(path1) and path1[:len(path2)] == path2
def writeToFile(filename, lines, append = False):
" utility function: write or append lines to filename "
# create directory if needed
dir = os.path.split(filename)[0]
if dir != '' and not os.path.isdir(dir):
os.makedirs(dir)
if append:
file = open(filename, 'a')
else:
file = open(filename, 'w')
file.write(lines)
file.close()
def env_subst(target, source, env):
''' subst variables in source by those in env, and output to target
source and target are scons File() objects
%key% (not key itself) is an indication of substitution
'''
assert len(target) == 1
assert len(source) == 1
target_file = file(str(target[0]), "w")
source_file = file(str(source[0]), "r")
contents = source_file.read()
for k, v in env.items():
try:
val = env.subst('$'+k)
# temporary fix for the \Resource backslash problem
val = val.replace('\\', '/')
# multi-line replacement
val = val.replace('\n',r'\\n\\\n')
contents = re.sub('@'+k+'@', val, contents)
except:
pass
target_file.write(contents + "\n")
target_file.close()
#st = os.stat(str(source[0]))
#os.chmod(str(target[0]), stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
def env_nsis(source, target, env, for_signature):
''' Get nsis command line '''
def quoteIfSpaced(str):
if ' ' in str:
return '"' + str + '"'
else:
return str
ret = env['NSIS'] + " /V1 "
if env.has_key('NSISFLAGS'):
for flag in env['NSISFLAGS']:
ret += flag
ret += ' '
if env.has_key('NSISDEFINES'):
for d in env['NSISDEFINES']:
ret += '/D'+d
if env['NSISDEFINES'][d]:
ret += '=' + quoteIfSpaced(env['NSISDEFINES'][d])
ret += ' '
# bundled?
if '-bundle.exe' in str(target[0]):
ret += '/DSETUPTYPE=BUNDLE '
for s in source:
ret += quoteIfSpaced(str(s))
return ret
def env_toc(target, source, env):
'''Generate target from source files'''
# this is very tricky because we need to use installed lyx2lyx with
# correct lyx2lyx_version.py
sys.path.append(env['LYX2LYX_DEST'])
sys.path.append(env.Dir('$TOP_SRCDIR/lib/doc').abspath)
import doc_toc
# build toc
doc_toc.build_toc(str(target[0]), [file.abspath for file in source])
def env_cat(target, source, env):
'''Cat source > target. Avoid pipe to increase portability'''
output = open(env.File(target[0]).abspath, 'w')
for src in source:
input = open(env.File(src).abspath)
output.write(input.read())
input.close()
output.close()
def env_potfiles(target, source, env):
'''Build po/POTFILES.in'''
# command
# grep -l '_(\".*\")' `find src \( -name '*.h' -o -name '*.cpp' -o -name '*.cpp.in' \) -print` | grep -v -e "src/support/Package.cpp$$" | sort | uniq
# is used under *nix but windows users have to do these all in python
target_file = open(str(target[0]), "w")
potfiles = []
trans = re.compile('_\(".*"\)', re.M)
for file in source:
rel_file = relativePath(str(file), env.subst('$TOP_SRCDIR'))
if rel_file not in potfiles and trans.search(open(str(file)).read()):
potfiles.append(rel_file)
potfiles.sort()
print >> target_file, '\n'.join(potfiles)
target_file.close()
def createResFromIcon(env, icon_file, rc_file):
''' create a rc file with icon, and return res file (windows only) '''
if os.name == 'nt':
rc_name = env.File(rc_file).abspath
dir = os.path.split(rc_name)[0]
if not os.path.isdir(dir):
os.makedirs(dir)
rc = open(rc_name, 'w')
print >> rc, 'IDI_ICON1 ICON DISCARDABLE "%s"' % \
os.path.join(env.Dir('$TOP_SRCDIR').abspath, 'development', 'win32',
'packaging', 'icons', icon_file).replace('\\', '\\\\')
rc.close()
return env.RES(rc_name)
else:
return []
def env_qtResource(target, source, env):
'''Create resource.qrc'''
qrc = open(str(target[0]), 'w')
print >> qrc, "<!DOCTYPE RCC><RCC version='1.0'><qresource>"
for file in source:
rel_file = relativePath(str(file), env.subst('$TOP_SRCDIR/lib'))
abs_file = str(file.abspath)
print >> qrc, '<file alias="%s">%s</file>' % (rel_file, abs_file)
print >> qrc, '</qresource></RCC>'
qrc.close()
#
# autoconf tests
#
def checkPkgConfig(conf, version):
''' Return false if pkg_config does not exist, or is too old '''
conf.Message('Checking for pkg-config...')
ret = conf.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0]
conf.Result(ret)
return ret
def checkPackage(conf, pkg):
''' check if pkg is under the control of conf '''
conf.Message('Checking for package %s...' % pkg)
ret = conf.TryAction("pkg-config --print-errors --exists %s" % pkg)[0]
conf.Result(ret)
return ret
def checkMkdirOneArg(conf):
check_mkdir_one_arg_source = """
#include <sys/stat.h>
int main()
{
mkdir("somedir");
}
"""
conf.Message('Checking for the number of args for mkdir... ')
ret = conf.TryLink(check_mkdir_one_arg_source, '.c') or \
conf.TryLink('#include <unistd.h>' + check_mkdir_one_arg_source, '.c') or \
conf.TryLink('#include <direct.h>' + check_mkdir_one_arg_source, '.c')
if ret:
conf.Result('one')
else:
conf.Result('two')
return ret
def checkCXXGlobalCstd(conf):
''' Checking the use of std::tolower or tolower '''
check_global_cstd_source = '''
#include <cctype>
using std::tolower;
int main()
{
return 0;
}
'''
conf.Message('Checking for the use of global cstd... ')
# if can not compile, define CXX_GLOBAL_CSTD
ret = conf.TryLink(check_global_cstd_source, '.cpp')
conf.Result(ret)
return ret
def checkSelectArgType(conf):
''' Adapted from autoconf '''
conf.Message('Checking for arg types for select... ')
for arg234 in ['fd_set *', 'int *', 'void *']:
for arg1 in ['int', 'size_t', 'unsigned long', 'unsigned']:
for arg5 in ['struct timeval *', 'const struct timeval *']:
check_select_source = '''
#if HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
#if HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
extern int select (%s, %s, %s, %s, %s);
int main()
{
return(0);
}
''' % (arg1, arg234, arg234, arg234, arg5)
ret = conf.TryLink(check_select_source, '.c')
if ret:
conf.Result(ret)
return (arg1, arg234, arg5)
conf.Result('no (use default)')
return ('int', 'int *', 'struct timeval *')
def checkBoostLibraries(conf, libs, lib_paths, inc_paths, versions, isDebug):
''' look for boost libraries
libs: library names
lib_paths: try these paths for boost libraries
inc_paths: try these paths for boost headers
versions: supported boost versions
isDebug: if true, use debug libraries
'''
conf.Message('Checking for boost library %s... ' % ', '.join(libs))
libprefix = conf.env['LIBPREFIX']
libsuffix = '(%s|%s)' % (conf.env['LIBSUFFIX'], conf.env['SHLIBSUFFIX'])
found_lib = False
found_inc = False
lib_names = []
lib_path = None
inc_path = None
for path in lib_paths:
conf.Log("Looking into %s\n" % path)
for lib in libs:
# get all the libs, then filter for the right library
files = glob.glob(os.path.join(path, '%sboost_%s-*.*' % (libprefix, lib)))
# check things like libboost_iostreams-gcc-mt-d-1_33_1.a
if len(files) > 0:
conf.Log("Find boost libraries: %s\n" % files)
# runtime code includes s,g,y,d,p,n, where we should look for
# d,g,y for debug, s,p,n for release
lib_files = []
if isDebug:
for ver in versions:
lib_files += filter(lambda x: re.search('%sboost_%s-\w+-mt-[^spn]+-%s%s' % (libprefix, lib, ver, libsuffix), x), files)
else:
for ver in versions:
lib_files += filter(lambda x: re.search('%sboost_%s-\w+-mt-([^dgy]+-)*%s%s' % (libprefix, lib, ver, libsuffix), x), files)
if len(lib_files) == 0:
# use alternative libraries
for ver in versions:
lib_files += filter(lambda x: re.search('%sboost_%s-[\w-]+%s%s' % (libprefix, lib, ver, libsuffix), x), files)
if len(lib_files) > 0:
# get xxx-gcc-1_33_1 from /usr/local/lib/libboost_xxx-gcc-1_33_1.a
name = lib_files[0].split(os.sep)[-1][len(libprefix):]
lib_names.append(name.split('.')[0])
conf.Log("Qualified libraries: %s\n" % lib_names)
else:
conf.Log("No qualified library is found.\n")
break
if len(lib_names) == len(libs):
found_lib = True
lib_path = path
break
if not found_lib:
if len(lib_names) == 0:
conf.Log("No boost library is found\n")
else:
conf.Log("Found boost libraries: %s\n" % lib_names)
conf.Result('no')
return (None, None, None)
# check version number in boost/version.hpp
def isValidBoostDir(dir):
version_file = os.path.join(dir, 'boost', 'version.hpp')
if not os.path.isfile(version_file):
return False
version_file_content = open(version_file).read()
version_strings = ['#define BOOST_LIB_VERSION "%s"' % ver for ver in versions]
return True in [x in version_file_content for x in version_strings]
# check for boost header file
for path in inc_paths:
conf.Log("Checking for inc path: %s\n" % path)
if isValidBoostDir(path):
inc_path = path
found_inc = True
else: # check path/boost_1_xx_x/boost
dirs = glob.glob(os.path.join(path, 'boost-*'))
if len(dirs) > 0 and isValidBoostDir(dirs[0]):
conf.Log("Checing for sub directory: %s\n" % dirs[0])
inc_path = dirs[0]
found_inc = True
# return result
if found_inc:
conf.Result('yes')
conf.Log('Using boost libraries %s\n' % (', '.join(lib_names)))
return (lib_names, lib_path, inc_path)
else:
conf.Result('no')
return (None, None, None)
def checkCommand(conf, cmd):
''' check the existence of a command
return full path to the command, or none
'''
conf.Message('Checking for command %s...' % cmd)
res = WhereIs(cmd)
conf.Result(res is not None)
return res
def checkNSIS(conf):
''' check the existence of nsis compiler, return the fullpath '''
conf.Message('Checking for nsis compiler...')
res = None
if can_read_reg:
# If we can read the registry, get the NSIS command from it
try:
k = RegOpenKeyEx(hkey_mod.HKEY_LOCAL_MACHINE,
'SOFTWARE\\NSIS')
val, tok = RegQueryValueEx(k,None)
ret = val + os.path.sep + 'makensis.exe'
if os.path.isfile(ret):
res = '"' + ret + '"'
else:
res = None
except:
pass # Couldn't find the key, just act like we can't read the registry
# Hope it's on the path
if res is None:
res = WhereIs('makensis.exe')
conf.Result(res is not None)
return res
def checkLC_MESSAGES(conf):
''' check the definition of LC_MESSAGES '''
check_LC_MESSAGES = '''
#include <locale.h>
int main()
{
return LC_MESSAGES;
}
'''
conf.Message('Checking for LC_MESSAGES in locale.h... ')
ret = conf.TryLink(check_LC_MESSAGES, '.c')
conf.Result(ret)
return ret
def checkIconvConst(conf):
''' check the declaration of iconv '''
check_iconv_const = '''
#include <iconv.h>
// this declaration will fail when there already exists a non const char**
// version which returns size_t
double iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
int main() {
return 0;
}
'''
conf.Message('Checking if the declaration of iconv needs const... ')
ret = conf.TryLink(check_iconv_const, '.cpp')
conf.Result(ret)
return ret
def checkSizeOfWChar(conf):
''' check the size of wchar '''
check_sizeof_wchar = '''
#include <wchar.h>
int i[ ( sizeof(wchar_t)==%d ? 1 : -1 ) ];
int main()
{
return 0;
}
'''
conf.Message('Checking the size of wchar_t... ')
if conf.TryLink(check_sizeof_wchar % 2, '.cpp'):
ret = 2
elif conf.TryLink(check_sizeof_wchar % 4, '.cpp'):
ret = 4
else:
ret = 0
conf.Result(str(ret))
return ret
def checkDeclaration(conf, func, headers):
''' check if a function is declared in given headers '''
check_decl = '''
#include <%%s>
int main()
{
#ifndef %s
char *p = (char *) %s;
#endif
}
''' % (func, func)
conf.Message('Checking for the declaration of function %s... ' % func)
ret = True in [conf.TryLink(check_decl % header, '.c') for header in headers]
conf.Result(ret)
return ret
def createConfigFile(conf, config_file,
config_pre = '', config_post = '',
headers = [], functions = [], declarations = [], types = [], libs = [],
custom_tests = [], extra_items = []):
''' create a configuration file, with options
config_file: which file to create
config_pre: first part of the config file
config_post: last part of the config file
headers: header files to check, in the form of a list of
('file', 'HAVE_FILE', 'c'/'c++')
functions: functions to check, in the form of a list of
('func', 'HAVE_func', 'include lines'/None)
declarations: function declarations to check, in the form of a list of
('func', 'HAVE_DECL_func', header_files)
types: types to check, in the form of a list of
('type', 'HAVE_TYPE', 'includelines'/None)
libs: libraries to check, in the form of a list of
('lib', 'HAVE_LIB', 'LIB_NAME'). HAVE_LIB will be set if 'lib' exists,
or any of the libs exists if 'lib' is a list of libs.
Optionally, user can provide another key LIB_NAME, that will
be set to the detected lib (or None otherwise).
custom_tests: extra tests to perform, in the form of a list of
(test (True/False), 'key', 'desc', 'true config line', 'false config line')
If the last two are ignored, '#define key 1' '/*#undef key */'
will be used.
extra_items: extra configuration lines, in the form of a list of
('config', 'description')
Return:
The result of each test, as a dictioanry of
res['XXX'] = True/False
XXX are keys defined in each argument.
'''
cont = config_pre + '\n'
result = {}
# add to this string, in appropriate format
def configString(lines, desc=''):
text = ''
if lines.strip() != '':
if desc != '':
text += '/* ' + desc + ' */\n'
text += lines + '\n\n'
return text
#
# headers
for header in headers:
description = "Define to 1 if you have the <%s> header file." % header[0]
if (header[2] == 'c' and conf.CheckCHeader(header[0])) or \
(header[2] == 'cxx' and conf.CheckCXXHeader(header[0])):
result[header[1]] = 1
cont += configString('#define %s 1' % header[1], desc = description)
else:
result[header[1]] = 0
cont += configString('/* #undef %s */' % header[1], desc = description)
# functions
for func in functions:
description = "Define to 1 if you have the `%s' function." % func[0]
if conf.CheckFunc(func[0], header=func[2]):
result[func[1]] = 1
cont += configString('#define %s 1' % func[1], desc = description)
else:
result[func[1]] = 0
cont += configString('/* #undef %s */' % func[1], desc = description)
for decl in declarations:
description = "Define to 1 if you have the declaration of `%s', and to 0 if you don't." % decl[0]
if conf.CheckDeclaration(decl[0], decl[2]):
result[decl[1]] = 1
cont += configString('#define %s 1' % decl[1], desc = description)
else:
result[decl[1]] = 0
cont += configString('/* #undef %s */' % decl[1], desc = description)
# types
for t in types:
description = "Define to 1 if you have the `%s' type." % t[0]
if conf.CheckType(t[0], includes=t[2]):
result[t[1]] = 1
cont += configString('#define %s 1' % t[1], desc = description)
else:
result[t[1]] = 0
cont += configString('/* #undef %s */' % t[1], desc = description)
# libraries
for lib in libs:
description = "Define to 1 if you have the `%s' library (-l%s)." % (lib[0], lib[0])
if type(lib[0]) is type(''):
lib_list = [lib[0]]
else:
lib_list = lib[0]
# check if any of the lib exists
result[lib[1]] = 0
# if user want the name of the lib detected
if len(lib) == 3:
result[lib[2]] = None
for ll in lib_list:
if conf.CheckLib(ll):
result[lib[1]] = 1
if len(lib) == 3:
result[lib[2]] = ll
cont += configString('#define %s 1' % lib[1], desc = description)
break
# if not found
if not result[lib[1]]:
cont += configString('/* #undef %s */' % lib[1], desc = description)
# custom tests
for test in custom_tests:
if test[0]:
result[test[1]] = 1
if len(test) == 3:
cont += configString('#define %s 1' % test[1], desc = test[2])
else:
cont += configString(test[3], desc = test[2])
else:
result[test[1]] = 0
if len(test) == 3:
cont += configString('/* #undef %s */' % test[1], desc = test[2])
else:
cont += configString(test[4], desc = test[2])
# extra items (no key is returned)
for item in extra_items:
cont += configString(item[0], desc = item[1])
# add the last part
cont += '\n' + config_post + '\n'
# write to file
writeToFile(config_file, cont)
return result
def installCygwinLDScript(path):
''' Install i386pe.x-no-rdata '''
ld_script = os.path.join(path, 'i386pe.x-no-rdata')
script = open(ld_script, 'w')
script.write('''/* specific linker script avoiding .rdata sections, for normal executables
for a reference see
http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html
http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html
*/
OUTPUT_FORMAT(pei-i386)
SEARCH_DIR("/usr/i686-pc-cygwin/lib"); SEARCH_DIR("/usr/lib"); SEARCH_DIR("/usr/lib/w32api");
ENTRY(_mainCRTStartup)
SECTIONS
{
.text __image_base__ + __section_alignment__ :
{
*(.init)
*(.text)
*(SORT(.text$*))
*(.glue_7t)
*(.glue_7)
___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
LONG (-1);*(.ctors); *(.ctor); *(SORT(.ctors.*)); LONG (0);
___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
LONG (-1); *(.dtors); *(.dtor); *(SORT(.dtors.*)); LONG (0);
*(.fini)
/* ??? Why is .gcc_exc here? */
*(.gcc_exc)
PROVIDE (etext = .);
*(.gcc_except_table)
}
/* The Cygwin32 library uses a section to avoid copying certain data
on fork. This used to be named ".data". The linker used
to include this between __data_start__ and __data_end__, but that
breaks building the cygwin32 dll. Instead, we name the section
".data_cygwin_nocopy" and explictly include it after __data_end__. */
.data BLOCK(__section_alignment__) :
{
__data_start__ = . ;
*(.data)
*(.data2)
*(SORT(.data$*))
*(.rdata)
*(SORT(.rdata$*))
*(.eh_frame)
___RUNTIME_PSEUDO_RELOC_LIST__ = .;
__RUNTIME_PSEUDO_RELOC_LIST__ = .;
*(.rdata_runtime_pseudo_reloc)
___RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
__RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
__data_end__ = . ;
*(.data_cygwin_nocopy)
}
.rdata BLOCK(__section_alignment__) :
{
}
.pdata BLOCK(__section_alignment__) :
{
*(.pdata)
}
.bss BLOCK(__section_alignment__) :
{
__bss_start__ = . ;
*(.bss)
*(COMMON)
__bss_end__ = . ;
}
.edata BLOCK(__section_alignment__) :
{
*(.edata)
}
/DISCARD/ :
{
*(.debug$S)
*(.debug$T)
*(.debug$F)
*(.drectve)
}
.idata BLOCK(__section_alignment__) :
{
/* This cannot currently be handled with grouped sections.
See pe.em:sort_sections. */
SORT(*)(.idata$2)
SORT(*)(.idata$3)
/* These zeroes mark the end of the import list. */
LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
SORT(*)(.idata$4)
SORT(*)(.idata$5)
SORT(*)(.idata$6)
SORT(*)(.idata$7)
}
.CRT BLOCK(__section_alignment__) :
{
___crt_xc_start__ = . ;
*(SORT(.CRT$XC*)) /* C initialization */
___crt_xc_end__ = . ;
___crt_xi_start__ = . ;
*(SORT(.CRT$XI*)) /* C++ initialization */
___crt_xi_end__ = . ;
___crt_xl_start__ = . ;
*(SORT(.CRT$XL*)) /* TLS callbacks */
/* ___crt_xl_end__ is defined in the TLS Directory support code */
___crt_xp_start__ = . ;
*(SORT(.CRT$XP*)) /* Pre-termination */
___crt_xp_end__ = . ;
___crt_xt_start__ = . ;
*(SORT(.CRT$XT*)) /* Termination */
___crt_xt_end__ = . ;
}
.tls BLOCK(__section_alignment__) :
{
___tls_start__ = . ;
*(.tls)
*(.tls$)
*(SORT(.tls$*))
___tls_end__ = . ;
}
.endjunk BLOCK(__section_alignment__) :
{
/* end is deprecated, don't use it */
PROVIDE (end = .);
PROVIDE ( _end = .);
__end__ = .;
}
.rsrc BLOCK(__section_alignment__) :
{
*(.rsrc)
*(SORT(.rsrc$*))
}
.reloc BLOCK(__section_alignment__) :
{
*(.reloc)
}
.stab BLOCK(__section_alignment__) (NOLOAD) :
{
*(.stab)
}
.stabstr BLOCK(__section_alignment__) (NOLOAD) :
{
*(.stabstr)
}
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section. Unlike other targets that fake this by putting the
section VMA at 0, the PE format will not allow it. */
/* DWARF 1.1 and DWARF 2. */
.debug_aranges BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_aranges)
}
.debug_pubnames BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_pubnames)
}
/* DWARF 2. */
.debug_info BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_info) *(.gnu.linkonce.wi.*)
}
.debug_abbrev BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_abbrev)
}
.debug_line BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_line)
}
.debug_frame BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_frame)
}
.debug_str BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_str)
}
.debug_loc BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_loc)
}
.debug_macinfo BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_macinfo)
}
/* SGI/MIPS DWARF 2 extensions. */
.debug_weaknames BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_weaknames)
}
.debug_funcnames BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_funcnames)
}
.debug_typenames BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_typenames)
}
.debug_varnames BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_varnames)
}
/* DWARF 3. */
.debug_ranges BLOCK(__section_alignment__) (NOLOAD) :
{
*(.debug_ranges)
}
}
''')
script.close()
return(ld_script)
def installCygwinPostinstallScript(path):
''' Install lyx.sh '''
postinstall_script = os.path.join(path, 'lyx.sh')
script = open(postinstall_script, 'w')
script.write(r'''#!/bin/sh
# Add /usr/share/lyx/fonts to /etc/fonts/local.conf
# if it is not already there.
if [ -f /etc/fonts/local.conf ]; then
grep -q /usr/share/lyx/fonts /etc/fonts/local.conf
if [ $? -ne 0 ]; then
sed 's/^<\/fontconfig>/<dir>\/usr\/share\/lyx\/fonts<\/dir>\n<\/fontconfig>/' /etc/fonts/local.conf > /etc/fonts/local.conf.tmp
mv -f /etc/fonts/local.conf.tmp /etc/fonts/local.conf
fc-cache /usr/share/lyx/fonts
fi
fi
''')
script.close()
return(postinstall_script)
try:
# these will be used under win32
import win32file
import win32event
import win32process
import win32security
except:
# does not matter if it fails on other systems
pass
class loggedSpawn:
def __init__(self, env, logfile, longarg, info):
# save the spawn system
self.env = env
self.logfile = logfile
# clear the logfile (it may not exist)
if logfile != '':
# this will overwrite existing content.
writeToFile(logfile, info, append=False)
#
self.longarg = longarg
# get hold of the old spawn? (necessary?)
self._spawn = env['SPAWN']
# define new SPAWN
def spawn(self, sh, escape, cmd, args, spawnenv):
# get command line
newargs = ' '.join(map(escape, args[1:]))
cmdline = cmd + " " + newargs
#
# if log is not empty, write to it
if self.logfile != '':
# this tend to be slow (?) but ensure correct output
# Note that cmdline may be long so I do not escape it
try:
# since this is not an essential operation, proceed if things go wrong here.
writeToFile(self.logfile, cmd + " " + ' '.join(args[1:]) + '\n', append=True)
except:
print "Warning: can not write to log file ", self.logfile
#
# if the command is not too long, use the old
if not self.longarg or len(cmdline) < 8000:
exit_code = self._spawn(sh, escape, cmd, args, spawnenv)
else:
sAttrs = win32security.SECURITY_ATTRIBUTES()
StartupInfo = win32process.STARTUPINFO()
for var in spawnenv:
spawnenv[var] = spawnenv[var].encode('ascii', 'replace')
# check for any special operating system commands
if cmd == 'del':
for arg in args[1:]:
win32file.DeleteFile(arg)
exit_code = 0
else:
# otherwise execute the command.
hProcess, hThread, dwPid, dwTid = win32process.CreateProcess(None, cmdline, None, None, 1, 0, spawnenv, None, StartupInfo)
win32event.WaitForSingleObject(hProcess, win32event.INFINITE)
exit_code = win32process.GetExitCodeProcess(hProcess)
win32file.CloseHandle(hProcess);
win32file.CloseHandle(hThread);
return exit_code
def setLoggedSpawn(env, logfile = '', longarg=False, info=''):
''' This function modify env and allow logging of
commands to a logfile. If the argument is too long
a win32 spawn will be used instead of the system one
'''
#
# create a new spwn object
ls = loggedSpawn(env, logfile, longarg, info)
# replace the old SPAWN by the new function
env['SPAWN'] = ls.spawn