mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-12 16:50:39 +00:00
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:
parent
dcbfef703a
commit
2949a35176
@ -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
351
INSTALL.scons
Normal 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.
|
||||
|
||||
|
@ -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
2072
development/scons/SConstruct
Normal file
File diff suppressed because it is too large
Load Diff
2248
development/scons/scons_manifest.py
Normal file
2248
development/scons/scons_manifest.py
Normal file
File diff suppressed because it is too large
Load Diff
669
development/scons/scons_utils.py
Normal file
669
development/scons/scons_utils.py
Normal 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
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user