pybind / pybind11

Seamless operability between C++11 and Python
https://pybind11.readthedocs.io/
Other
15.7k stars 2.1k forks source link

Linking additional libraries in CMake pybind11_add_module() #387

Closed lathen closed 8 years ago

lathen commented 8 years ago

I'm not very experienced with CMake so I'm sure there's a simple solution to this. I'm adding an issue since it could be useful to add the reply to the docs.

I have additional libraries that I need to link to the target Python module, basically adding elements to the target_link_libraries command in pybind11_add_module(). I understand that one solution would be to setup everything manually, i.e. replicating the stuff in pybind11_add_module() in my project's CMakeLists. But I would rather use the pybind11_add_module() function since this makes everything really clean. Is there a way to tell CMake to add additional link libraries or does pybind11_add_module() need to be extended with additional arguments?

Ping also the contributor in #207 (@dean0x7d)

wjakob commented 8 years ago

target_link_libraries is what you want, you can just specify the target name of the pybind11 module.

lathen commented 8 years ago

Ah, I actually tried this orginally but got the message The keyword signature for target_link_libraries has already been used and immediately assumed that you could only use target_link_libraries once. But it was the PRIVATE keyword that was missing in my additional call to target_link_libraries. So now all is fine. Maybe this was a bit too silly to add to the docs, I should have investigated the error message further.. Don't bother - we'll close this!

Thanks btw for an awesome library, I'm also a huge fan of NanoGUI :thumbsup:

mivade commented 7 years ago

On the contrary, I think showing this in the docs would be extremely helpful. I was getting the same CMake error mentioned above and, given my relative inexperience with CMake, had no idea what that was supposed to mean.

wichert commented 6 years ago

I ran into this as well, and ended up here with a Google search. I still doesn't work for me though. My first attempt based on this ticket was to use target_link_libraries with PRIVATE. This broke with:

  Target "stylist" of type MODULE_LIBRARY may not be linked into another
  target.  One may link only to STATIC or SHARED libraries, or to executables
  with the ENABLE_EXPORTS property set.

I ended up with this:

find_package(Stylist REQUIRED)
include_directories(SYSTEM ${Stylist_INCLUDE_DIRS})
link_directories(${Stylist_LIBRARY_DIRS})

add_subdirectory(pybind11)
pybind11_add_module(_stylist SHARED ${SOURCES})
target_link_libraries(_stylist PRIVATE ${Stylist_LIBRARIES})

Which still fails:

>>> import _stylist
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define module export function (PyInit__stylist)
Abhijit-2592 commented 6 years ago

@lathen did you solve the error?

jagerman commented 6 years ago

@Abhijit-2592 - yes, see the second post (about needing the PRIVATE keyword).

(Also, for future visitors, note that @wichert 's "still fails" error was unrelated--it was a mismatch between the compiled .so filename and the module specified in the PYBIND11_MODULE macro; see #1271).

GliderGeek commented 6 years ago

I have a similar, but slightly different problem. It would like to link another pybind11 module.

Am trying to create the following two modules:

Anyone suggestions on how to fix this? i have described my problem in more detail in a SO question.

jagerman commented 6 years ago

line: can be called directly and also uses point module.

Try adding a py::module::import("point"); in the line binding code to get Python to load the point module before you do anything in line that relies on it (i.e. near the beginning of your PYBIND11_MODULE code).

GliderGeek commented 6 years ago

That doesn't do the trick unfortunately. There were a few other suggestions on the gitter channel which are similar, but didn't work:

py::object point = (py::object) py::module::import("point");
py::module point = py::module::import("point");
soulslicer commented 6 years ago

I can't get any of my 3rd party libraries to work. I set target_link_libraries, but it still complains of undefined symbols..

nvmind this worked

target_link_libraries(mymodule PRIVATE pybind11::module ${ITK_LIBRARIES})

Dariusz1989 commented 6 years ago

Same here, I'm trying to add QT library but pybind11 is not allowing. To be honest, seeing that pybind11 is cmake based I though that this will be easy. But yet here I am 3 days alter questioning the universes....

How on earth do we get this stuff to work ?!

I've got this, target_link_libraries(${PROJECT_NAME} Qt5::Widgets Qt5::Core Qt5::Gui Qt5::Network Qt5::Qml Qt5::Quick Qt5::Multimedia Qt5::MultimediaWidgets Qt5::Concurrent opengl32.lib)

How to add pybind11 to this I have no idea ;[

TIA.

BIGBALLON commented 5 years ago

@lathen thanks for your answer!! It works well!!!

eythimis commented 3 years ago

Thanks @lathen :)

qgbcs commented 10 months ago

target_link_libraries是你想要的,你可以只指定 pybind11 模块的目标名称。

-- Found pybind11: /opt/vcpkg/installed/x64-linux/include (found version "2.11.1") CMake Error at CMakeLists.txt:84 (target_link_libraries): The keyword signature for target_link_libraries has already been used with the target "cashflow". All uses of target_link_libraries with a target must be either all-keyword or all-plain.

The uses of the keyword signature are here: