1#
2# get-py-info.py: get various Python info (for building)
3#
4######################################################################
5#    Licensed to the Apache Software Foundation (ASF) under one
6#    or more contributor license agreements.  See the NOTICE file
7#    distributed with this work for additional information
8#    regarding copyright ownership.  The ASF licenses this file
9#    to you under the Apache License, Version 2.0 (the
10#    "License"); you may not use this file except in compliance
11#    with the License.  You may obtain a copy of the License at
12#
13#      http://www.apache.org/licenses/LICENSE-2.0
14#
15#    Unless required by applicable law or agreed to in writing,
16#    software distributed under the License is distributed on an
17#    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18#    KIND, either express or implied.  See the License for the
19#    specific language governing permissions and limitations
20#    under the License.
21######################################################################
22#
23# This should be loaded/run by the appropriate Python, rather than executed
24# directly as a program. In other words, you should:
25#
26#    $ python2 get-py-info.py --includes
27#
28
29import sys
30import os
31
32def usage():
33  print('USAGE: python %s WHAT' % sys.argv[0])
34  print('  Returns information about how to build Python extensions.')
35  print('  WHAT may be one of:')
36  print("    --includes : return -I include flags")
37  print("    --compile  : return a compile command")
38  print("    --link     : return a link command")
39  print("    --libs     : return just the library options for linking")
40  print("    --site     : return the path to site-packages")
41  sys.exit(1)
42
43if len(sys.argv) != 2:
44  usage()
45
46try:
47  from distutils import sysconfig
48except ImportError:
49  # No information available
50  print("none")
51  sys.exit(1)
52
53if sys.argv[1] == '--includes':
54  inc = sysconfig.get_python_inc()
55  plat = sysconfig.get_python_inc(plat_specific=1)
56  if inc == plat:
57    print("-I" + inc)
58  else:
59    print("-I%s -I%s" % (inc, plat))
60  sys.exit(0)
61
62if sys.argv[1] == '--compile':
63  cc, ccshared = sysconfig.get_config_vars('CC', 'CCSHARED')
64  print("%s %s" % (cc, ccshared))
65  sys.exit(0)
66
67def add_option(options, name, value=None):
68  """Add option to list of options"""
69  options.append(name)
70  if value is not None:
71    options.append(value)
72
73def add_option_if_missing(options, name, value=None):
74  """Add option to list of options, if it is not already present"""
75  if options.count(name) == 0 and options.count("-Wl,%s" % name) == 0:
76    add_option(options, name, value)
77
78def link_options():
79  """Get list of Python linker options"""
80
81  # Initialize config variables
82  assert os.name == "posix"
83  options = sysconfig.get_config_var('LDSHARED').split()
84
85  if sys.platform == 'darwin':
86
87    # Load bundles from python
88    python_exe = os.path.join(sysconfig.get_config_var("BINDIR"),
89      sysconfig.get_config_var('PYTHON'))
90    add_option_if_missing(options, "-bundle_loader", python_exe)
91
92  elif sys.platform == 'cygwin' or sys.platform.startswith('openbsd'):
93
94    # Add flags to build against the Python library (also necessary
95    # for Darwin, but handled elsewhere).
96
97    # Find the path to the library, and add a flag to include it as a
98    # library search path.
99    shared_libdir = sysconfig.get_config_var('LIBDIR')
100    static_libdir = sysconfig.get_config_var('LIBPL')
101    ldlibrary = sysconfig.get_config_var('LDLIBRARY')
102    if os.path.exists(os.path.join(shared_libdir, ldlibrary)):
103      if shared_libdir != '/usr/lib':
104        add_option_if_missing(options, '-L%s' % shared_libdir)
105    elif os.path.exists(os.path.join(static_libdir, ldlibrary)):
106      add_option_if_missing(options, "-L%s" % static_libdir)
107
108    # Add a flag to build against the library itself.
109    python_version = sysconfig.get_config_var('VERSION')
110    add_option_if_missing(options, "-lpython%s" % python_version)
111
112  return options
113
114def lib_options():
115  """Get list of Python library options"""
116  link_command = link_options()
117  options = []
118
119  # Extract library-related options from link command
120  for i in range(len(link_command)):
121    option = link_command[i]
122    if (not option.startswith("-L:") and option.startswith("-L") or
123        option.startswith("-Wl,") or option.startswith("-l") or
124        option.startswith("-F") or option == "-bundle" or
125        option == "-flat_namespace"):
126      options.append(option)
127    elif (option == "-undefined" or option == "-bundle_loader" or
128          option == "-framework"):
129      options.append(option)
130      options.append(link_command[i+1])
131
132  return options
133
134if sys.argv[1] == '--link':
135  print(" ".join(link_options()))
136  sys.exit(0)
137
138if sys.argv[1] == '--libs':
139  print(" ".join(lib_options()))
140  sys.exit(0)
141
142if sys.argv[1] == '--site':
143  print(sysconfig.get_python_lib())
144  sys.exit(0)
145
146usage()
147