You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
491 lines
16 KiB
491 lines
16 KiB
# This script handles the SIP configuration and generates the Makefiles. |
|
# |
|
# Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com> |
|
# |
|
# This file is part of SIP. |
|
# |
|
# This copy of SIP is licensed for use under the terms of the SIP License |
|
# Agreement. See the file LICENSE for more details. |
|
# |
|
# This copy of SIP may also used under the terms of the GNU General Public |
|
# License v2 or v3 as published by the Free Software Foundation which can be |
|
# found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package. |
|
# |
|
# SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of |
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
|
|
|
|
import sys |
|
import os |
|
import glob |
|
import optparse |
|
from distutils import sysconfig |
|
|
|
import siputils |
|
|
|
|
|
# Initialise the globals. |
|
sip_version = 0x040a05 |
|
sip_version_str = "4.10.5" |
|
py_version = sys.hexversion >> 8 |
|
plat_py_site_dir = None |
|
plat_py_inc_dir = None |
|
plat_py_conf_inc_dir = None |
|
plat_py_lib_dir = None |
|
plat_sip_dir = None |
|
plat_bin_dir = None |
|
platform_specs = [] |
|
src_dir = os.path.dirname(os.path.abspath(__file__)) |
|
|
|
# Constants. |
|
DEFAULT_MACOSX_ARCH = 'i386 ppc' |
|
MACOSX_SDK_DIR = '/Developer/SDKs' |
|
|
|
# Command line options. |
|
default_platform = None |
|
default_sipbindir = None |
|
default_sipmoddir = None |
|
default_sipincdir = None |
|
default_sipsipdir = None |
|
|
|
# The names of build macros extracted from the platform specific configuration |
|
# files. |
|
build_macro_names = [ |
|
"DEFINES", "CONFIG", |
|
"CC", |
|
"CFLAGS", |
|
"CFLAGS_RELEASE", "CFLAGS_DEBUG", |
|
"CFLAGS_CONSOLE", "CFLAGS_SHLIB", "CFLAGS_THREAD", |
|
"CFLAGS_MT", "CFLAGS_MT_DBG", "CFLAGS_MT_DLL", "CFLAGS_MT_DLLDBG", |
|
"CFLAGS_EXCEPTIONS_ON", "CFLAGS_EXCEPTIONS_OFF", |
|
"CFLAGS_RTTI_ON", "CFLAGS_RTTI_OFF", |
|
"CFLAGS_STL_ON", "CFLAGS_STL_OFF", |
|
"CFLAGS_WARN_ON", "CFLAGS_WARN_OFF", |
|
"CHK_DIR_EXISTS", "COPY", |
|
"CXX", |
|
"CXXFLAGS", |
|
"CXXFLAGS_RELEASE", "CXXFLAGS_DEBUG", |
|
"CXXFLAGS_CONSOLE", "CXXFLAGS_SHLIB", "CXXFLAGS_THREAD", |
|
"CXXFLAGS_MT", "CXXFLAGS_MT_DBG", "CXXFLAGS_MT_DLL", "CXXFLAGS_MT_DLLDBG", |
|
"CXXFLAGS_EXCEPTIONS_ON", "CXXFLAGS_EXCEPTIONS_OFF", |
|
"CXXFLAGS_RTTI_ON", "CXXFLAGS_RTTI_OFF", |
|
"CXXFLAGS_STL_ON", "CXXFLAGS_STL_OFF", |
|
"CXXFLAGS_WARN_ON", "CXXFLAGS_WARN_OFF", |
|
"DEL_FILE", |
|
"EXTENSION_SHLIB", "EXTENSION_PLUGIN", |
|
"INCDIR", "INCDIR_X11", "INCDIR_OPENGL", |
|
"LIBS_CORE", "LIBS_GUI", "LIBS_NETWORK", "LIBS_OPENGL", "LIBS_WEBKIT", |
|
"LINK", "LINK_SHLIB", "AIX_SHLIB", "LINK_SHLIB_CMD", |
|
"LFLAGS", "LFLAGS_CONSOLE", "LFLAGS_CONSOLE_DLL", "LFLAGS_DEBUG", |
|
"LFLAGS_DLL", |
|
"LFLAGS_PLUGIN", "LFLAGS_RELEASE", "LFLAGS_SHLIB", "LFLAGS_SONAME", |
|
"LFLAGS_THREAD", "LFLAGS_WINDOWS", "LFLAGS_WINDOWS_DLL", "LFLAGS_OPENGL", |
|
"LIBDIR", "LIBDIR_X11", "LIBDIR_OPENGL", |
|
"LIBS", "LIBS_CONSOLE", "LIBS_RT", |
|
"LIBS_RTMT", "LIBS_THREAD", "LIBS_WINDOWS", "LIBS_X11", |
|
"MAKEFILE_GENERATOR", |
|
"MKDIR", |
|
"RPATH", |
|
"AR", "RANLIB", "LIB", "STRIP" |
|
] |
|
|
|
|
|
def show_platforms(): |
|
"""Display the different platform/compilers. |
|
""" |
|
sys.stdout.write(""" |
|
The following platform/compiler configurations are supported: |
|
|
|
""") |
|
|
|
platform_specs.sort() |
|
sys.stdout.write(siputils.format(", ".join(platform_specs), leftmargin=2)) |
|
sys.stdout.write("\n\n") |
|
|
|
|
|
def show_macros(): |
|
"""Display the different build macros. |
|
""" |
|
sys.stdout.write(""" |
|
The following options may be used to adjust the compiler configuration: |
|
|
|
""") |
|
|
|
build_macro_names.sort() |
|
sys.stdout.write(siputils.format(", ".join(build_macro_names), leftmargin=2)) |
|
sys.stdout.write("\n\n") |
|
|
|
|
|
def set_defaults(): |
|
"""Set up the defaults for values that can be set on the command line. |
|
""" |
|
global default_platform, default_sipbindir, default_sipmoddir |
|
global default_sipincdir, default_sipsipdir |
|
|
|
# Set the platform specific default specification. |
|
platdefaults = { |
|
"aix": "aix-xlc", |
|
"bsd": "bsdi-g++", |
|
"cygwin": "cygwin-g++", |
|
"darwin": "macx-g++", |
|
"dgux": "dgux-g++", |
|
"freebsd": "freebsd-g++", |
|
"gnu": "hurd-g++", |
|
"hp-ux": "hpux-acc", |
|
"irix": "irix-cc", |
|
"linux": "linux-g++", |
|
"lynxos": "lynxos-g++", |
|
"netbsd": "netbsd-g++", |
|
"openbsd": "openbsd-g++", |
|
"openunix": "unixware-cc", |
|
"osf1": "tru64-cxx", |
|
"qnx": "qnx-g++", |
|
"reliantunix": "reliant-cds", |
|
"sco_sv": "sco-cc", |
|
"sinix": "reliant-cds", |
|
"sunos5": "solaris-cc", |
|
"ultrix": "ultrix-g++", |
|
"unix_sv": "unixware-g++", |
|
"unixware": "unixware-cc" |
|
} |
|
|
|
default_platform = "none" |
|
|
|
if sys.platform == "win32": |
|
if py_version >= 0x020600: |
|
default_platform = "win32-msvc2008" |
|
elif py_version >= 0x020400: |
|
default_platform = "win32-msvc.net" |
|
else: |
|
default_platform = "win32-msvc" |
|
else: |
|
for pd in list(platdefaults.keys()): |
|
if sys.platform[:len(pd)] == pd: |
|
default_platform = platdefaults[pd] |
|
break |
|
|
|
default_sipbindir = plat_bin_dir |
|
default_sipmoddir = os.path.join(plat_py_site_dir, 'sip4_tqt') |
|
default_sipincdir = plat_py_inc_dir |
|
default_sipsipdir = plat_sip_dir |
|
|
|
|
|
def inform_user(): |
|
"""Tell the user the option values that are going to be used. |
|
""" |
|
siputils.inform("The SIP code generator will be installed in %s." % opts.sipbindir) |
|
siputils.inform("The SIP module will be installed in %s." % opts.sipmoddir) |
|
siputils.inform("The SIP header file will be installed in %s." % opts.sipincdir) |
|
siputils.inform("The default directory to install .sip files in is %s." % opts.sipsipdir) |
|
siputils.inform("The platform/compiler configuration is %s." % opts.platform) |
|
|
|
if opts.arch: |
|
siputils.inform("MacOS/X binaries will be created for %s." % (", ".join(opts.arch.split()))) |
|
|
|
if opts.universal: |
|
siputils.inform("MacOS/X universal binaries will be created using %s." % opts.universal) |
|
|
|
|
|
def set_platform_directories(): |
|
"""Initialise the global variables relating to platform specific |
|
directories. |
|
""" |
|
global plat_py_site_dir, plat_py_inc_dir, plat_py_conf_inc_dir |
|
global plat_bin_dir, plat_py_lib_dir, plat_sip_dir |
|
|
|
# We trust distutils for some stuff. |
|
plat_py_site_dir = sysconfig.get_python_lib(plat_specific=1) |
|
plat_py_inc_dir = sysconfig.get_python_inc() |
|
plat_py_conf_inc_dir = os.path.dirname(sysconfig.get_config_h_filename()) |
|
|
|
if sys.platform == "win32": |
|
plat_py_lib_dir = sys.prefix + "\\libs" |
|
plat_bin_dir = sys.exec_prefix |
|
plat_sip_dir = sys.prefix + "\\sip" |
|
else: |
|
lib_dir = sysconfig.get_python_lib(plat_specific=1, standard_lib=1) |
|
|
|
plat_py_lib_dir = lib_dir + "/config" |
|
plat_bin_dir = sys.exec_prefix + "/bin" |
|
plat_sip_dir = sys.prefix + "/share/sip" |
|
|
|
|
|
def create_config(module, template, macros): |
|
"""Create the SIP configuration module so that it can be imported by build |
|
scripts. |
|
|
|
module is the module file name. |
|
template is the template file name. |
|
macros is the dictionary of build macros. |
|
""" |
|
siputils.inform("Creating %s..." % module) |
|
|
|
content = { |
|
"sip_config_args": sys.argv[1:], |
|
"sip_version": sip_version, |
|
"sip_version_str": sip_version_str, |
|
"platform": opts.platform, |
|
"sip_bin": os.path.join(opts.sipbindir, "sip"), |
|
"sip_inc_dir": opts.sipincdir, |
|
"sip_mod_dir": opts.sipmoddir, |
|
"default_bin_dir": plat_bin_dir, |
|
"default_mod_dir": plat_py_site_dir, |
|
"default_sip_dir": opts.sipsipdir, |
|
"py_version": py_version, |
|
"py_inc_dir": plat_py_inc_dir, |
|
"py_conf_inc_dir": plat_py_conf_inc_dir, |
|
"py_lib_dir": plat_py_lib_dir, |
|
"universal": opts.universal, |
|
"arch": opts.arch |
|
} |
|
|
|
siputils.create_config_module(module, template, content, macros) |
|
|
|
|
|
def create_makefiles(macros, extra_lib_dir=None, extra_libs=None): |
|
"""Create the Makefiles. |
|
|
|
macros is the dictionary of platform specific build macros. |
|
""" |
|
# Bootstrap. Make sure we get the right one. |
|
sys.path.insert(0, os.path.curdir) |
|
import sipconfig |
|
|
|
cfg = sipconfig.Configuration() |
|
|
|
cfg.set_build_macros(macros) |
|
|
|
sipconfig.inform("Creating top level Makefile...") |
|
|
|
open('__init__.py', 'a').close() |
|
|
|
sipconfig.ParentMakefile( |
|
configuration=cfg, |
|
subdirs=["sipgen", "siplib"], |
|
installs=(["__init__.py", "sipconfig.py", os.path.join(src_dir, "sipdistutils.py")], |
|
cfg.sip_mod_dir) |
|
).generate() |
|
|
|
sipconfig.inform("Creating sip code generator Makefile...") |
|
|
|
sipconfig.ProgramMakefile( |
|
configuration=cfg, |
|
build_file=os.path.join(src_dir, "sipgen", "sipgen.sbf"), |
|
dir="sipgen", |
|
install_dir=os.path.dirname(cfg.sip_bin), |
|
console=1, |
|
warnings=0, |
|
universal=opts.universal, |
|
arch=opts.arch |
|
).generate() |
|
|
|
sipconfig.inform("Creating sip module Makefile...") |
|
|
|
makefile = sipconfig.ModuleMakefile( |
|
configuration=cfg, |
|
build_file=os.path.join(src_dir, "siplib", "siplib.sbf"), |
|
dir="siplib", |
|
install_dir=cfg.sip_mod_dir, |
|
installs=([os.path.join(src_dir, "siplib", "sip.h")], cfg.sip_inc_dir), |
|
console=1, |
|
warnings=0, |
|
static=opts.static, |
|
debug=opts.debug, |
|
universal=opts.universal, |
|
arch=opts.arch |
|
) |
|
|
|
if extra_lib_dir: |
|
makefile.extra_lib_dirs.append(extra_lib_dir) |
|
|
|
if extra_libs: |
|
makefile.extra_libs.extend(extra_libs) |
|
|
|
makefile.generate() |
|
|
|
|
|
def create_optparser(): |
|
"""Create the parser for the command line. |
|
""" |
|
def store_abspath(option, opt_str, value, parser): |
|
setattr(parser.values, option.dest, os.path.abspath(value)) |
|
|
|
p = optparse.OptionParser(usage="python %prog [opts] [macro=value] " |
|
"[macro+=value]", version=sip_version_str) |
|
|
|
# Note: we don't use %default to be compatible with Python 2.3. |
|
p.add_option("-k", "--static", action="store_true", default=False, |
|
dest="static", help="build the SIP module as a static library") |
|
p.add_option("-p", "--platform", action="store", |
|
default=default_platform, type="string", metavar="PLATFORM", |
|
dest="platform", help="the platform/compiler configuration " |
|
"[default: %s]" % default_platform) |
|
p.add_option("-u", "--debug", action="store_true", default=False, |
|
help="build with debugging symbols") |
|
p.add_option("-g", "--libpython", |
|
default=None, type="string", metavar="LIB", |
|
dest="libpython", help="python " |
|
"library name [default: %s]" % None) |
|
|
|
if sys.platform == 'darwin': |
|
# Get the latest SDK to use as the default. |
|
sdks = glob.glob(MACOSX_SDK_DIR + '/MacOSX*.sdk') |
|
if len(sdks) > 0: |
|
sdks.sort() |
|
_, default_sdk = os.path.split(sdks[-1]) |
|
else: |
|
default_sdk = 'MacOSX10.4u.sdk' |
|
|
|
g = optparse.OptionGroup(p, title="MacOS X Configuration") |
|
g.add_option("--arch", action="append", default=[], dest="arch", |
|
choices=["i386", "x86_64", "ppc"], |
|
help="build for architecture ARCH") |
|
g.add_option("-n", "--universal", action="store_true", default=False, |
|
dest="universal", |
|
help="build the SIP code generator and module as universal " |
|
"binaries") |
|
g.add_option("-s", "--sdk", action="store", default=default_sdk, |
|
type="string", metavar="SDK", dest="sdk", |
|
help="the name of the SDK used when building universal " |
|
"binaries [default: %s]" % default_sdk) |
|
p.add_option_group(g) |
|
|
|
# Querying. |
|
g = optparse.OptionGroup(p, title="Query") |
|
g.add_option("--show-platforms", action="store_true", default=False, |
|
dest="show_platforms", help="show the list of supported " |
|
"platform/compiler configurations") |
|
g.add_option("--show-build-macros", action="store_true", default=False, |
|
dest="show_build_macros", help="show the list of supported build " |
|
"macros") |
|
p.add_option_group(g) |
|
|
|
# Installation. |
|
g = optparse.OptionGroup(p, title="Installation") |
|
g.add_option("-b", "--bindir", action="callback", |
|
default=default_sipbindir, type="string", metavar="DIR", |
|
dest="sipbindir", callback=store_abspath, help="where the SIP " |
|
"code generator will be installed [default: %s]" % |
|
default_sipbindir) |
|
g.add_option("-d", "--destdir", action="callback", |
|
default=default_sipmoddir, type="string", metavar="DIR", |
|
dest="sipmoddir", callback=store_abspath, help="where the SIP " |
|
"module will be installed [default: %s]" % default_sipmoddir) |
|
g.add_option("-e", "--incdir", action="callback", |
|
default=default_sipincdir, type="string", metavar="DIR", |
|
dest="sipincdir", callback=store_abspath, help="where the SIP " |
|
"header file will be installed [default: %s]" % default_sipincdir) |
|
g.add_option("-v", "--sipdir", action="callback", |
|
default=default_sipsipdir, type="string", metavar="DIR", |
|
dest="sipsipdir", callback=store_abspath, help="where .sip files " |
|
"are normally installed [default: %s]" % default_sipsipdir) |
|
p.add_option_group(g) |
|
|
|
return p |
|
|
|
|
|
def main(argv): |
|
"""Create the configuration module module. |
|
|
|
argv is the list of command line arguments. |
|
""" |
|
siputils.inform("This is SIP %s for Python %s on %s." % (sip_version_str, sys.version.split()[0], sys.platform)) |
|
|
|
if py_version < 0x020300: |
|
siputils.error("This version of SIP requires Python v2.3 or later.") |
|
|
|
global extra_lib_dir |
|
|
|
# Basic initialisation. |
|
set_platform_directories() |
|
|
|
# Build up the list of valid specs. |
|
for s in os.listdir(os.path.join(src_dir, "specs")): |
|
platform_specs.append(s) |
|
|
|
# Parse the command line. |
|
global opts |
|
|
|
set_defaults() |
|
p = create_optparser() |
|
opts, args = p.parse_args() |
|
|
|
# Make sure MacOS specific options get initialised. |
|
if sys.platform != 'darwin': |
|
opts.universal = '' |
|
opts.arch = [] |
|
opts.sdk = '' |
|
|
|
# Handle the query options. |
|
if opts.show_platforms or opts.show_build_macros: |
|
if opts.show_platforms: |
|
show_platforms() |
|
|
|
if opts.show_build_macros: |
|
show_macros() |
|
|
|
sys.exit() |
|
|
|
extra_libs = [] |
|
extra_lib_dir = None |
|
|
|
if opts.libpython: |
|
extra_libs.append(opts.libpython) |
|
|
|
# Convert the list 'arch' option to a string. Multiple architectures |
|
# imply a universal binary. |
|
if len(opts.arch) > 1: |
|
opts.universal = True |
|
|
|
opts.arch = ' '.join(opts.arch) |
|
|
|
# Convert the boolean 'universal' option to a string. |
|
if opts.universal: |
|
if '/' in opts.sdk: |
|
opts.universal = os.path.abspath(opts.sdk) |
|
else: |
|
opts.universal = MACOSX_SDK_DIR + '/' + opts.sdk |
|
|
|
if not os.path.isdir(opts.universal): |
|
siputils.error("Unable to find the SDK directory %s. Use the --sdk flag to specify the name of the SDK or its full path." % opts.universal) |
|
|
|
if opts.arch == '': |
|
opts.arch = DEFAULT_MACOSX_ARCH |
|
else: |
|
opts.universal = '' |
|
|
|
# Get the platform specific macros for building. |
|
macros = siputils.parse_build_macros( |
|
os.path.join(src_dir, "specs", opts.platform), build_macro_names, |
|
args) |
|
|
|
if macros is None: |
|
p.print_help() |
|
sys.exit(2) |
|
|
|
# Tell the user what's been found. |
|
inform_user() |
|
|
|
# Install the configuration module. |
|
create_config("sipconfig.py", os.path.join(src_dir, "siputils.py"), |
|
macros) |
|
|
|
# Create the Makefiles. |
|
create_makefiles(macros, extra_lib_dir=extra_lib_dir, extra_libs=extra_libs) |
|
|
|
|
|
############################################################################### |
|
# The script starts here. |
|
############################################################################### |
|
|
|
if __name__ == "__main__": |
|
try: |
|
main(sys.argv) |
|
except SystemExit: |
|
raise |
|
except: |
|
sys.stderr.write( |
|
"""An internal error occured. Please report all the output from the program, |
|
including the following traceback, to support@riverbankcomputing.com. |
|
""") |
|
raise
|
|
|