1 # SPDX-License-Identifier: MIT
3 # Copyright (C) 2017 Francis Deslauriers <francis.deslauriers@efficios.com>
4 # Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
11 # Distutils was removed in Python 3.12, use setuptools as an alternative.
12 if sys
.version_info
>= (3, 12):
13 from setuptools
import setup
, Extension
15 from distutils
.core
import setup
, Extension
17 # Starting with Debian's Python 3.10, the default install scheme is
18 # 'posix_local' which is a Debian specific scheme based on 'posix_prefix' but
19 # with an added 'local' prefix. This is the default so users doing system wide
20 # manual installations of python modules end up in '/usr/local'. This
21 # interferes with our autotools based install which already defaults to
22 # '/usr/local' and expect a provided prefix to be used verbatim.
24 # Monkeypatch sysconfig to override this scheme and use 'posix_prefix' instead.
25 if sys
.version_info
>= (3, 10):
28 original_get_preferred_scheme
= sysconfig
.get_preferred_scheme
30 def our_get_preferred_scheme(key
):
31 scheme
= original_get_preferred_scheme(key
)
32 if scheme
== "posix_local":
37 sysconfig
.get_preferred_scheme
= our_get_preferred_scheme
40 import distutils
.sysconfig
as sysconfig
42 PY_PATH_WARN_MSG
= """
43 -------------------------------------WARNING------------------------------------
44 The install directory used:\n ({})\nis not included in your PYTHONPATH.
46 To add this directory to your Python search path permanently you can add the
47 following command to your .bashrc/.zshrc:
48 export PYTHONPATH="${{PYTHONPATH}}:{}"
49 --------------------------------------------------------------------------------
52 original_get_config_vars
= sysconfig
.get_config_vars
56 cflags
= os
.environ
.get("CFLAGS")
59 [cflags
] = original_get_config_vars("CFLAGS")
64 # distutils performs a similar transformation step on LDSHARED on
65 # darwin to use the overridden CC as the default command for LDSHARED
66 # (see distutils' customize_compiler() step in the sysconfig module).
68 # This takes it a step further by using our own LDFLAGS (when available)
69 # along with the overridden compiler and ensure that flags that are unsupported
70 # by either the Python interprter's CC or the overridden CC don't cause a
73 cc
= os
.environ
.get("CC")
74 ldflags
= os
.environ
.get("LDFLAGS")
75 [py_cc
] = original_get_config_vars("CC")
76 [py_ldshared
] = original_get_config_vars("LDSHARED")
78 if not py_ldshared
.startswith(py_cc
):
82 return "{} -shared {}".format(cc
, ldflags
)
84 return cc
+ py_ldshared
[len(py_cc
) :]
86 return py_cc
+ py_ldshared
[len(py_cc
) :]
91 def our_get_config_vars(*args
):
92 overridden_config_vars_funcs
= {
94 "LDSHARED": get_ldshared
,
98 # Return a dict with all config vars.
99 all_config_vars
= original_get_config_vars()
100 for name
in overridden_config_vars_funcs
:
101 all_config_vars
[name
] = overridden_config_vars_funcs
[name
]()
103 return all_config_vars
105 # Return a list with the requested config vars.
106 subset_config_vars
= []
108 if name
in overridden_config_vars_funcs
:
109 subset_config_vars
.append(overridden_config_vars_funcs
[name
]())
111 subset_config_vars
.append(original_get_config_vars(name
)[0])
113 return subset_config_vars
116 sysconfig
.get_config_vars
= our_get_config_vars
119 # Returns 'True' when running on a MinGW system.
121 return sys
.platform
== "win32" and shutil
.which("cygpath") != None
124 # On MinGW systems run 'cygpath -m' on 'path', on other systems return 'path' as-is.
125 def cygpath_m(path
: str):
127 return subprocess
.check_output(
128 'cygpath -m "{}"'.format(path
), shell
=True, encoding
="utf-8"
134 # On MinGW systems, check CFLAGS and CPPFLAGS for absolute include paths
135 # (starts with '-I/') and convert them to valid Windows paths using cygpath.
137 for flagvar
in ["CFLAGS", "CPPFLAGS"]:
138 cur_flags
= os
.getenv(flagvar
)
139 if cur_flags
!= None:
141 for flag
in cur_flags
.split():
142 if flag
.startswith("-I/"):
143 flag
= "-I{}".format(cygpath_m(flag
[2:]))
145 new_flags
+= " {}".format(flag
)
147 os
.environ
[flagvar
] = new_flags
151 babeltrace_ext
= Extension(
155 cygpath_m("@srcdir@/bt2/logging.c"),
157 libraries
=["babeltrace2", "glib-2.0"],
159 "@top_builddir@/src/autodisc/.libs/libautodisc.a",
160 "@top_builddir@/src/logging/.libs/liblogging.a",
161 "@top_builddir@/src/common/.libs/libcommon.a",
162 "@top_builddir@/src/py-common/.libs/libpy-common.a",
163 "@top_builddir@/src/string-format/.libs/libstring-format.a",
169 version
="@PACKAGE_VERSION@",
170 description
="Babeltrace 2 Python Bindings",
172 package_dir
={"bt2": "bt2"},
174 "build": {"build_base": "build", "build_lib": "build/build_lib"},
175 "build_ext": {"build_lib": "build/build_lib"},
177 url
="https://babeltrace.org/",
178 ext_modules
=[babeltrace_ext
],
181 "Development Status :: 5 - Production/Stable",
182 "Intended Audience :: Developers",
183 "License :: OSI Approved :: The MIT License",
184 "Programming Language :: Python :: 3" "Topic :: System :: Logging",
188 # After the installation, we check that the install directory is included in
189 # the Python search path and we print a warning message when it's not.
190 # We need to do this because Python search path differs depending on the distro
191 # and some distros don't include any /usr/local/ in the search path. This is
192 # also useful for out-of-tree installs and tests.
193 # It's only relevant to make this check on the `install` command.
195 if "install" in dist
.command_obj
:
196 install_dir
= dist
.command_obj
["install"].install_libbase
197 if install_dir
not in sys
.path
:
198 # We can't consider this an error because if affects every
199 # distro differently. We only warn the user that some
200 # extra configuration is needed to use the bindings
201 print(PY_PATH_WARN_MSG
.format(install_dir
, install_dir
))
204 if __name__
== "__main__":