1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

C言語でPython拡張モジュールを作成する手順

Posted at

はじめに

目的

C言語のソースファイルから、Python拡張モジュールを作成するための手順を記載する。
Python拡張モジュールを作成するため、環境構築手順も記載する。


Python拡張モジュールの作成手順

概要

C言語のソースファイルからPython拡張モジュールを作成する手順は、以下3種類がある。
今時点では「手順③」によるPyhton拡張モジュールの作成が推奨されているが、開発環境のpythonのバージョン等により作成手順を選択する。

  • C言語のソースファイルからPython拡張モジュールを作成する手順
    • 手順①:(python3.11以前)setup.pyで"distutils.core"モジュールを呼び出して、C言語のソースファイルをビルドする
    • 手順②:(python3.12以降)setup.pyで"setuptools"モジュールを呼び出して、C言語のソースファイルをビルドする
    • 手順③:(手順②から)"pyproject.toml"を用意して、"python -m build"コマンドからC言語のソースファイルをビルドする

環境構築(手順①向け):distutilsモジュールのインストール

前提条件

Pythonのバージョンが3.11より古い場合には、Pythonの"distutils"モジュールを利用することができる。

pipインストール

下記コマンドでpipをインストールする。

pipインストール
sudo apt install python3-pip
()

pip -V
pip 22.0.2 from /usr/lib/python3/dist-packages/pip (python 3.10)

pip list
(pipのモジュール一覧を表示)
Package               Version
--------------------- ----------------
apt-clone             0.2.1
apturl                0.5.2
async-timeout         4.0.1
(以下略)

$ sudo apt list --installed | grep python3-distutils

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
python3-distutils/jammy-updates,jammy-security,now 3.10.8-1~22.04 all [installed,automatic]

pipをインストールした場合に、apt側の依存関係により"python3-distutils"のモジュール(debパッケージ)もインストールされる。


ビルド手順(手順①向け)

ビルド用のソースファイルの配置

事前にソースファイルを準備する。今回は以下の章にある「サンプルプログラム」のソースファイルを利用してビルドを行う。
srcディレクトリ配下に以下ファイルを配置する。

(ファイル配置構成)

src/
 ├ outputmes.c
 ├ setup.py

以下コマンドでpythonモジュールをビルドして、作成したモジュールのインストールを行う。

pythonモジュールのインストール(ビルド)
mkdir src
cd src
pwd
(ここに。上記サンプルプログラムのソースファイルを配置する)

ls -l
合計 0
-rw-rw-r-- 1 user user 0  3月 23 16:52 outputmes.c
-rw-rw-r-- 1 user user 0  3月 23 16:52 setup.py

pythonモジュールのビルド

以下コマンドによりビルドを行う。

sudo python3 setup.py build

(以下ファイルがビルドできたことを確認する)
/home/user/src/setup.py:1: DeprecationWarning: The distutils package is deprecated and slated for removal in Python 3.12. Use setuptools or check PEP 632 for potential alternatives
  from distutils.core import setup, Extension
running build
running build_ext
building 'mymesmod' extension
creating build
creating build/temp.linux-x86_64-3.10
x86_64-linux-gnu-gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.10 -c outputmes.c -o build/temp.linux-x86_64-3.10/outputmes.o
creating build/lib.linux-x86_64-3.10
x86_64-linux-gnu-gcc -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -g -fwrapv -O2 -Wl,-Bsymbolic-functions -g -fwrapv -O2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 build/temp.linux-x86_64-3.10/outputmes.o -o build/lib.linux-x86_64-3.10/mymesmod.cpython-310-x86_64-linux-gnu.so

実行確認

作成されたモジュールが存在するディレクトリに移動して、モジュールの有無を確認する。

$ cd build/lib.linux-x86_64-cpython-310/
$ ls -l
-rwxr-xr-x 1 root root 24896 Mar 30 09:22 mymesmod.cpython-310-x86_64-linux-gnu.so

ビルド後は以下手順で実行確認を行う。


環境構築(手順②③向け):setuptoolsモジュールのインストール

前提条件

Pythonのバージョンが3.12以降では、Pythonの"distutils"モジュールが利用できない。
その後継モジュールである"setuptools"をインストールする必要がある。

エラー回避策

エラー回避策として、以下の2つの追加手順がある。

  • 追加手順(1):venvを利用する
  • 追加手順(2):"break-system-packages"オプションを利用して強制的にインストールする

環境構築(手順②③向け):setuptoolsモジュールのインストール/追加手順(1)venv利用

Python仮想環境構成(venv環境)

Python仮想環境構成(venv環境)は、以下となる

myproject(プロジェクトフォルダ)/
 ├ myenv1(venv環境)/
 │ ├ bin/
 │ │ └ activate(環境変数)
 │ └ src/
 ├ myenv2/
 └ myenv3/

venvインストール

sudo apt install python3.12-venv

venvコマンドでPythonの仮想環境を作成

mkdir myproject
(上記は任意のディレクトリ名で可能)
cd myproject
python3 -m venv myenv1
(Python仮想環境用のディレクトリ名を入れる。名前は任意で可能)

Pythonの仮想環境の有効化(環境変数の呼び出し)

. ./myenv1/bin/activate
環境変数の呼び出し

(myenv1) user@server01:~/myproject$
(括弧の中身には設定したPython仮想環境の名前が入る)

pip list

以下コマンドを実行して、該当のPython仮想環境に必要ツールをインストールする。

python3 -m pip install --upgrade pip
python3 -m pip install setuptools
python3 -m pip install build
pip list

Pythonの仮想環境の使用を終了したい場合には、以下コマンドで仮想環境から抜けることができる。

deactivate

環境構築(手順②③向け):setuptoolsモジュールのインストール/追加手順(2)強制インストール

手順

pipコマンドでのインストール時に引数を指定して強制的にインストールを行う。

python3 -m pip install --upgrade pip --break-system-packages
python3 -m pip install setuptools --break-system-packages
python3 -m pip install build --break-system-packages
pip list

ビルド手順(手順②向け)

ビルド用のソースファイルの配置

事前にソースファイルを準備する。今回は以下の章にある「サンプルプログラム」のソースファイルを利用してビルドを行う。
srcディレクトリ配下に以下ファイルを配置する。

(ファイル配置構成)

src/
 ├ outputmes.c
 ├ setup.py

pythonモジュールのビルド

setuptoolsモジュールのインストールが完了した場合には、以下コマンドでpythonモジュールをビルドして、作成したモジュールのインストールを行う。
コマンドは手順①と同じである。

pythonモジュールのインストール(ビルド)
. ./myenv1/bin/activate
環境変数の呼び出し
cd src
python3 setup.py build

ビルド後は以下手順で実行確認を行う。


ビルド手順(手順③向け)

ビルド用のソースファイルの配置

事前にソースファイルを準備する。今回は以下の章にある「サンプルプログラム」のソースファイルを利用してビルドを行う。
srcディレクトリ配下に以下ファイルを配置する。

(ファイル配置構成)

src/
 ├ outputmes.c
 ├ setup.py
 └ pyproject.toml

ソースファイル配置
cd myenv1
mkdir src
cd src
pwd
(ここに上記のファイルを配置する)
ls -l

. ./myenv1/bin/activate
環境変数の呼び出し

ビルド実行

上記のソースファイルが配置された状態で、以下コマンドを実行してビルドを行う。

pythonモジュールのビルド
python3 -m build

ビルド後は以下手順で実行確認を行う。


モジュールの実行確認(手順①②③共通)

モジュールの実行確認

以下コマンドで、想定の出力がされるかを確認する。

モジュールの実行確認
python3
Python 3.10.12 (main, Jan 17 2025, 14:35:34) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

>>> import mymesmod
(テストモジュールのimportを行う)

>>> mymesmod.output_mes()
Hello, World!
(テスト用のHello, World!」が表示されることを確認する)

>>> quit()

サンプルプログラム

処理概要

pythonからの実行により、"Hello, World!"を表示させるプログラムです。

サンプルプログラム(共通コアファイル)

手順①から手順③までの共通のC言語ファイル
以下ファイル(ソースファイル)を、srcディレクトリに配置する。

outputmes.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>

static void output_mes(){
    printf("Hello, World!\n");
}

static PyObject *pyc_output_mes(PyObject *self, PyObject *args){
    output_mes();
    Py_RETURN_NONE;
}

static PyMethodDef output_mes_methods[] = {
    {"output_mes", pyc_output_mes, METH_NOARGS, PyDoc_STR("output messages")},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef output_mes_mod = {
    PyModuleDef_HEAD_INIT,
    "mymesmod",
    PyDoc_STR("Test module for output messages"),
    0,
    output_mes_methods,
};

PyMODINIT_FUNC PyInit_mymesmod(){
    return PyModule_Create(&output_mes_mod);
}

サンプルプログラム(手順①ファイル)

以下の"setup.py"をsrcディレクトリに配置する。

setup.py(distutils用)
from distutils.core import setup, Extension

setup(
    name='mymesmod',
    version='1.0.0',
    ext_modules=[
        Extension(
            name="mymesmod",
            sources=["outputmes.c"],
        ),
    ]
)

サンプルプログラム(手順②ファイル)

以下の"setup.py"をsrcディレクトリに配置する。

setup.py(setuptools用_pyproject.tomlを利用しない場合)
from setuptools import setup, Extension

setup(
    name='mymesmod',
    version='1.0.0',
    ext_modules=[
        Extension(
            name="mymesmod",
            sources=["outputmes.c"],
        ),
    ]
)

サンプルプログラム(手順③ファイル)

以下の"pyproject.toml"と"setup.py"をsrcディレクトリに配置する。

pyproject.toml
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[project]
name = "mymesmod"
version = "1.0.0"
setup.py(pyproject.tomlを利用する場合)
from setuptools import setup, Extension

setup(
    ext_modules=[
        Extension(
            name="mymesmod",
            sources=["outputmes.c"],
        ),
    ]
)

公開情報サイト


1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?