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.
492 lines
16 KiB
492 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
|