#
# get-py-info.py: get various Python info (for building)
#
######################################################################
#
# Copyright (c) 2002-2006 CollabNet.  All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution.  The terms
# are also available at http://subversion.tigris.org/license-1.html.
# If newer versions of this license are posted there, you may use a
# newer version instead, at your option.
#
######################################################################
#
# This should be loaded/run by the appropriate Python, rather than executed
# directly as a program. In other words, you should:
#
#    $ python2 get-py-info.py --includes
#

import sys
import os

def usage():
  print 'USAGE: python %s WHAT' % sys.argv[0]
  print '  Returns information about how to build Python extensions.'
  print '  WHAT may be one of:'
  print "    --includes : return -I include flags"
  print "    --compile  : return a compile command"
  print "    --link     : return a link command"
  print "    --libs     : return just the library options for linking"
  sys.exit(1)

if len(sys.argv) != 2:
  usage()

try:
  from distutils import sysconfig
except ImportError:
  # No information available
  print "none"
  sys.exit(1)

if sys.argv[1] == '--includes':
  inc = sysconfig.get_python_inc()
  plat = sysconfig.get_python_inc(plat_specific=1)
  if inc == plat:
    print "-I" + inc
  else:
    print "-I%s -I%s" % (inc, plat)
  sys.exit(0)

if sys.argv[1] == '--compile':
  cc, basecflags, opt, ccshared = \
      sysconfig.get_config_vars('CC', 'BASECFLAGS', 'OPT', 'CCSHARED')
  if basecflags:
    opt = basecflags + ' ' + opt
  print cc, opt, ccshared
  sys.exit(0)

def add_option(options, name, value=None):
  """Add option to list of options"""
  options.append(name)
  if value is not None:
    options.append(value)

def add_option_if_missing(options, name, value=None):
  """Add option to list of options, if it is not already present"""
  if options.count(name) == 0 and options.count("-Wl,%s" % name) == 0:
    add_option(options, name, value)

def link_options():
  """Get list of Python linker options"""

  # Initialize config variables
  assert os.name == "posix"
  options = sysconfig.get_config_var('LDSHARED').split()
  fwdir = sysconfig.get_config_var('PYTHONFRAMEWORKDIR')

  if fwdir and fwdir != "no-framework":

    # Setup the framework prefix
    fwprefix = sysconfig.get_config_var('PYTHONFRAMEWORKPREFIX')
    if fwprefix != "/System/Library/Frameworks":
      add_option_if_missing(options, "-F%s" % fwprefix)

    # Load in the framework
    fw = sysconfig.get_config_var('PYTHONFRAMEWORK')
    add_option(options, "-framework", fw)

  elif sys.platform == 'darwin':

    # Load bundles from python
    python_exe = os.path.join(sysconfig.get_config_var("BINDIR"),
      sysconfig.get_config_var('PYTHON'))
    add_option_if_missing(options, "-bundle_loader", python_exe)

  elif sys.platform == 'cygwin' or sys.platform.startswith('openbsd'):

    # Add flags to build against the Python library (also necessary
    # for Darwin, but handled elsewhere).

    # Find the path to the library, and add a flag to include it as a
    # library search path.
    shared_libdir = sysconfig.get_config_var('LIBDIR')
    static_libdir = sysconfig.get_config_var('LIBPL')
    ldlibrary = sysconfig.get_config_var('LDLIBRARY')
    if os.path.exists(os.path.join(shared_libdir, ldlibrary)):
      if shared_libdir != '/usr/lib':
        add_option_if_missing(options, '-L%s' % shared_libdir)
    elif os.path.exists(os.path.join(static_libdir, ldlibrary)):
      add_option_if_missing(options, "-L%s" % static_libdir)
    
    # Add a flag to build against the library itself.
    python_version = sysconfig.get_config_var('VERSION')
    add_option_if_missing(options, "-lpython%s" % python_version)

  return options

def lib_options():
  """Get list of Python library options"""
  link_command = link_options()
  options = []

  # Extract library-related options from link command
  for i in range(len(link_command)):
    option = link_command[i]
    if (not option.startswith("-L:") and option.startswith("-L") or
        option.startswith("-Wl,") or option.startswith("-l") or
        option.startswith("-F") or option == "-bundle" or
        option == "-flat_namespace"):
      options.append(option)
    elif (option == "-undefined" or option == "-bundle_loader" or
          option == "-framework"):
      options.append(option)
      options.append(link_command[i+1])

  return options

if sys.argv[1] == '--link':
  print " ".join(link_options())
  sys.exit(0)

if sys.argv[1] == '--libs':
  print " ".join(lib_options())
  sys.exit(0)

usage()
