From b9a93909bb6c9e5242d075221d0bb41483c2c4a1 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Wed, 8 Jun 2022 20:15:45 +0200 Subject: [PATCH] Improve error handling if runtime_library_dirs is set with cygwin/mingw On Windows there is nothing like rpath, so when CygwinCCompiler() tries to link it will assume unix and pass rpath flags to the linker, which will fail. In cygwin this is currently patched away: https://cygwin.com/git-cygwin-packages/?p=git/cygwin-packages/python39.git;a=blob;f=3.1-enable-new-dtags.patch;h=716af3b14d3483e5a4 It is taking some macos fallback branch that is equal to library_dirs, which doesn't add much if library_dirs is set, so in theory it should just return [] there. This patch tries to bring it a bit closer to MSVCCompiler() which warns if runtime_library_dirs is passed and raises if runtime_library_dir_option() is called. In the case of cygwin we only warn if runtime_library_dir_option() is called and return nothing, so runtime_library_dirs is ignored. It's debatable if it should fail here, but since cygwin is used to build unix software that might not be aware of this limitation a warning seems more fitting. In the mingw case we assume the user knows that they are targeting Windows and so we can be more strict and error out like MSVCCompiler(). In both cases we warn if runtime_library_dirs is passed to the compiler, like with MSVC. --- distutils/cygwinccompiler.py | 19 +++++++++++++++++++ distutils/tests/test_cygwinccompiler.py | 6 ++++++ 2 files changed, 25 insertions(+) diff --git a/distutils/cygwinccompiler.py b/distutils/cygwinccompiler.py index 931b3661..445e2e51 100644 --- a/distutils/cygwinccompiler.py +++ b/distutils/cygwinccompiler.py @@ -58,6 +58,7 @@ from distutils.file_util import write_file from distutils.errors import ( DistutilsExecError, + DistutilsPlatformError, CCompilerError, CompileError, UnknownFileError, @@ -197,6 +198,12 @@ def link( libraries = copy.copy(libraries or []) objects = copy.copy(objects or []) + if runtime_library_dirs: + self.warn( + "I don't know what to do with 'runtime_library_dirs': " + + str(runtime_library_dirs) + ) + # Additional libraries libraries.extend(self.dll_libraries) @@ -265,6 +272,13 @@ def link( target_lang, ) + def runtime_library_dir_option(self, dir): + # cygwin doesn't support rpath. While in theory we could error + # out like MSVC does, code might expect it to work like on Unix, so + # just warn and hope for the best. + self.warn("don't know how to set runtime library search path on Windows") + return [] + # -- Miscellaneous methods ----------------------------------------- def object_filenames(self, source_filenames, strip_dir=0, output_dir=''): @@ -325,6 +339,11 @@ def __init__(self, verbose=0, dry_run=0, force=0): # with MSVC 7.0 or later. self.dll_libraries = get_msvcr() + def runtime_library_dir_option(self, dir): + raise DistutilsPlatformError( + "don't know how to set runtime library search path on Windows" + ) + # Because these compilers aren't configured in Python's pyconfig.h file by # default, we should at least warn the user if he is using an unmodified diff --git a/distutils/tests/test_cygwinccompiler.py b/distutils/tests/test_cygwinccompiler.py index b3c164ed..7760436a 100644 --- a/distutils/tests/test_cygwinccompiler.py +++ b/distutils/tests/test_cygwinccompiler.py @@ -48,6 +48,12 @@ def test_find_library_file(self): self.assertTrue(os.path.exists(linkable_file)) self.assertEquals(linkable_file, "/usr/lib/lib{:s}.dll.a".format(link_name)) + @unittest.skipIf(sys.platform != "cygwin", "Not running on Cygwin") + def test_runtime_library_dir_option(self): + from distutils.cygwinccompiler import CygwinCCompiler + compiler = CygwinCCompiler() + self.assertEqual(compiler.runtime_library_dir_option('/foo'), []) + def test_check_config_h(self): # check_config_h looks for "GCC" in sys.version first