Add scons build system.

* INSTALL.scons: instruction
	* development/scons/*: scons build system, qt frontend only
	* development/ChangeLog, status.14x, ChangeLog: bookkeeping


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/branches/BRANCH_1_4_X@14650 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Bo Peng 2006-08-13 16:07:17 +00:00
parent dcbfef703a
commit 2949a35176
7 changed files with 5350 additions and 0 deletions

View File

@ -1,3 +1,7 @@
2006-08-13 Bo Peng <ben.bob@gmail.com>
* INSTALL.scons: instructions of the new scons build system.
2006-07-13 Jean-Marc Lasgouttes <lasgouttes@lyx.org>
* status.14x:

351
INSTALL.scons Normal file
View File

@ -0,0 +1,351 @@
=========================
Building LyX with SCons
=========================
Aug, 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 qt frontends.
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 >= 1.5.2 is required to run scons, but Python >= 2.3 is used by
lyx itself so the newer version is needed. Python is widely
available on non-windows systems. Windows users can download and install
python from http://www.python.org.
* SCons:
scons >= 0.96.92 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), qt3 (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 qt_dir=d:/qt3 -j3 lyx
or from top source directory by:
> scons -f development/scons/SConstruct all
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=qt2: qt2 is the default, and there is no other choice
* 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/pspell/ispell/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:
* fast_start=yes/no: if true, bypass initial configuration step and use
existing src/config.h
* 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.
* 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
* dest_dir: 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.
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, qt2, lyxbase
Programs:
tex2lyx, client, lyx, all = tex2lyx + client + lyx
Installation:
po, install = all + po
Misc:
msvs_projects
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
- qt2: lyx executable built with the qt frontend
- executables: lyxclient, tex2lyx, lyx
MSVS projects will be put to development/scons (and you should invoke
scons from there for this target).
A typical working sequence:
---------------------------
> cd development/scons
> scons qt_dir=/path/to/qt3
(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_main.C, so only need to rebuild lyxbase)
> scons
(build again, only lyxbase will be rebuilt)
> scons fast_start=no --config=force
(need to regenerate src/config.h)
> scons prefix=/usr/site dest_dir=/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
=================
LyX should be easy to compile, but you must use the most recent cygwin
dll (version 1.5.20-1 as of July 2006) because the qt3 library in the
cygwin distribution does not work with previous versions due to broken
threading support.
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 qt3-bin
aspell-dev jpeg libpng qt3-devel
gcc libintl libpng2
gettext libintl1 jpeg
gettext-devel libintl2 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/qt3 uses directories
/usr/include/qt3, /usr/lib/qt3/bin and /usr/lib/qt3/lib. If these
directories can not be detected automatically, use options, for example,
qt_dir=/usr/lib/qt3 qt_inc_path=/usr/include/qt3
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 qt3
- download qt3 source from trolltech (not the binary version, which
only works with mingw)
- get q../free patch for qt3
- compile qt3 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

@ -1,3 +1,7 @@
2006-08-13 Bo Peng <ben.bob@gmail.com>
* scons/*: add scons build system
2006-08-13 Michael Gerz <michael.gerz@teststep.org>
* tools/mkdoclinks.sh:

2072
development/scons/SConstruct Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,669 @@
# 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 WhereIs
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)
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)
#
# 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):
''' Check the use of std::tolower or tolower '''
check_global_cstd_source = '''
#include <cctype>
using std::tolower;
int main()
{
return 0;
}
'''
conf.Message('Check for the use of global cstd... ')
ret = conf.TryLink(check_global_cstd_source, '.c')
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, version, isDebug):
''' look for boost libraries
libs: library names
lib_paths: try these paths for boost libraries
inc_paths: try these paths for boost headers
version: required boost version
isDebug: if true, use debug libraries
'''
conf.Message('Checking for boost library %s... ' % ', '.join(libs))
found_lib = False
found_inc = False
lib_names = []
lib_path = None
inc_path = None
for path in lib_paths:
# direct form: e.g. libboost_iostreams.a
# ignore isDebug
if False not in [os.path.isfile(os.path.join(path, 'libboost_%s.a' % lib)) for lib in libs]:
conf.Result('yes')
found_lib = True
lib_path = path
lib_names = libs
break
for lib in libs:
# get all the libs, then filter for the right library
files = glob.glob(os.path.join(path, 'libboost_%s-*.a' % lib))
# check things like libboost_iostreams-gcc-mt-d-1_33_1.a
if len(files) > 0:
# runtime code includes s,g,y,d,p,n, where we should look for
# d,g,y for debug, s,p,n for release
if isDebug:
lib_files = filter(lambda x: re.search('libboost_%s-\w+-mt-[^spn]+-%s.a' % (lib, version), x), files)
else:
lib_files = filter(lambda x: re.search('libboost_%s-\w+-mt-([^dgy]+-)*%s.a' % (lib, version), x), files)
if len(lib_files) == 0:
print 'Warning: Can not find an appropriate boost library in %s.' % path
lib_files = filter(lambda x: re.search('libboost_%s-[\w-]+%s.a' % (lib, version), x), files)
if len(lib_files) > 0:
print 'Use library %s' % lib_files[0]
if len(lib_files) > 0:
# get xxx-gcc-1_33_1 from /usr/local/lib/libboost_xxx-gcc-1_33_1.a
lib_names.append(lib_files[0].split(os.sep)[-1][3:-2])
if len(lib_names) == len(libs):
found_lib = True
lib_path = path
break
if not found_lib:
conf.Result('no')
return (None, None, None)
# check version number in boost/version.hpp
def isValidBoostDir(dir):
file = os.path.join(dir, 'boost', 'version.hpp')
version_string = '#define BOOST_LIB_VERSION "%s"' % version
return os.path.isfile(file) and version_string in open(file).read()
# check for boost header file
for path in inc_paths:
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]):
inc_path = dirs[0]
found_inc = True
# return result
if found_inc:
conf.Result('yes')
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 checkLC_MESSAGES(conf):
''' check the definition of LC_MESSAGES '''
check_LC_MESSAGES = '''
#include <locale.h>
int main()
{
return LC_MESSAGES;
}
'''
conf.Message('Check 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 <stdlib.h>
#include <iconv.h>
extern
#ifdef __cplusplus
"C"
#endif
#if defined(__STDC__) || defined(__cplusplus)
#ifndef LIBICONV_DLL_EXPORTED
size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
#endif
#else
size_t iconv();
#endif
int main()
{
return 1;
}
'''
conf.Message('Check if the declaration of iconv needs const... ')
ret = conf.TryLink(check_iconv_const, '.c')
conf.Result(ret)
return ret
def createConfigFile(conf, config_file,
config_pre = '', config_post = '',
headers = [], functions = [], 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)
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]] = True
cont += configString('#define %s 1' % header[1], desc = description)
else:
result[header[1]] = False
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]] = True
cont += configString('#define %s 1' % func[1], desc = description)
else:
result[func[1]] = False
cont += configString('/* #undef %s */' % func[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]] = True
cont += configString('#define %s 1' % t[1], desc = description)
else:
result[t[1]] = False
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]] = False
# 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]] = True
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]] = True
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]] = False
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)
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

View File

@ -82,6 +82,8 @@ What's new
- Install python files together with precompiled versions.
- A scons build system is added, details please see INSTALL.scons.
* Miscellaneous
- Display latex package checking results faster during configuration.