Skip to content

Conversation

@aldanor
Copy link
Member

@aldanor aldanor commented Jun 19, 2017

Please correct me if I'm wrong; I've double-checked this today on ubuntu's python3-dev and pyenv Python on OS X:

  • On Linux, it doesn't build without -fPIC explicitly specified
  • python-config --ldflags is unnecessary
  • On Python 3, one has to use python3-config
  • On Mac OS, it doesn't build without -undefined dynamic_lookup

The changes to the docs reflect all of the above points.

@jagerman
Copy link
Member

  • Other places in the docs default to talking about Python 3 [for example, the string/unicode page], so I think python-config should be python3-config with a note to use python-config if building for Python 2 (rather than the other way around).
  • Is the full --cflags necessary? I usually just use --includes when compiling something simple.
  • If embedding, you'll want python3-config --libs (rather than --ldflags). For modules, you shouldn't need either. Right now we don't mention compiling for embedding at all; it's probably worth adding an extra paragraph for compiling a simple embedded python example.
  • For Python 3, instead of the output name example.so it would be better to use example`python3-config --extension-suffix` for Python 3. That appears to work for python-config as well (giving just .so), but doesn't seem to be supported by macOS's system python (perhaps it was added after 2.7.10?).

@jagerman
Copy link
Member

-Wall might be a useful addition as well.

@aldanor
Copy link
Member Author

aldanor commented Jun 20, 2017

Other places in the docs default to talking about Python 3 [for example, the string/unicode page], so I think python-config should be python3-config with a note to use python-config if building for Python 2 (rather than the other way around).

Makes sense, crossed my mind as well.

Is the full --cflags necessary? I usually just use --includes when compiling something simple.

Yea, --includes should be sufficient. --cflags just adds -g -O3 -fwrapv and enables a bunch of warnings (it's a bit weird it doesn't list -fPIC on Linux though).

If embedding, you'll want python3-config --libs (rather than --ldflags). For modules, you shouldn't need either. Right now we don't mention compiling for embedding at all; it's probably worth adding an extra paragraph for compiling a simple embedded python example.

Yea, I've removed --ldflags. already I don't know much about building embedded stuff, but it should probably be documented too at some point.

For Python 3, instead of the output name example.so it would be better to use examplepython3-config --extension-suffix for Python 3. That appears to work for python-config as well (giving just .so), but doesn't seem to be supported by macOS's system python (perhaps it was added after 2.7.10?).

Ditto, --extension-suffix doesn't seem to work on macOS system python.

@aldanor
Copy link
Member Author

aldanor commented Jun 20, 2017

With all this in mind, I wonder... should we just ship a pybind11-config script or is that too much?

(To think about it, I've actually done something very similar in ipybind (which also works on Windows), maybe it should just expose pybind11-build entry point for all the building logic so its accessible from command line.)

@aldanor
Copy link
Member Author

aldanor commented Jun 20, 2017

Added -Wall; changed --cflags to --includes; changed python-config to python3-config.

@jagerman
Copy link
Member

It looks like --extension-suffix comes from a debian-applied patch to Python 2.7. It's still definitely the right thing to do for Python 3, though. Maybe a note for Python 2 users?

@aldanor
Copy link
Member Author

aldanor commented Jun 20, 2017

Fair enough; added --extension-suffix to the default commands + a note to the poor py2 users.

@dean0x7d
Copy link
Member

dean0x7d commented Jun 23, 2017

+1 for updating the manual build commands. The Python 2/3 and platform nuances can be frustrating to figure out, so this should help a lot.

One thing I would strongly suggest is moving the instructions from "First steps" to a new section in "Build systems" and replacing the section in "First steps" with a link to the example repositories. Those are much simpler to set up (pip install .) and just start experimenting with some simple binding code, which is the point of "First steps".

@jagerman
Copy link
Member

This seems worth including in 2.2 (so that it ends up in the default stable documentation). @aldanor - when you have a chance, can you update this PR to move the section (as per @dean0x7d's suggestion) and use the nifty new #921 commands for the includes?

@jagerman jagerman added this to the v2.2 milestone Jul 23, 2017
@aldanor
Copy link
Member Author

aldanor commented Jul 23, 2017

I've moved the build notes to "Build systems" section and updated it to use python -m pybind11 --includes, it now looks quite a bit simpler. I've added references to this section from "First steps" but didn't add links to example repos there as they're mentioned in "Build systems" anyway -- arguably, the easiest way to compile a module is to do it manually, still.

@aldanor
Copy link
Member Author

aldanor commented Jul 23, 2017

(My rst-fu is pretty bad, I hope that :ref:compiling link would actually work)

pybind11 is a header-only-library, hence it is not necessary to link against
any special libraries (other than Python itself).

On Linux, the above example can be compiled using the following command:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no "above" anymore. Perhaps:

On Linux, you can compile an example such as the ones given in
:ref:`simple_example` using the following command:

with an addition of:

.. _simple_example:

in basics.rst just before:

Creating bindings for a simple function
=======================================

Note that on Python 2.7.x ``python-config`` has to be used instead of
``python3-config`` in the command above. Besides, ``--extension-suffix``
option may or may not be available, depending on the distribution; in the latter
case, the module extension can be manually set to ``.so``.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this whole paragraph is slightly obsolete by the #921 changes (since the only python3-config is now the extension suffix one). Perhaps just simplify it to:

Note that Python 2.7 modules don't use a special suffix, so you should simply use `example.so` instead of ``example`python3-config --extension-suffix```.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is the link to the Python library in this command? I need something like:

$ c++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` `python3-config --libs` example.cpp -o example`python3-config --extension-suffix`

I'm also on macOS and didn't been the --undefined dynamic_lookup part, at least for the built-in Python 2 and the sample in #1041.

Copy link
Member

@wjakob wjakob Aug 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Linux, it's better to (intentionally) not link against libpython. The symbols will be resolved when the extension library is loaded into a Python binary. This is preferable because you might have several different installations of a given Python version (e.g. the system-provided Python, and one that ships with a piece of commercial software). In this way, the plugin will work with both versions, instead of possibly importing a second Python library into a process that already contains one (which will lead to a segfault).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, so I traded the undefined for the link. Nevermind, then! Thanks.

@jagerman
Copy link
Member

(My rst-fu is pretty bad, I hope that :ref:compiling link would actually work)

You can make -C docs html SPHINX_OPTIONS=-w then see how it turned out in docs/.build/index.html. (There are some dependencies--see the docs build in .travis-ci.yml).

@dean0x7d
Copy link
Member

arguably, the easiest way to compile a module is to do it manually, still.

I'm not sure about that. I can easily remember the two lines of CMake needed in the simplest case, but for the manual build I always need to refer to the docs to copy/paste the exact flags (and still watch out for the special cases). In my opinion, the manual build only has the advantage if:

  1. You just want to compile a one-off example.
  2. You already know what you're doing -- there are still caveats related to Python versions, distributions (Anaconda has its own command line build quirks) and platforms (Windows is completely out of the picture).

The "First Steps" section should really be about what's easiest to learn but also what's most useful for future expansion. Users will naturally want to connect the binding code with a larger Python or C++ project and that will require a proper build/distribution system. The manual build doesn't offer that, so that means users learn something only to drop it and go in a completely different direction.

The example repos offer a dead simple way to get started:

git clone <repo_url>
pip install ./<example_name>

From there it's easy to build on and experiment without worrying about Python versions/distributions or operating systems.

So my suggestions are:

  1. "Building manually" should be the last section of compiling.rst, not the first.
  2. I'd still link to the example repos in "First Steps" in order to recommend them as the easiest way to get started.

@wjakob
Copy link
Member

wjakob commented Aug 21, 2017

I think it's nice to at least mention the 1-line compile command to make it crystal clear that there is no magic happening in the background (compiling extra libraries, etc :)).

@dean0x7d dean0x7d mentioned this pull request Aug 23, 2017
6 tasks
@dean0x7d
Copy link
Member

Since this would be very useful to have for the v2.2 release, I've pushed some changes to complete the docs, incorporated suggestions by @jagerman and I copy/pasted @wjakob's comment about linking to libpython (useful note for the docs and nicely worded in the comment). The 1-line compile command is back in basics.rst, but without all the variants and details (just a link to the detailed section). Also mentioned the example repos as a good starting point.

How does it look to everyone?


.. code-block:: bash
$ c++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` example.cpp -o example`python3-config --extension-suffix`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assumes that pybind11 has been installed using pip or conda, which may be worth mentioning.

Copy link
Collaborator

@henryiii henryiii Aug 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it hasn't, this needs to be the Python include directory (python-config3 --includes) and PyBind's include directory, as that command incorporates both. (Not sure if that's worth mentioning, just added it for completeness)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be addressed by the latest commit.


Note that Python 2.7 modules don't use a special suffix, so you should simply
use ``example.so`` instead of ``example`python3-config --extension-suffix```.
Besides, ``--extension-suffix`` option may or may not be available, depending
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing 'the' before --extension-suffix

@wjakob
Copy link
Member

wjakob commented Aug 30, 2017

Looks great (I added two minor comments)

@dean0x7d dean0x7d merged commit 5cbfda5 into pybind:master Aug 30, 2017
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.

5 participants