I want to make the code written in C ++ a library that can be called in Python. However, there was a big wall called Cython.
This is the "Cython" tutorial that makes Python explosive: when C ++ code depends on the library. This is the continuation of the preparation section.
The code is listed in "github here", so please take a look.
As a minimum folder structure, it was like this.
(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
Furthermore, at the end of the last time,
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
I installed the `` `gmp``` library.
This time, first
I will explain up to 3. Regarding 4, I will actually compile a C ++ program with dependencies using Cython so that it can be called from Python, which I will write in the next article.
gmp
This is the command when the library is installed.
./configure --prefix=/usr/local/gmp/6_1_2
This is where to store the object file created when compiling with ``` make` `` later, and the header file that is the source of the project at the time of` `make install` ``. Is the specified command.
If not specified, the object files are basically stored in `` `/ usr / local / lib` `` and the necessary header files (basically one header file containing all the program files required for the library). ) Is stored in `` `/ usr / local / include` ``.
After this, it is compiled by `` `make` ``, and the object file and header file compiled by `` `make install` `` are stored.
Here, make sure that the object file and header file of the gmp library are actually stored in the specified folder.
```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
Certainly, the object file is under `` `/ usr / local / gmp / 6_1_2 / lib, The header file is stored under
/ usr / local / gmp / 6_1_2 / include```.
cmake
Therefore, in order to create and compile a program that uses them, you need to compile with reference to them. First, simply use g ++ to write a simple program and compile it.
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();
}
You don't need to know about the gmp library, but since gmp is a library that calculates large integers, this is a program that simply assigns 1 to an object called test and prints it.
Explicitly compile the library with options. Of course, if you try to compile without writing anything about the library, you will get a reference error.
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
It will be. This is of course because the dependent libraries are not specified, but by solving it,
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
Of course you can compile like this.
In this case, `` `-Lspecifies the path to the library (object file),
-i```Is a compile option that specifies the path to the header file.
However, when there are multiple dependent libraries or when writing multiple programs, compiling with `g ++`
like this can be quite annoying. Therefore, prepare CMakeLists.txt and compile it easily.
To do that, create the following `CMakelists.txt`
and
cmake . &&It is preferable to compile using make.
Here, instead of creating `` `CMakelists.txt` `` as follows and compiling with the command `` `g ++` `` and options, `` `cmake. && make``` I will try to compile using it.
#### **`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
As knowledge necessary when converting a C ++ program to cython, the following was done to achieve cythonization of a program that has a dependency on the C ++ side.
--I explained the dependencies that are easy to trip when writing C ++ programs. --Explained how to compile C ++ using CMake.
In the next article --I will explain how to write setup.py based on the dependencies.
This time around here.
end.
Recommended Posts