-
Notifications
You must be signed in to change notification settings - Fork 2.2k
CMake installation path consistency #652
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
Conversation
If you are fine with this, I will open another PR which will use the |
With this PR, the headers are placed into A better way to do this would be to just give CMake a different Note that switching the header install location from |
The correct solution is to fix the |
Note that |
5ba0d11
to
c1dd58e
Compare
Yeah only on unix platforms. But my change handles the windows case too. If you are using homebrew python, this is different, but I want to see if there is buy-in for this approach before I work on adjusting the tests for cmake. |
Eventually, I would like the (Very much like pyzmq's setup.py which can either bundle zeromq for pypi, or optionally link with an already provided version). This option will then be used by e.g. the conda recipe so that pybind11 users who rely on the conda package should be able to use it with both distutils and cmake. |
I would personally love that. Even more if it was also available with But I think there are still some issues with the current implementation:
|
(Item 1 is more an issue with the implementation of the tests IMO.) |
Quick precision: the header path is not absolute, it is relative to the install prefix unless the found python version is outside of it.
That is right (also it is the point of the PR). It would probably make sense to provide a cmake option to pass a specific python prefix. |
Yea, it would be nice to have a way of getting headers installed into |
That is not what I meant. What I meant is always have the headers in the python include path (even with cmake install like in this PR) but enable the use cmake to produce the |
What's the suggested way of having the headers installed to prefix/include then? |
We would not enable this. EDIT: would you want an option to do so? (I don't think that it would be a good idea for the reasons above). |
If I'm understanding this right, if I install using Python 2.7 as the python version for cmake, then later try to use find_package (but now under Python 3.5), I'm going to end up with both Python 2.7 and Python 3.5 include directories in my search path. That seems horribly wrong. |
I'm all for the conda package putting the headers in a CMake-expected location and actually installing the pybind11Config (See conda-forge/pybind11-feedstock#11). But I don't think From CMake, places to search for nameConfig:
|
In a given install environment, only one version of python can exist at a time. The python version found by cmake at install time.
Side note: Having the headers as package data like numpy causes a lot of pain to users who need to use a numpy's runtime to tell them where its headers are located. Distutils' This PR makes the cmake installation of pybind11 consistent with distutils. Since the opposite is not possible. |
Yes. That's exactly the problem. With this patch, the install environment python version is the only one that can be used by cmake pybind11-using projects, while the python version to build against is supposed to be configurable (e.g. by setting Given that there can only be one
|
My point too, headers are completely interpreter-version-independent. Also, with conda in mind, all conda packages I've ever seen (on Linux/Mac that is, bar numpy) install non-Python-specific headers to |
We could put this new behavior behind an option for cmake. This would allow distributing the |
I'm not keen on moving the (cmake + make)-built pybind11 headers from But what is the need to shift pybind11Config into site-pkgs? Distutils, I think, doesn't care about it unless to build the conda pkg, and one can use cmake for that step. Switching conda envs from 2.7 to 3.5 would force switching out the pybind11_py27 package for the 35, so Config would be in the same python-indep place and able to point to the correct py-dep headers location. EDIT: Sorry, I was a behind on reading the thread.. |
The goal of this is for users of the conda recipe who author packages depending on pybind11 to use either cmake or distutils to package it. |
Btw, just to clarify, latest conda (4.3) now supports Python-type noarch packages, so instead of the almost identical |
Yeah, the issue with conda noarch is that they have a whitelist of file formats that are ok with it (at least it was like this for it). |
So I set this behavior behind a flag so that we can use it in the context of the conda-forge recipe. |
Shouldn't the flag also disable installing the cmake script? |
I don't understand what you mean? |
With this feature enabled, isn't a |
I think installing |
In that case I don't see what the flag addresses: it still installs something into a non-python-specific path that breaks projects that want to use python major/minor versions other than the one that last installed using the flag. (Except now it also seems like I could have a working pybind11 version-independent installation, then via a dependency, end up breaking my version-independent installation by replacing/overriding its pybind11Tools.cmake with one that is going to inject wrong-version python headers into my search path). |
To back up several steps: Can someone explain to me in a concise way what the specific benefits are of installing pybind11 headers into a python-version-specific include directory? |
Yes, that is the point of the PR. It is installed in the conda cmake configuration directory. I make a more detailed explanation in the next post. |
Just to make sure we're all on the same page here (I think we've been talking past each other a bit), there are three ways to install pybind11, which all do slightly different things.
I think we should specify which install method we're talking about to avoid confusion. |
|
So, my main points here are:
|
It might be possible to place them under |
The only other thing would be to change setup.py to not install the headers is some environment variable |
Thanks @dean0x7d, it seems reasonable to me now. I think the flag should have a big warning comment above it that this will break multi-Python environments, but otherwise seems reasonable. |
CMakeLists.txt
Outdated
@@ -92,6 +92,11 @@ endforeach() | |||
set(${PROJECT_NAME}_VERSION ${PYBIND11_VERSION_MAJOR}.${PYBIND11_VERSION_MINOR}.${PYBIND11_VERSION_PATCH}) | |||
message(STATUS "pybind11 v${${PROJECT_NAME}_VERSION}") | |||
|
|||
option (USE_PYTHON_INCLUDE_DIR "Install pybind11 headers in Python include directory" OFF) |
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.
The comment could be more explanatory: "Install [..] within the Python include directory instead of the default installation prefix"
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.
Makes sense.
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.
Done.
928d4fb
to
695866c
Compare
I added a commit which disables the header installation in setup.py if a certain environment variable is set. |
I echo @dean0x7d that there should be a warning with
Other than warnings, I've no objection to the current state of the PR and am grateful that @SylvainCorlay has taken up the reconciliation of the distutils/cmake directory structures. But is there any reason why the same effect couldn't be gotten by installing headers into |
So on windows, the change to that would merely be to replace I am neutral on this proposal. The advantage of the current approach over this is only in the case where this proves useful in a different context than conda. Homebrew has a different directory structure for example. |
@SylvainCorlay: I deleted the old package. |
@wjakob The one in the pybind anaconda org remains. |
Hey, do you guys need anything else for this to get in? |
Sorry, I'm just swamped with work and haven't had time to sit down and do proper code reviews in the last couple of weeks. |
Hi -- I took a look just now. I don't understand the |
This environment variable can be set externally to disable the installation of the headers by setup.py.
In the conda recipe for pybind11, we would set it prior to call setup.py and perform a cmake install for the headers.
In doing so, we will have both the pybind11 python module, and the Pybind11Config.cmake files included in the package.
Then, users who build upon pybind11 will be able to use either `find_package` or `pip`. Besides, if they simply pip install a package that depends on pybind, it will correctly see it as installed...
Sylvain
|
Ok, that makes sense! -- I'll merge the PR then. |
Problem:
In a given installation PREFIX,
pip install pybind11
orconda install pybind11
will install pybind11 headers into a newpybind11
subdirectory of the python include directory, whilecmake + make install
results in pybind11 headers being put intoPREFIX/include/pybind11
.For example, with a conda installation, pip will give
PREFIX/include/pythonX.Y/pybind11
while cmake yieldsPREFIX/include/pybind11
.It would be nice to have a consistent installation scheme between the two methods, plus the benefit of having the cmake project config files being made available, in the context of conda.
Solution:
This changes the destination of the headers of pybind into
PYTHON_INCLUDE_DIRS/pybind11
.The generated project config cmake files are installed in the same location as before, but reflect the new location of the headers.