Почему вам не нужно делать target_link_libraries при использовании Eigen с pybind11

Я пытался скомпилировать это example.cpp из учебника по pybind11 под названием pybind11_examples на GitHub.

#include <pybind11/pybind11.h>
#include <pybind11/eigen.h>

#include <Eigen/LU>
#include <iostream>

// ----------------
// regular C++ code
// ----------------

Eigen::MatrixXd mul(const Eigen::MatrixXd &xs, double fac)
{
    std::cout << "Double" << std::endl;
    return fac*xs;
}

Eigen::MatrixXi mul(const Eigen::MatrixXi &xs, int    fac)
{
    std::cout << "Int" << std::endl;
    return fac*xs;
}

// ----------------
// Python interface
// ----------------

namespace py = pybind11;

PYBIND11_MODULE(example,m)
{
  m.doc() = "pybind11 example plugin";

  // N.B. the order here is crucial, in the reversed order every "int" is converted to a "double"
  m.def("mul", py::overload_cast<const Eigen::MatrixXi &,int   >(&mul) );
  m.def("mul", py::overload_cast<const Eigen::MatrixXd &,double>(&mul) );
}

и соответствующий CMakeLists.txt файл

cmake_minimum_required(VERSION 2.8.12)
project(example)

set (CMAKE_CXX_STANDARD 14)

find_package( PkgConfig )
pkg_check_modules( EIGEN3 REQUIRED eigen3 )
include_directories( ${EIGEN3_INCLUDE_DIRS} )

add_subdirectory(pybind11)
pybind11_add_module(example example.cpp)

У меня есть одно замешательство: почему нам не нужно связывать Eigen с example. Это потому, что Eigen — это библиотека только для заголовков, поэтому include_directories достаточно? Тогда что мне делать с библиотеками, не предназначенными только для заголовков?

Заранее спасибо!

IIRC Eigen — это библиотека только для заголовков, что означает, что весь код находится в файлах .h, и ваш проект его компилирует.

user253751 09.02.2023 18:34
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
58
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Обновлено: Чтобы ответить на ваш вопрос о том, что делать с библиотеками не только для заголовков:

Pybind11 pybind11_add_module работает так же, как CMakes add_executable или add_library, он определяет цель (первый аргумент), с которой вы затем можете связать. В твоем случае:

#Rest of the CMakeLists.txt...

pybind11_add_module(example example.cpp)

target_link_libraries(example my_library)

#Rest of the CMakeLists.txt...

Как уже писал пользователь @user253751 в комментариях. Eigen — это библиотека только для заголовков. Вы можете убедиться сами на их домашней странице:

Требования


Eigen не имеет никаких зависимостей, кроме стандартной библиотеки C++.

Мы используем систему сборки CMake, но только для сборки документации и юнит-тестов, а также для автоматизации установки. Если вы просто хотите использовать Eigen, вы можете сразу использовать заголовочные файлы. Нет бинарной библиотеки для ссылки и настроенного файла заголовка. Eigen — это чистая библиотека шаблонов, определенная в заголовках.

Любая идея, что я должен сделать для библиотек, отличных от заголовков?

QualsPassed 09.02.2023 21:51

@QualsPassed хорошо, вы сами ответили на вопрос, то есть: используйте target_link_libraries и свяжите его со своим исполняемым файлом / библиотекой. pybind11_add_module Pybind11 работает так же, как add_executable или add_library, он определяет цель (первый аргумент), с которой вы затем можете связать.

Milan Š. 09.02.2023 22:01

Итак, добавьте строку ниже pybind11_add_module, например, target_link_libraries(example <library>)? Означает ли это, что если я сделаю find_package(Eigen3 3.3) и target_link_libraries(example Eigen3::Eigen), он также сможет строить? Я попробовал это, и это не работает.

QualsPassed 09.02.2023 22:11

@QualsPassed Вам не нужно делать это с Eigen, поскольку Eigen - это только заголовок. Но если вы, например, хотите связать OpenCV, вам придется сделать target_link_libraries. С eigen все, что вам нужно сделать, это сделать заголовки доступными, что вы делаете, вызывая эту команду include_directories( ${EIGEN3_INCLUDE_DIRS} )

Milan Š. 09.02.2023 23:02

Да, я понимаю это с Eigen Мне не нужно этого делать, я просто использовал Эйгена в качестве примера.

QualsPassed 09.02.2023 23:16

@QualsPassed ах, я неправильно понял, мой плохой.

Milan Š. 09.02.2023 23:33

Подробнее о проблеме target_link_library я попробовал следующее CMakeLists.txt

cmake_minimum_required(VERSION 2.8.12)
project(example)

set (CMAKE_CXX_STANDARD 14)

find_package(Eigen3 3.3)

add_subdirectory(pybind11)
pybind11_add_module(example example.cpp)
target_link_libraries(example Eigen3::Eigen)

И мне выдаст ошибку:

CMake Error at CMakeLists.txt:14 (target_link_libraries):
  The keyword signature for target_link_libraries has already been used with
  the target "example".  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:

   * pybind11/tools/pybind11Tools.cmake:179 (target_link_libraries)
   * pybind11/tools/pybind11Tools.cmake:211 (target_link_libraries)

Это потому, что две строки, упомянутые выше, вызывают target_link_libraries как

179: target_link_libraries(${target_name} PRIVATE pybind11::module)
211: target_link_libraries(${target_name} PRIVATE pybind11::lto)

Это вызывает ошибку, потому что, как указано в сообщении об ошибке:

все использования target_link_libraries с целью должны быть либо all-keyword, либо all-plain.

all-keyword относится к включению PRIVATE|PUBLIC|INTERFACE в вызов target_link_libraries, как в двух строках выше.

all-plain означает не включать PRIVATE|PUBLIC|INTERFACE в команду target_link_libraries, например:

target_link_libraries(example Eigen3::Eigen)

Мы должны выбрать один из вышеперечисленных способов использования команды target_link_libraries в одном файле CMakeLists.txt. Поскольку pybind11 сделал этот выбор за нас, используя вызов по ключевому слову, мы также должны сделать то же самое. Итак, если мы используем

target_link_libraries(example PRIVATE Eigen3::Eigen)

он будет успешно скомпилирован. Если мы используем PUBLIC вместо PRIVATE, он также успешно скомпилируется.

Другие вопросы по теме