Правильный файл CMakeLists.txt для вызова библиотеки MAXON в сценарии Python с использованием pybind11 - PullRequest
0 голосов
/ 03 февраля 2020

Я очень новичок во всем CMake. После this и this записей, теперь я хочу вызвать функцию MAXON внутри Python, используя pybind11. Что я сделал до сих пор:

wget https://www.maxongroup.com/medias/sys_master/root/8837358518302/EPOS-Linux-Library-En.zip
  • распаковать:
unzip EPOS-Linux-Library-En.zip
  • сделать исполняемый скрипт оболочки установки и запустить его:
chmod +x ./install.sh
sudo ./install.sh
  • Затем перейдем к папке с примером:
cd /opt/EposCmdLib_6.6.1.0/examples/HelloEposCmd/
  • Теперь объединяем файлы CMakeLists.txt из здесь :
# CMakeLists.txt

cmake_minimum_required(VERSION 2.8.12)
project (HelloEposCmd)

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall")

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

find_package(pybind11 REQUIRED)
pybind11_add_module(${PROJECT_NAME} HelloEposCmd.cpp)

add_executable(${PROJECT_NAME} HelloEposCmd.cpp)

target_link_libraries(${PROJECT_NAME} -lEposCmd)
  • и HelloEposCmd.cpp эта строка добавляется сразу после других заголовочных файлов:
#include <pybind11/pybind11.h>

основная функция переименована в:

int run(int argc, char** argv)

и синтаксис pybind11 для добавления модуля написан в конце:

PYBIND11_MODULE(HelloEposCmd, m) {

    m.def("run", &run, "runs the HelloEposCmd");
}

Однако, когда я запускаю cmake ., я получаю ошибку:

CMake Ошибка в CMakeLists.txt: 13 (add_executable):

add_executable не может создать цель "HelloEposCmd", поскольку другая цель с таким именем уже существует. Существующей целью является библиотека модулей, созданная в исходном каталоге "/opt/EposCmdLib_6.6.1.0/examples/HelloEposCmd" Подробнее см. Документацию по политике CMP0002.

...

Мне было интересно, не могли бы вы помочь мне получить правильный файл CMakeList.txt. В идеале я должен иметь возможность вызывать скомпилированный модуль в python:

# HelloEposCmd.py

import HelloEposCmd

HelloEposCmd.run()

Спасибо за вашу поддержку заранее.

Ответы [ 2 ]

1 голос
/ 03 февраля 2020

pybind11_add_module уже создает цель для вас. Так что тебе больше не нужно add_executable. Просто удалите эту строку, и при сборке вы получите библиотеку с именем HelloEposCmd

add_executable, если вы создаете исполняемый файл (.exe), что, я считаю, не то, что вам нужно .

Документация от pybind11 гласит.

Эта функция во многом похожа на встроенную в CMake add_library (на самом деле это функция-оболочка для этой команды).

0 голосов
/ 03 февраля 2020

Благодаря abhilb post и его любезному продолжению в комментариях я смог разобраться в проблеме. ну, хотя бы найдите временный обходной путь:

  • Согласно этой записи , две последние строки файла CMakeLists.txt должны измениться на
# this line can be removed
# add_executable(${PROJECT_NAME} HelloEposCmd.cpp)

target_link_libraries(${PROJECT_NAME} PRIVATE -lEposCmd)
  • и затем, поскольку согласно этот пост pybind11 не поддерживает двойные указатели, мы меняем функцию запуска на:
int run() {

    int argc = 1;
    char* argv[] = {"./HelloEposCmd"};

...
}

, которую я предполагаю быть ужасным обходным путем (вдохновленный информацией от этой страницы ). Теперь работающие cmake ., make и python3 HelloEposCmd.py должны работать должным образом (кроме небольшого предупреждения c ++!).

PS1. Возможно, кто-то может использовать std::vector<std::string>, как предложено здесь . Эта идея была предложена здесь, и уже есть некоторые ответы, которые стоит изучить.

PS2. После этого обсуждения другой обходной путь может быть что-то вроде:

#include <stdio.h>
#include <stdlib.h>

void myFunc(int argc, char* argv[]) {
    for (int i = 0; i < argc; ++i) {
        printf("%s\n", argv[i]);
    }
}

int run(int argc, long* argv_) {

    char** argv = (char**)malloc(argc * sizeof(char*));

    for (int i = 0; i < argc; ++i) {
        argv[i] = (char*)(argv_[i]);
    }

    myFunc(argc, argv);

    free(argv);

    return 0;
}
...