Je veux faire du code écrit en C ++ une bibliothèque qui puisse être appelée en Python. Cependant, il y avait un grand mur appelé Cython.
C'est le tutoriel "Cython" qui rend Python explosif: quand le code C ++ dépend de la bibliothèque. Ceci est une suite de la section de préparation.
Le code est répertorié dans "github here", veuillez donc y jeter un œil.
En tant que structure de dossier minimale, c'était comme ça.
(myenv) user@~/Documents/cython_practice[master]> tree .
.
├── README.md
├── cpp_library
│ ├── TestClass1.cpp
│ └── TestClass1.h
├── cython
│ ├── my_library.pxd
│ ├── my_library.pyx
│ ├── test_class1.pxd
│ └── test_class1.pyx
└── setup.py
De plus, à la fin de la dernière fois,
wget https://gmplib.org/download/gmp/gmp-6.1.2.tar.xz &&\
tar xvf gmp-6.1.2.tar.xz &&\
cd gmp-6.1.2 &&\
./configure --prefix=/usr/local/gmp/6_1_2 &&\
make && make check && make install
J'ai installé la bibliothèque
gmp```.
Cette fois, d'abord
J'expliquerai jusqu'à 3. Concernant 4, j'utiliserai en fait Cython pour compiler un programme C ++ avec des dépendances afin qu'il puisse être appelé depuis Python, ce que j'écrirai dans le prochain article.
gmp
Il s'agit de la commande lorsque la bibliothèque est installée.
./configure --prefix=/usr/local/gmp/6_1_2
C'est là que stocker le fichier objet créé lors de la compilation avec `` `make` '' plus tard, et le fichier d'en-tête qui est la source du projet au moment de` `make install`` `. Est la commande spécifiée.
S'il n'est pas spécifié, le fichier objet est essentiellement stocké dans `` `` / usr / local / lib` `` `` et le fichier d'en-tête requis (essentiellement un fichier d'en-tête contenant tous les fichiers de programme requis pour la bibliothèque). ) Est stocké dans `` `` / usr / local / include` ``.
Après cela, il est compilé par `` `make` '', et le fichier objet et le fichier d'en-tête compilé par` `make install '' 'sont stockés.
Ici, assurez-vous que le fichier objet et le fichier d'en-tête de la bibliothèque gmp sont réellement stockés dans le dossier spécifié.
```bash
root@e96f489c2395:/# ls /usr/local/gmp/6_1_2/lib/
libgmp.a libgmp.la libgmp.so libgmp.so.10 libgmp.so.10.3.2
root@e96f489c2395:/# ls /usr/local/gmp/6_1_2/include/
gmp.h
Certes, le fichier objet se trouve sous
/ usr / local / gmp / 6_1_2 / lib, Le fichier d'en-tête est stocké sous `` `` / usr / local / gmp / 6_1_2 / include
.
cmake
Par conséquent, pour créer et compiler un programme qui les utilise, vous devez compiler en référence à eux. Tout d'abord, utilisez simplement g ++ pour écrire un programme simple et le compiler.
test.cpp
#include <iostream>
#include <gmp.h>
using namespace std;
void print_test(){
mpz_t test;
mpz_init(test);
mpz_set_ui(test, 1);
gmp_printf("print : %Zd \n", test);
}
int main(){
print_test();
}
Vous n'avez pas besoin de connaître la bibliothèque gmp, mais comme gmp est une bibliothèque qui calcule de grands entiers, c'est un programme qui attribue simplement 1 à un objet appelé test et l'imprime.
Compilez explicitement la bibliothèque avec des options. Bien sûr, si vous essayez de compiler sans rien écrire sur la bibliothèque, vous obtiendrez une erreur de référence.
root@e96f489c2395:/from_local# g++ test.cpp
/tmp/ccZnVmvP.o: In function `main':
test.cpp:(.text+0x1f): undefined reference to `__gmpz_init'
test.cpp:(.text+0x30): undefined reference to `__gmpz_set_ui'
test.cpp:(.text+0x48): undefined reference to `__gmp_printf'
collect2: error: ld returned 1 exit status
Ce sera. C'est bien sûr parce que les bibliothèques dépendantes ne sont pas spécifiées, mais en le résolvant,
root@e96f489c2395:/from_local# g++ test.cpp -L/usr/local/gmp/6_1_2/lib -I/usr/local/gmp/6_1_2/include -lgmp
root@e96f489c2395:/from_local# ./a.out
print : 1
Bien sûr, vous pouvez compiler comme ça.
Dans ce cas,
-Lspécifie le chemin vers la bibliothèque (fichier objet),
-i```Est une option de compilation qui spécifie le chemin d'accès au fichier d'en-tête.
Cependant, lorsque vous avez plusieurs bibliothèques dépendantes, ou lorsque vous avez plusieurs programmes que vous écrivez, compiler avec `` g ++ '' comme celui-ci peut être assez ennuyeux. Par conséquent, préparez CMakeLists.txt et compilez-le facilement.
Pour ce faire, créez le suivant CMakelists.txt`
cmake . &&Il est préférable de compiler en utilisant make.
Ici, au lieu de créer `` `` CMakelists.txt` '' comme suit et de compiler avec la commande `` `g ++` `` `et les options,` `` `cmake. && make``` Je vais essayer de compiler en l'utilisant.
#### **`CMakeLists.txt`**
```txt
cmake_minimum_required(VERSION 3.10)
project(TEST VERSION 1.1.0 LANGUAGES CXX)
# Executable will be in ../bin
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR})
set(CMAKE_CXX_FLAGS "-g -O0 -lgmp")
add_executable(test1
test.cpp
)
target_sources(test1
PRIVATE
)
target_include_directories(test1 PRIVATE /usr/local/gmp/6_1_2/include/)
target_link_libraries(test1 gmp /usr/local/gmp/6_1_2/lib)
root@e96f489c2395:/from_local# cmake .
-- Configuring done
WARNING: Target "test1" requests linking to directory "/usr/local/gmp/6_1_2/lib". Targets may link only to libraries. CMake is dropping the item.
-- Generating done
-- Build files have been written to: /from_local
root@e96f489c2395:/from_local# make
[100%] Built target test1
root@e96f489c2395:/from_local# ./test1
print : 1
En tant que connaissances nécessaires lors de la conversion d'un programme C ++ en cython, ce qui suit a été effectué pour réaliser la cythonisation d'un programme qui a une dépendance du côté C ++.
Dans le prochain article --Je vais expliquer comment écrire setup.py en fonction des dépendances.
Cette fois par ici.
fin.
Recommended Posts