[BUG]: CMake FindPython issues on CMake>3.23, and Python linking issue in debug mode
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 18k
- Forks
- 2.3k
- Avg merge
- 5d 17h
- Merged PRs (30d)
- 10
Description
Required prerequisites
- Make sure you've read the documentation. Your issue may be addressed there.
- Search the issue tracker and Discussions to verify that this hasn't already been reported. +1 or comment there if it has.
- Consider asking first in the Gitter chat room or in a Discussion.
What version (or hash if on master) of pybind11 are you using?
2.13.6
Problem description
Setting:
- Compiling my Python bindings using C++/CMake. Using CMAKE_TOOLCHAIN_FILE=...vcpkg - I am using vcpkg for my code's dependencies but not for pybind11.
cmake_minimum_required(VERSION 3.23...3.29)- Python 3.12, Windows 11, Visual Studio 2022 (latest), using VS's CMake (VS File -> Open CMake...).
- Using pybind11 as submodule, with
add_subdirectory("3rdparty/pybind11") - These issues started happening when I switched
cmake_minimum_requiredfrom 3.10 to 3.23...3.29. As far as I understand, this will have changed CMake's behaviour from using its old FindPython logic to the new FindPython logic.
Settings/Issues:
Release mode compilation and set(PYBIND11_FINDPYTHON ON)
No issues: CMake runs. Compilation works, linking works.
Release mode compilation and set(PYBIND11_FINDPYTHON OFF) and find_package(Python 3.12 COMPONENTS Interpreter Development REQUIRED)
CMake error: Could not find a package configuration file provided by "PythonInterp" (requested version 3.7) with any of the following names: PythonInterpConfig.cmake pythoninterp-config.cmake. As far as I could find out, "PythonInterp" is the old deprecated CMake FindPython module, and it shouldn't ever be called in this case. I've investigated this using VS's CMake debugger and in pybind11Common.cmake line 228 it's using the "else()" with the "Classic mode" and calls pybind11Tools.cmake, which in turn on L50 calls find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} MODULE REQUIRED ${_pybind11_quiet}), which in turn calls FindPythonLibsNew.cmake, which on L114 calls find_package(PythonInterp ${PythonLibsNew_FIND_VERSION} ${_pythonlibs_required} ${_pythonlibs_quiet}) with 3.7 as version, and this call obviously fails. I don't understand why pybind11's CMake scripts are taking this route, first, since I'm using a recent CMake version and policies, and second, why would it try and find Python at all, if I've got PYBIND11_FINDPYTHON OFF and my own find_package(Python...) call has already found 3.12. Yes, I've cleared the CMake cache / build folder.
Debug mode compilation and set(PYBIND11_FINDPYTHON OFF) and find_package(Python 3.12 COMPONENTS Interpreter Development REQUIRED)
Same issues as above with PythonInterp
Debug mode compilation and set(PYBIND11_FINDPYTHON ON)
CMake runs. Compilation works. Linker produces an error: out\build\x64-debug\LINK : fatal error LNK1104: cannot open file 'python312.lib'. This is the full linker command-line:
>------ Build started: Configuration: x64-debug -------
[1/1] Linking CXX shared module python\eos.cp312-win_amd64.pyd
FAILED: python/eos.cp312-win_amd64.pyd
C:\Windows\system32\cmd.exe /C "cd . && "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -E vs_link_dll --intdir=python\CMakeFiles\python-bindings.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100226~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100226~1.0\x64\mt.exe --manifests -- C:\PROGRA~1\MIB055~1\2022\COMMUN~1\VC\Tools\MSVC\1442~1.344\bin\Hostx64\x64\link.exe /nologo python\CMakeFiles\python-bindings.dir\generate-python-bindings.cpp.obj /out:python\eos.cp312-win_amd64.pyd /implib:python\eos.lib /pdb:python\eos.pdb /dll /version:0.0 /machine:x64 /debug /INCREMENTAL C:\Users\PatrikHuber\AppData\Local\Programs\Python\Python312\libs\python312_d.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && C:\Windows\system32\cmd.exe /C "cd /D C:\Users\PatrikHuber\Projects\eos\eos\out\build\x64-debug\python && "C:\Program Files\PowerShell\7\pwsh.exe" -noprofile -executionpolicy Bypass -file "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/vcpkg/scripts/buildsystems/msbuild/applocal.ps1" -targetBinary C:/Users/PatrikHuber/Projects/eos/eos/out/build/x64-debug/python/eos.cp312-win_amd64.pyd -installedDir C:/Users/PatrikHuber/Projects/eos/eos/out/build/x64-debug/vcpkg_installed/x64-windows/debug/bin -OutVariable out""
LINK Pass 1: command "C:\PROGRA~1\MIB055~1\2022\COMMUN~1\VC\Tools\MSVC\1442~1.344\bin\Hostx64\x64\link.exe /nologo python\CMakeFiles\python-bindings.dir\generate-python-bindings.cpp.obj /out:python\eos.cp312-win_amd64.pyd /implib:python\eos.lib /pdb:python\eos.pdb /dll /version:0.0 /machine:x64 /debug /INCREMENTAL C:\Users\PatrikHuber\AppData\Local\Programs\Python\Python312\libs\python312_d.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:python\CMakeFiles\python-bindings.dir/intermediate.manifest python\CMakeFiles\python-bindings.dir/manifest.res" failed (exit code 1104) with the following output:
C:\Users\PatrikHuber\Projects\eos\eos\out\build\x64-debug\LINK : fatal error LNK1104: cannot open file 'python312.lib'
ninja: build stopped: subcommand failed.
Build failed.
So this is really weird. On the linker command-line it shows it's linking to python312_d.lib, and python312.lib isn't even part of the linker command-line call. Why would it complain that it can't find a file that is not part of its commandline-arguments anyway? Also: In my C:\Users\PatrikHuber\AppData\Local\Programs\Python\Python312\libs folder, I do have both python312.lib and python312_d.lib. So if it was needed, it should find it there. I think something odd is going on here.
Reproducible example code
See above.
For the full code, it's the devel branch of my library here https://github.com/patrikhuber/eos/tree/devel. It's self-contained and builds with vcpkg plus the rest of the dependencies from submodules (git submodule update --init --recursive).
Is this a regression? Put the last known working version here if it is.
Not a regression
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the CMake configurations from the issue using the eos devel branch and Python 3.12 on Windows. Trace pybind11Common.cmake line 228, pybind11Tools.cmake line 50, and FindPythonLibsNew.cmake line 114 to compare classic and new FindPython behavior. Done means the reported PythonInterp and debug-linking failures are explained and corrected or clearly isolated.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cmake, cpp, python
- Domain
- build-system, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 45/100