はじめに
目的
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をインストールする。
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モジュールをビルドして、作成したモジュールのインストールを行う。
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モジュールをビルドして、作成したモジュールのインストールを行う。
コマンドは手順①と同じである。
. ./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
環境変数の呼び出し
ビルド実行
上記のソースファイルが配置された状態で、以下コマンドを実行してビルドを行う。
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ディレクトリに配置する。
#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ディレクトリに配置する。
from distutils.core import setup, Extension
setup(
name='mymesmod',
version='1.0.0',
ext_modules=[
Extension(
name="mymesmod",
sources=["outputmes.c"],
),
]
)
サンプルプログラム(手順②ファイル)
以下の"setup.py"をsrcディレクトリに配置する。
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ディレクトリに配置する。
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
[project]
name = "mymesmod"
version = "1.0.0"
from setuptools import setup, Extension
setup(
ext_modules=[
Extension(
name="mymesmod",
sources=["outputmes.c"],
),
]
)
公開情報サイト
- (手順①関連)distutilsでビルド
- (手順②関連)setuptoolsインストール(distutils廃止について)
- (手順②関連)setuptoolsでビルド
- (手順③関連)pyproject.tomlファイルを作成してビルド
- Pythonパッケージの管理
- pipの利用手順
- "error: externally-managed-environment"について
- venvの利用手順