mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-09 18:31:04 +00:00
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:
parent
1585015805
commit
360b94ee35
357
INSTALL.scons
357
INSTALL.scons
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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
@ -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
|
@ -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
|
@ -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
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user