"Cython" tutorial to make Python explosive: When C ++ code depends on the library. First of all, CMake.

Overview

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.

Situation explanation

(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.

What to do this time

This time, first

  1. Write simple code using the gmp library and make sure you can compile it with commands.
  2. How are the C ++ libraries installed and referenced in the first place?
  3. How is the compilation of dependent programs performed using CMake?
  4. How is it written in setup.py when it is cythonized?

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.

C ++ dependencies

How are the C ++ libraries installed and referenced in the first place?

gmpThis 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

How is the compilation of a dependent program performed using 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 

Summary

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

"Cython" tutorial to make Python explosive: When C ++ code depends on the library. First of all, CMake.
"Cython" tutorial to make Python explosive: When C ++ code depends on the library. Preparation
"Cython" tutorial to make Python explosive: When C ++ code depends on the library. Write setup.py.
"Cython" tutorial to make Python explosive: Pass the C ++ class object to the class object on the Python side. Part 2
"Cython" tutorial to make Python explosive: Handling when a function on the C ++ side is passed by reference.
"Cython" Tutorial to Make Python Explosive: Basic Configuration
"Cython" tutorial to make Python explosive: How to parse an Enum class defined in C ++ code into a Python Enum.
First python ② Try to write code while examining the features of python
How to use the C library in Python
I stumbled on the character code when converting CSV to JSON in Python
I want to make C ++ code from Python code!
Make a breakpoint on the c layer with python
Easy build of C ++ code with CMake on Docker
I felt that I ported the Python code to C ++ 98.
[Introduction to Python] Basic usage of the library matplotlib
GPU-enabled build of LibTorch (PyTorch C ++) app on Windows without CMake (only the first time)
Make the display of Python module exceptions easier to understand
The first API to make with python Djnago REST framework
Settings to debug the contents of the library with VS Code
Pass OpenCV data from the original C ++ library to Python
Through the installation of pip package that depends on opencv-python when building opencv from source code
When you want to use multiple versions of the same Python library (virtual environment using venv)
Wrap (part of) the AtCoder Library in Cython for use in Python
Differences C # engineers felt when learning python for the first time
Let's measure the test coverage of pushed python code on GitHub.
[Introduction to Python] I compared the naming conventions of C # and Python.
[Python] How to get the first and last days of the month
I wrote the code to write the code of Brainf * ck in python
How to update the python version of Cloud Shell on GCP
How to run the practice code of the book "Creating a profitable AI with Python" on Google Colaboratory
First Python 3 ~ The beginning of repetition ~
[Python] How to import the library
Python Note: When you want to know the attributes of an object
I tried to get the authentication code of Qiita API with Python.
Download all the images attached to the body of the pull request on Github
Hook to Shared Library on Linux to interrupt the behavior of existing binaries
I tried to verify and analyze the acceleration of Python by Cython
From re-environment construction of Python to graph drawing (on visual studio code)
Python code to determine the monthly signal of a relative strength investment
[Python3] Code that can be used when you want to change the extension of an image at once
How to deal with "^ [[A ^ [[B ^ [[C ^ [[D"] when you press the arrow keys when executing python on mac