[Python-checkins] bpo-42603: Use pkg-config to get TCL/TK paths for tkinter. (GH-23721)

ned-deily webhook-mailer at python.org
Sun Feb 28 22:30:04 EST 2021


https://github.com/python/cpython/commit/d20279494a3a311c7aefa313174c45d32aa7f5d1
commit: d20279494a3a311c7aefa313174c45d32aa7f5d1
branch: master
author: Manolis Stamatogiannakis <mstamat at gmail.com>
committer: ned-deily <nad at python.org>
date: 2021-02-28T22:29:57-05:00
summary:

bpo-42603: Use pkg-config to get TCL/TK paths for tkinter. (GH-23721)

files:
A Misc/NEWS.d/next/Build/2020-12-08-19-25-20.bpo-42603.mXs2dB.rst
M configure
M configure.ac
M setup.py

diff --git a/Misc/NEWS.d/next/Build/2020-12-08-19-25-20.bpo-42603.mXs2dB.rst b/Misc/NEWS.d/next/Build/2020-12-08-19-25-20.bpo-42603.mXs2dB.rst
new file mode 100644
index 0000000000000..eea77e01fa7bb
--- /dev/null
+++ b/Misc/NEWS.d/next/Build/2020-12-08-19-25-20.bpo-42603.mXs2dB.rst
@@ -0,0 +1,7 @@
+Make configure script use pkg-config to detect the location of Tcl/Tk
+headers and libraries, used to build tkinter.
+
+On macOS, a Tcl/Tk configuration provided by pkg-config will be preferred
+over Tcl/Tk frameworks installed in ``/{System/,}Library/Frameworks``.
+If both exist and the latter is preferred, the appropriate
+``--with-tcltk-*`` configuration options need to be explicitly set.
diff --git a/configure b/configure
index 8c948250e41e4..2d5a61e71eb79 100755
--- a/configure
+++ b/configure
@@ -10714,8 +10714,13 @@ then
   then
     as_fn_error $? "use both --with-tcltk-includes='...' and --with-tcltk-libs='...' or neither" "$LINENO" 5
   fi
-  TCLTK_INCLUDES=""
-  TCLTK_LIBS=""
+  if test -n "$PKG_CONFIG" && "$PKG_CONFIG" --exists tcl tk; then
+    TCLTK_INCLUDES="`"$PKG_CONFIG" tcl tk --cflags-only-I 2>/dev/null`"
+    TCLTK_LIBS="`"$PKG_CONFIG" tcl tk --libs 2>/dev/null`"
+  else
+    TCLTK_INCLUDES=""
+    TCLTK_LIBS=""
+  fi
 else
   TCLTK_INCLUDES="$with_tcltk_includes"
   TCLTK_LIBS="$with_tcltk_libs"
diff --git a/configure.ac b/configure.ac
index 29957935e9b2a..e71d74c872b70 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3157,8 +3157,13 @@ then
   then
     AC_MSG_ERROR([use both --with-tcltk-includes='...' and --with-tcltk-libs='...' or neither])
   fi
-  TCLTK_INCLUDES=""
-  TCLTK_LIBS=""
+  if test -n "$PKG_CONFIG" && "$PKG_CONFIG" --exists tcl tk; then
+    TCLTK_INCLUDES="`"$PKG_CONFIG" tcl tk --cflags-only-I 2>/dev/null`"
+    TCLTK_LIBS="`"$PKG_CONFIG" tcl tk --libs 2>/dev/null`"
+  else
+    TCLTK_INCLUDES=""
+    TCLTK_LIBS=""
+  fi
 else
   TCLTK_INCLUDES="$with_tcltk_includes"
   TCLTK_LIBS="$with_tcltk_libs"
diff --git a/setup.py b/setup.py
index 0c4947fd762ee..554772217785d 100644
--- a/setup.py
+++ b/setup.py
@@ -1879,18 +1879,34 @@ def detect_modules(self):
             self.add(Extension('xxlimited', ['xxlimited.c']))
             self.add(Extension('xxlimited_35', ['xxlimited_35.c']))
 
-    def detect_tkinter_explicitly(self):
-        # Build _tkinter using explicit locations for Tcl/Tk.
+    def detect_tkinter_fromenv(self):
+        # Build _tkinter using the Tcl/Tk locations specified by
+        # the _TCLTK_INCLUDES and _TCLTK_LIBS environment variables.
+        # This method is meant to be invoked by detect_tkinter().
         #
-        # This is enabled when both arguments are given to ./configure:
+        # The variables can be set via one of the following ways.
         #
+        # - Automatically, at configuration time, by using pkg-config.
+        #   The tool is called by the configure script.
+        #   Additional pkg-config configuration paths can be set via the
+        #   PKG_CONFIG_PATH environment variable.
+        #
+        #     PKG_CONFIG_PATH=".../lib/pkgconfig" ./configure ...
+        #
+        # - Explicitly, at configuration time by setting both
+        #   --with-tcltk-includes and --with-tcltk-libs.
+        #
+        #     ./configure ... \
         #     --with-tcltk-includes="-I/path/to/tclincludes \
         #                            -I/path/to/tkincludes"
         #     --with-tcltk-libs="-L/path/to/tcllibs -ltclm.n \
         #                        -L/path/to/tklibs -ltkm.n"
         #
-        # These values can also be specified or overridden via make:
-        #    make TCLTK_INCLUDES="..." TCLTK_LIBS="..."
+        #  - Explicitly, at compile time, by passing TCLTK_INCLUDES and
+        #    TCLTK_LIBS to the make target.
+        #    This will override any configuration-time option.
+        #
+        #      make TCLTK_INCLUDES="..." TCLTK_LIBS="..."
         #
         # This can be useful for building and testing tkinter with multiple
         # versions of Tcl/Tk.  Note that a build of Tk depends on a particular
@@ -1914,6 +1930,7 @@ def detect_tkinter_explicitly(self):
 
     def detect_tkinter_darwin(self):
         # Build default _tkinter on macOS using Tcl and Tk frameworks.
+        # This method is meant to be invoked by detect_tkinter().
         #
         # The macOS native Tk (AKA Aqua Tk) and Tcl are most commonly
         # built and installed as macOS framework bundles.  However,
@@ -1932,16 +1949,20 @@ def detect_tkinter_darwin(self):
         #    search only the SDK's /Library/Frameworks (normally empty)
         #    and /System/Library/Frameworks.
         #
-        # Any other use case should be able to be handled explicitly by
-        # using the options described above in detect_tkinter_explicitly().
-        # In particular it would be good to handle here the case where
+        # Any other use cases are handled either by detect_tkinter_fromenv(),
+        # or detect_tkinter(). The former handles non-standard locations of
+        # Tcl/Tk, defined via the _TCLTK_INCLUDES and _TCLTK_LIBS environment
+        # variables. The latter handles any Tcl/Tk versions installed in
+        # standard Unix directories.
+        #
+        # It would be desirable to also handle here the case where
         # you want to build and link with a framework build of Tcl and Tk
         # that is not in /Library/Frameworks, say, in your private
         # $HOME/Library/Frameworks directory or elsewhere. It turns
         # out to be difficult to make that work automatically here
         # without bringing into play more tools and magic. That case
         # can be handled using a recipe with the right arguments
-        # to detect_tkinter_explicitly().
+        # to detect_tkinter_fromenv().
         #
         # Note also that the fallback case here is to try to use the
         # Apple-supplied Tcl and Tk frameworks in /System/Library but
@@ -2041,12 +2062,17 @@ def detect_tkinter_darwin(self):
 
     def detect_tkinter(self):
         # The _tkinter module.
+        #
+        # Detection of Tcl/Tk is attempted in the following order:
+        #   - Through environment variables.
+        #   - Platform specific detection of Tcl/Tk (currently only macOS).
+        #   - Search of various standard Unix header/library paths.
+        #
+        # Detection stops at the first successful method.
 
-        # Check whether --with-tcltk-includes and --with-tcltk-libs were
-        # configured or passed into the make target.  If so, use these values
-        # to build tkinter and bypass the searches for Tcl and TK in standard
-        # locations.
-        if self.detect_tkinter_explicitly():
+        # Check for Tcl and Tk at the locations indicated by _TCLTK_INCLUDES
+        # and _TCLTK_LIBS environment variables.
+        if self.detect_tkinter_fromenv():
             return True
 
         # Rather than complicate the code below, detecting and building



More information about the Python-checkins mailing list