Skip to content
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

[READY] Do not rely on CMake to find Python libraries #481

Merged
merged 1 commit into from
May 9, 2016

Conversation

micbou
Copy link
Collaborator

@micbou micbou commented May 7, 2016

Problem

CMake is not able to find the Python libraries from pyenv. We can observe this on Travis. If we look at the build output of the Python 2.6 run on Linux, we have the following line during the CMake configuration:

-- Found PythonLibs: /usr/lib/libpython2.7.so (found suitable version "2.7.3", minimum required is "2.6")

which, in addition to be the wrong version, is the system library instead of the pyenv one. We confirm this by inspecting the ycm_core.so library from the build:

$ ldd ycm_core.so | grep python
libpython2.7.so.1.0 => /usr/lib/libpython2.7.so.1.0 (0x00007f0521fa1000)

Same issue with the Python 2.7 and 3.3 Linux runs although the library version is correct in these cases.
In the Travis configuration file, there is this comment:

This is because stupid cmake 2.8.11 has a bug preventing it from finding the pyenv pythons (ostensibly; I haven't checked, but online reports say the issue is gone with cmake 3.4).

I tried with CMake 3.5.1 (3.5.2 is the last version) and it is still not working.

That's not all. In some situations, CMake find the wrong Python system libraries (see this workaround on AppVeyor) or cannot find them at all (see this post on ycm-users).

Solution

From this, it is clear that we cannot rely on CMake to find the Python libraries. We need to find them in the build.py script and pass the PYTHON_LIBRARY and PYTHON_INCLUDE_DIR parameters to CMake, like we already do for OS X.
This is implemented by creating a FindPythonLibraries function for each supported platform: Linux, OS X, and Windows. For OS X, we are keeping the logic from CustomPythonCmakeArgs except that we are dropping support for system Python 2.6. For Linux, we need to use the ldconfig tool to find the system Python library on some distributions (e.g. Ubuntu) because it is not installed in its standard location. For Windows, it is straightforward. In all cases, we assume that the Python running the script is the one that will be used to build the library.

This PR also fixes an important issue. When building the ycmd library with Clang support and linking it to a non-system Python libray, the dynamic linker will not be able to find the Python library:

$ ldd ycm_core.so | grep python
libpython3.4m.so.1.0 => not found
$ objdump -x ycm_core.so | grep RPATH
RPATH                $ORIGIN

This is solved by setting the CMAKE_INSTALL_RPATH_USE_LINK_PATH option to true (see this wiki page for details on the option):

> ldd ycm_core.so | grep python
libpython3.4m.so.1.0 => /home/micbou/.pyenv/versions/3.4.4/lib/libpython3.4m.so.1.0 (0x00007f9fb6472000)
> objdump -x ycm_core.so | grep RPATH
RPATH                $ORIGIN:/home/micbou/.pyenv/versions/3.4.4/lib

Closes #196 (we don't care about the Python interpreter when building the ycmd library).
Fixes #479.


This change is Reviewable

@micbou micbou force-pushed the find-python-libs branch from 0e0d318 to bd7822b Compare May 7, 2016 14:36
@micbou
Copy link
Collaborator Author

micbou commented May 7, 2016

We need to clear Travis cache because the Python library from cached pyenv is not dynamic.


Reviewed 7 of 7 files at r1.
Review status: all files reviewed at latest revision, all discussions resolved.


Comments from Reviewable

@micbou micbou force-pushed the find-python-libs branch 2 times, most recently from 74a83be to 83ef584 Compare May 7, 2016 15:04
@coveralls
Copy link

Coverage Status

Coverage remained the same at 84.901% when pulling 83ef584 on micbou:find-python-libs into 8617de8 on Valloric:master.

@Valloric
Copy link
Member

Valloric commented May 7, 2016

I just cleared out all Travis caches.

Thanks for doing this! Yet Another Reason to never use Python for anything of importance ever again.

:lgtm:


Review status: all files reviewed at latest revision, 2 unresolved discussions.


build.py, line 44 [r1] (raw file):
"but no dynamic" reads weird. Could this be rephrased?


build.py, line 183 [r1] (raw file):
This python_name buildup is repeated from the find-on-linux function. Could you extract it into a function? Similar for other parts if possible, there appears to be some opportunity for helper funcs.


Comments from Reviewable

@puremourning
Copy link
Member

:lgtm: with one possible bug fix


Review status: all files reviewed at latest revision, 3 unresolved discussions.


build.py, line 213 [r1] (raw file):
Isn't this a tautology? Should it be if p.isfile( python_library )' ?


Comments from Reviewable

@micbou micbou force-pushed the find-python-libs branch 2 times, most recently from 94b6739 to c2db194 Compare May 7, 2016 19:15
@micbou micbou force-pushed the find-python-libs branch from c2db194 to 15f3d04 Compare May 7, 2016 19:19
@micbou
Copy link
Collaborator Author

micbou commented May 7, 2016

Reviewed 1 of 1 files at r2, 1 of 1 files at r3.
Review status: all files reviewed at latest revision, 3 unresolved discussions.


build.py, line 44 [r1] (raw file):
I changed it. Hope it's better formulated this way.


build.py, line 183 [r1] (raw file):
Done for the python_name, python_library_root, and python_include variables.


build.py, line 213 [r1] (raw file):
Yes, good catch.


Comments from Reviewable

@coveralls
Copy link

Coverage Status

Coverage remained the same at 84.901% when pulling 94b6739 on micbou:find-python-libs into 8617de8 on Valloric:master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 84.901% when pulling 15f3d04 on micbou:find-python-libs into 8617de8 on Valloric:master.

@vheon
Copy link
Contributor

vheon commented May 7, 2016

Reviewed 6 of 7 files at r1, 1 of 1 files at r2.
Review status: all files reviewed at latest revision, 3 unresolved discussions.


Comments from Reviewable

@puremourning
Copy link
Member

:lgtm:


Reviewed 6 of 7 files at r1, 1 of 1 files at r3.
Review status: all files reviewed at latest revision, 2 unresolved discussions.


Comments from Reviewable

@coveralls
Copy link

Coverage Status

Coverage remained the same at 84.901% when pulling 15f3d04 on micbou:find-python-libs into 8617de8 on Valloric:master.

@micbou micbou changed the title [RFC] Do not rely on CMake to find Python libraries [READY] Do not rely on CMake to find Python libraries May 8, 2016
@micbou
Copy link
Collaborator Author

micbou commented May 8, 2016

PR is ready. When this is merged, I'll send a PR to the YCM repository that updates the Travis configuration.

Previously, coveralls wrote…

Coverage Status

Coverage remained the same at 84.901% when pulling 15f3d04 on micbou:find-python-libs into 8617de8 on Valloric:master.


Review status: all files reviewed at latest revision, all discussions resolved.


Comments from Reviewable

@Valloric
Copy link
Member

Valloric commented May 9, 2016

Awesome!

@homu r+

@homu
Copy link
Contributor

homu commented May 9, 2016

📌 Commit 15f3d04 has been approved by Valloric

homu added a commit that referenced this pull request May 9, 2016
[READY] Do not rely on CMake to find Python libraries

### Problem

CMake is not able to find the Python libraries from `pyenv`. We can observe this on Travis. If we look at the build output of the Python 2.6 run on Linux, we have the following line during the CMake configuration:
```sh
-- Found PythonLibs: /usr/lib/libpython2.7.so (found suitable version "2.7.3", minimum required is "2.6")
```
which, in addition to be the wrong version, is the system library instead of the `pyenv` one. We confirm this by inspecting the `ycm_core.so` library from the build:
```sh
$ ldd ycm_core.so | grep python
libpython2.7.so.1.0 => /usr/lib/libpython2.7.so.1.0 (0x00007f0521fa1000)
```
Same issue with the Python 2.7 and 3.3 Linux runs although the library version is correct in these cases.
In the Travis configuration file, there is this comment:

> This is because stupid cmake 2.8.11 has a bug preventing it from finding the pyenv pythons (ostensibly; I haven't checked, but online reports say the issue is gone with cmake 3.4).

I tried with CMake 3.5.1 (3.5.2 is the last version) and it is still not working.

That's not all. In some situations, CMake find the wrong Python system libraries (see [this workaround on AppVeyor](https://github.com/Valloric/ycmd/blob/master/ci/appveyor/appveyor_install.bat#L36)) or cannot find them at all (see [this post on ycm-users](https://groups.google.com/forum/#!searchin/ycm-users/windows$20cmake/ycm-users/e6K-grbeUMw/0kzwtAaYCQAJ)).

### Solution

From this, it is clear that we cannot rely on CMake to find the Python libraries. We need to find them in the `build.py` script and pass the `PYTHON_LIBRARY` and `PYTHON_INCLUDE_DIR` parameters to CMake, like we already do for OS X.
This is implemented by creating a `FindPythonLibraries` function for each supported platform: Linux, OS X, and Windows. For OS X, we are keeping the logic from `CustomPythonCmakeArgs` except that we are dropping support for system Python 2.6. For Linux, we need to use the `ldconfig` tool to find the system Python library on some distributions (e.g. Ubuntu) because it is not installed in its standard location. For Windows, it is straightforward. In all cases, we assume that the Python running the script is the one that will be used to build the library.

This PR also fixes an important issue. When building the ycmd library with Clang support and linking it to a non-system Python libray, the dynamic linker will not be able to find the Python library:
```sh
$ ldd ycm_core.so | grep python
libpython3.4m.so.1.0 => not found
$ objdump -x ycm_core.so | grep RPATH
RPATH                $ORIGIN
```
This is solved by setting the `CMAKE_INSTALL_RPATH_USE_LINK_PATH` option to true (see [this wiki page](https://cmake.org/Wiki/CMake_RPATH_handling) for details on the option):
```
> ldd ycm_core.so | grep python
libpython3.4m.so.1.0 => /home/micbou/.pyenv/versions/3.4.4/lib/libpython3.4m.so.1.0 (0x00007f9fb6472000)
> objdump -x ycm_core.so | grep RPATH
RPATH                $ORIGIN:/home/micbou/.pyenv/versions/3.4.4/lib
```

Closes #196 (we don't care about the Python interpreter when building the ycmd library).
Fixes #479.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/valloric/ycmd/481)
<!-- Reviewable:end -->
@homu
Copy link
Contributor

homu commented May 9, 2016

⌛ Testing commit 15f3d04 with merge 3b135e1...

@homu
Copy link
Contributor

homu commented May 9, 2016

💔 Test failed - status

@micbou
Copy link
Collaborator Author

micbou commented May 9, 2016

Let's retry without the cache.

@homu r+

Previously, homu (Homu) wrote…

💔 Test failed - status


Review status: all files reviewed at latest revision, all discussions resolved, some commit checks failed.


Comments from Reviewable

@homu
Copy link
Contributor

homu commented May 9, 2016

💡 This pull request was already approved, no need to approve it again.

  • This pull request previously failed. You should add more commits to fix the bug, or use retry to trigger a build again.

@homu
Copy link
Contributor

homu commented May 9, 2016

📌 Commit 15f3d04 has been approved by micbou

@homu
Copy link
Contributor

homu commented May 9, 2016

💡 This pull request was already approved, no need to approve it again.

  • This pull request previously failed. You should add more commits to fix the bug, or use retry to trigger a build again.

@micbou
Copy link
Collaborator Author

micbou commented May 9, 2016

@homu retry

Previously, homu (Homu) wrote…

💡 This pull request was already approved, no need to approve it again.

  • This pull request previously failed. You should add more commits to fix the bug, or use retry to trigger a build again.

Review status: all files reviewed at latest revision, all discussions resolved, some commit checks failed.


Comments from Reviewable

homu added a commit that referenced this pull request May 9, 2016
[READY] Do not rely on CMake to find Python libraries

### Problem

CMake is not able to find the Python libraries from `pyenv`. We can observe this on Travis. If we look at the build output of the Python 2.6 run on Linux, we have the following line during the CMake configuration:
```sh
-- Found PythonLibs: /usr/lib/libpython2.7.so (found suitable version "2.7.3", minimum required is "2.6")
```
which, in addition to be the wrong version, is the system library instead of the `pyenv` one. We confirm this by inspecting the `ycm_core.so` library from the build:
```sh
$ ldd ycm_core.so | grep python
libpython2.7.so.1.0 => /usr/lib/libpython2.7.so.1.0 (0x00007f0521fa1000)
```
Same issue with the Python 2.7 and 3.3 Linux runs although the library version is correct in these cases.
In the Travis configuration file, there is this comment:

> This is because stupid cmake 2.8.11 has a bug preventing it from finding the pyenv pythons (ostensibly; I haven't checked, but online reports say the issue is gone with cmake 3.4).

I tried with CMake 3.5.1 (3.5.2 is the last version) and it is still not working.

That's not all. In some situations, CMake find the wrong Python system libraries (see [this workaround on AppVeyor](https://github.com/Valloric/ycmd/blob/master/ci/appveyor/appveyor_install.bat#L36)) or cannot find them at all (see [this post on ycm-users](https://groups.google.com/forum/#!searchin/ycm-users/windows$20cmake/ycm-users/e6K-grbeUMw/0kzwtAaYCQAJ)).

### Solution

From this, it is clear that we cannot rely on CMake to find the Python libraries. We need to find them in the `build.py` script and pass the `PYTHON_LIBRARY` and `PYTHON_INCLUDE_DIR` parameters to CMake, like we already do for OS X.
This is implemented by creating a `FindPythonLibraries` function for each supported platform: Linux, OS X, and Windows. For OS X, we are keeping the logic from `CustomPythonCmakeArgs` except that we are dropping support for system Python 2.6. For Linux, we need to use the `ldconfig` tool to find the system Python library on some distributions (e.g. Ubuntu) because it is not installed in its standard location. For Windows, it is straightforward. In all cases, we assume that the Python running the script is the one that will be used to build the library.

This PR also fixes an important issue. When building the ycmd library with Clang support and linking it to a non-system Python libray, the dynamic linker will not be able to find the Python library:
```sh
$ ldd ycm_core.so | grep python
libpython3.4m.so.1.0 => not found
$ objdump -x ycm_core.so | grep RPATH
RPATH                $ORIGIN
```
This is solved by setting the `CMAKE_INSTALL_RPATH_USE_LINK_PATH` option to true (see [this wiki page](https://cmake.org/Wiki/CMake_RPATH_handling) for details on the option):
```
> ldd ycm_core.so | grep python
libpython3.4m.so.1.0 => /home/micbou/.pyenv/versions/3.4.4/lib/libpython3.4m.so.1.0 (0x00007f9fb6472000)
> objdump -x ycm_core.so | grep RPATH
RPATH                $ORIGIN:/home/micbou/.pyenv/versions/3.4.4/lib
```

Closes #196 (we don't care about the Python interpreter when building the ycmd library).
Fixes #479.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/valloric/ycmd/481)
<!-- Reviewable:end -->
@homu
Copy link
Contributor

homu commented May 9, 2016

⌛ Testing commit 15f3d04 with merge b338481...

@homu
Copy link
Contributor

homu commented May 9, 2016

☀️ Test successful - status

@homu homu merged commit 15f3d04 into ycm-core:master May 9, 2016
@micbou micbou deleted the find-python-libs branch May 9, 2016 09:52
homu added a commit that referenced this pull request May 10, 2016
[READY] Remove architecture option in scripts

With the changes from PR #481, the `--arch` option cannot be used anymore to specify the architecture on Windows because the architecture of the Python library is now the same as the Python interpreter running the `build.py` script and this architecture must match the one used to compile ycmd.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/valloric/ycmd/484)
<!-- Reviewable:end -->
homu added a commit to ycm-core/YouCompleteMe that referenced this pull request May 10, 2016
[READY] Update Travis configuration

Update ycmd to include PR ycm-core/ycmd#481 and update Travis configuration according to this PR.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/2157)
<!-- Reviewable:end -->
homu added a commit to ycm-core/YouCompleteMe that referenced this pull request May 10, 2016
[READY] Update Travis configuration

Update ycmd to include PR ycm-core/ycmd#481 and update Travis configuration according to this PR.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/2157)
<!-- Reviewable:end -->
@micbou
Copy link
Collaborator Author

micbou commented May 16, 2016

Thanks for the heads up. We'll take care of that in the next iteration.

@micbou
Copy link
Collaborator Author

micbou commented May 19, 2016

@ff2000 Could you try PR #499 and tell us if it works for you?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Ycmd build system assumes that the current python on OSX is the same to compile ycmd for.
7 participants