-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: CMake update, part 1 #2338
Conversation
fix: include PYTHON_IS_DEBUG
Beware of Were there now talks to preserve some legacy support for old CMake? I'd happily drop that, actually. CMake 3.7 is +3.5 years old (https://cmake.org/pipermail/cmake/2016-November/064540.html), so we can't keep up support forever. |
@wjakob made this the minimum for now, based on Debian oldstable (see https://cliutils.gitlab.io/modern-cmake/chapters/intro/installing.html#full-list ) . Personally, I think it's easier to tell users to update CMake than to maintain old code and the bugs in older versions which cause issues (I see quite a few in our issue tracker that would have been fixed by updates to CMake), and your CMake should always be newer than your compiler, and CMake is not required if you just want to use the library, you can pip install it, it's extremely backward compatible, etc... But I do understand wanting to keep older CMake support, and I support 3.4+ currently with CLI11, so I guess I'm not one to talk. ;) |
No, I completely agree. If it's been 3.5 years, we should be able to drop some of the burden! |
On: docs/compiling.rst Before, we hacked in the compile flags for visibility into the target, and it showed - we were breaking on mixed language builds and compilers where we didn't know the correct flags to add. The point of If CMake added an |
Sorry, because of GitHub's clipping of the changelog, I completely missed that this is for the EDIT: Same discussion happened here: #995 (comment) |
We link to |
I addressed the |
9ca5ebc
to
56a9f9c
Compare
I found a nice CMake format tool, this is more like the old format, everything is now consistent, and pre-commit checked too! :) |
Added more protections for the Py2.7 flag, and added a flag for windows C++17 + Py 2.7. I didn't protect the Win flag with CXX; if you use it with CUDA, this might break it (and to enable Windows 2.7 support only, that would be a shame). I don't use CUDA + MSVC, though, so not sure. Fixed a small typo in master that was not making warnings errors. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @henryiii -- it looks great! A few comments/questions from my end.
@@ -0,0 +1,69 @@ | |||
parse: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First time I heard about .cmake-format, that's neat! One related question: we're beginning to "clog up" the root directory with many dot-files related to CI infrastructure. Can we move them to '.github' as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Putting them in .github
is probably a bad idea, as the files in there have special meanings for GitHub - like .github/CONTRIBUTING.md
, issue templates, pull request templates, actions, workflows, etc. But this one could go anywhere, such as in tools
. The problem is that if you try to run cmake-format
from the command line, it will pick this up only if it's in the main folder. However, I would expect this and all the other formatters to only be run by pre-commit
, so that's not a big deal. The .pre-commit-config.yaml
file needs to be in the main folder. I rather think the .clang-format
file will need to be in the main folder (IIRC, -style=file
is the parameter you run, which doesn't include a path).
These are all just dot files, so they only make the main GitHub page longer (which is still a little irritating, but a common issue, especially for Python).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(My general rule is that I always use the default name/location if something expects it, so tools "just work" if someone tries to run them; but if there's not special meaning to a name/path, I put it in a folder to keep the page clean)
Dropping the changlog here - will fill out and finish in part 2: v2.6.0 (IN PROGRESS)
-----------------------------------------------------
* CMake 3.7 or newer is now required, with newer versions strongly preferred.
`#2338 <https://github.com/pybind/pybind11/pull/2338>`_.
Several details of the CMake support have been deprecated; warnings will be
shown if you need to change something. The changes are:
* ``PYBIND11_CPP_STANDARD=<platform-flag>`` is deprecated, please use
``CMAKE_CXX_STANDARD=<number>`` instead, or any other valid CMake CXX or CUDA
standard selection method, like ``target_compile_features``.
* If you do not request a standard, PyBind11 targets will compile with the
compiler default, but not less than C++11, instead of forcing C++14.
* Direct ``pybind11::module`` usage should always be accompanied by at least
``set(CMAKE_CXX_VISIBILITY_PRESET hidden)`` or similar - it used to try to
manually force this compiler flag (but not correctly on all compilers or with
CUDA).
* ``pybind11_add_module``'s ``SYSTEM`` argument is deprecated - this now behaves
like other imported libraries in both config and submodule mode, and behaves
like a ``SYSTEM`` library by default.
* CMake 3.9+ will use CMake's built-in ``INTERPROCEDURAL_OPTIMIZATION`` instead
of a custom flag discovery algorithm - set ``PYPBIND11_CLASSIC_LTO`` to force
the old system on all CMake versions. ``THIN_LTO`` has no effect when the new
system is being used, it will select the ``thin_lto`` as applicable. |
Timed out error on appveyor, can be ignored. I don't have permission to restart the appveyor builds. |
I restarted it |
See pybind/pybind11#2338 Add CMP0069 (addressing the pybind11 cmake update for IPO) and CMP0074 at right places.
This is a complete CMake update, part 1 of approximately 2. The key themes are better use of CMake built-in features, better consistency between subdirectory and config mode, and a more deterministic config file. This will enable new features in subsequent PRs.
CMake 3.7 or better is now required
This enables many simplifications, and a more unified approach to targets. Many if statements dropped, though a few more added for enhanced support for later CMake versions.
Reworked C++ support to properly handle C++ version in CMake instead manually
CMake 2.8, which came out three years before 2011, does not have C++11 support (hopefully not a surprise, though given the number of people that seem to want to use a new compiler with a CMake version that significantly predates it, I'm not sure). Now it does, so PyBind11 plays nice with C++ support! FINALLY! Key points:
PYBIND11_CPP_STANDARD
is deprecated, and issues a warning. It does still work, though, just grabbing the last two digits and settingCMAKE_CXX_STANDARD
with it.CMAKE_CXX_STANDARD
is not required - CMake knows that pybind requires at least C++11 support, and will automatically add at least the C++11 flag if needed to any target that links to it (via compile features) if the compiler has a default less than C++11.CMAKE_CXX_STANDARD
(global) or CXX_STANDARD (per target, not inherited)Closes #1097
If-less config files
The config file generated will not depend on the host system - this is a requirement for the CMake config files to be distributed in a pure python wheel - which can't know what the host compiler / python version is beforehand. Generator expressions are used, which are evaluated during the build, rather than before.
Note: there are two ifs that affect the configs: If you generate the file with CMake 3.13+, it cannot be read by 3.7-3.12. However, this is much better than before, were you couldn't change much of anything after generating a Config file, and crucially, the 3.13+ one has a lower potential for bugs (it enforces that the dynamic lookup does not get de-duplicated accidentally). The main planned user of this feature is PyPI package, and there should be no problem getting CMake 3.13+ using pip.
Key first step for #2266!
PS: Normal if's in the Config.in are fine, just not if's making the targets themselves in the main file.
SYSTEM changes
The current handling of SYSTEM is not consistent with CMake standards. CMake treats all IMPORTED targets as SYSTEM, so this was/is always on when using configuration mode. This now treats Python always as SYSTEM (may fix the warning we struggled with for a while), and treats PyBind11 as SYSTEM when being used as a subdirectory, consistent with the config mode. The SYSTEM argument to
pybind11_add_module
is no longer needed and is inconsistent withtarget_link_libraries
. A warning is printed if given. You can always setNO_SYSTEM_FROM_IMPORTED
if you want to make imported targets non-system.Smaller features
pybind11_VERSION*
andPROJECT_VERSION*(
, picked up correctly by CMake wherever it's needed (for example, by CPack)BUILD_TESTING
flag is now supported, along withPYBIND11_TEST
include(CTest)
here, which setsBUILD_TESTING
up for you, but I could.pybind11::module
target; it caused issues (closes pybind11 incorrectly adds "-fvisibility" flag to nvcc #1710, combined with flto change closes CXX flags passed to nvcc using CMake make compilation fail #1991), it went against the description (simplest possible flags), it clashes with the correct way to do this in thepybind11_add_module
function, and is better handled by a nice example (added to the docs).PYPBIND11_CLASSIC_LTO
to force the old search method and manual flags-DPy_DEBUG
with cmake #2018This has gotten large enough, so I'll be working on new FindPython support in the next PR. Also, we currently might be a bit sloppy about putting build products in the source tree - I'll investigate that in the near future, too. This is mostly focused on correctness, which should make alternate compilers, CUDA, and such easier to support (since we are relying on CMake to support them, rather than trying to hardcode everything ourselves), but we do get 5 or so issues closed with this (not counting 1-2 of mine). This also should enable CMake configs in the python wheel, which when mixed with PEP 518 builds and scikit-build, could make something truly beautiful. :)
As a further test, I dropped this into boost-histogram (CMake mode) and awkward1 (both submodule systems) and verified that no changes were needed, it is backward compatible and still builds correctly locally.
Upgrade guide:
Several details of the CMake support have been deprecated; warnings will be shown if you need to change something. The changes are:
PYBIND11_CPP_STANDARD=<platform-flag>
is deprecated, please useCMAKE_CXX_STANDARD=<number>
instead, or any other valid CMake CXX or CUDA standard selection method, liketarget_compile_features
.pybind11::module
usage should always be accompanied by at leastset(CMAKE_CXX_VISIBILITY_PRESET hidden)
or similar - it used to try to manually force this compiler flag (but not correctly on all compilers or with CUDA).pybind11_add_module
'sSYSTEM
argument is deprecated - this now behaves like other imported libraries in both config and submodule mode, and behaves like aSYSTEM
library by default.INTERPROCEDURAL_OPTIMIZATION
instead of a custom flag discovery algorithm - setPYPBIND11_CLASSIC_LTO
to force the old system on all CMake versions.THIN_LTO
has no effect when the new system is being used, it will select thethin_lto
as applicable.