Lier des fichiers objets C ++ intégrés avec Python

Oct 03 2020

J'ai un fichier de constructeur C ++ ( formatting_SQ.cpp) d'un fichier d'en-tête formatting_SQ.hque je veux lier à d'autres fichiers de constructeur de fichiers d'en-tête ( neat.cpp nnode.cpp link.cpp etc...-> neat.h nnode.h link.h) afin d'avoir formatting_SQ.o.

Ensuite, je veux lier mon fichier main.cpp à ce formatting_SQ.ofichier. Le problème est: formatting_SQest intégré avec python, et pour autant que je sache, C ++ intégré avec Python a besoin de l'indicateur de compilation -lpython3.6msous Linux: un tel indicateur nécessite une référence à une main()fonction, que je n'ai pas formatting_SQ.cppcar c'est un fichier constructeur destiné être un fichier objet.

J'ai donc d'abord essayé de créer des fichiers objets pour chaque fichier de constructeur, puis de tout lier en même temps :

g++ -c -O3 -Wall -fPIC -fopenmp -std=c++14 -lstdc++ `python3 -m pybind11 --includes` *.cpp 
g++ -o the_executable neat.o nnode.o link.o trait.o gene.o network.o innovation.o organism.o species.o genome.o population.o formatting_SQ.o main.o -fopenmp -O3 -Wall -fPIC `python3 -m pybind11 --includes` -lpython3.6m

Voici ma première question: ces commandes sont-elles correctes ou y a-t-il finalement un indicateur de compilation manquant? Cela me donne une erreur de segmentation lorsque j'essaye d'exécuter ./the_executable.

Ensuite, j'ai essayé de compiler formatting_SQ.cppindépendamment avec tous les autres fichiers du constructeur, mais comme prévu, cela ne fonctionne pas car il n'y a pas de référence à main in formatting_SQ.cpp.

g++ -o temp_formatting neat.o nnode.o link.o trait.o gene.o network.o innovation.o organism.o species.o genome.o population.o formatting_SQ.o -fopenmp -O3 -Wall -fPIC `python3 -m pybind11 --includes` -lpython3.6m

Voici donc ma deuxième question: comment pourrais-je créer un fichier objet intégré python liant formatting_SQ.cpptous les autres fichiers du constructeur sans avoir cette undefined reference to mainerreur?

formatage_SQ.cpp

#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <pybind11/stl.h>
#include <Python.h>
#include <omp.h>
#include "formatting_SQ.h"
#include "neat.h"
#include "network.h"
#include "link.h"
#include "nnode.h"
#include "trait.h"
#include "gene.h"
#include "genome.h"
#include "innovation.h"
#include "organism.h"
#include "species.h"
#include "population.h"

namespace py = pybind11;
py::module compile_data = py::module::import("initialize");

main.cpp

#include <pybind11/embed.h>
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <pybind11/stl.h>
#include <Python.h>
#include "formatting_SQ.h"
#include <omp.h>
    
namespace py = pybind11;
        
int main(int argc, char** argv){
      
....

Réponses

Joachim Oct 03 2020 at 12:19

Donc, après de longues heures de recherche, je peux conclure que la méthode de compilation est correcte mais SOYEZ EXTRÊMEMENT PRUDENT avec l'endroit où vous déclarez vos modules d'importation depuis python, car c'était le problème pour moi

#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <pybind11/stl.h>
#include <Python.h>
#include <omp.h>
#include "formatting_SQ.h"
#include "neat.h"
#include "network.h"
#include "link.h"
#include "nnode.h"
#include "trait.h"
#include "gene.h"
#include "genome.h"
#include "innovation.h"
#include "organism.h"
#include "species.h"
#include "population.h"

namespace py = pybind11;
py::module compile_data = py::module::import("initialize"); DON'T DO THIS its wrong !!! 

Vous devez déclarer vos modules localement, sinon il y aura des conflits dans l'espace de noms car le même module peut être importé plusieurs fois et cela provoque l'erreur de segmentation.