with one click
max-external
Max/MSPのエクスターナルオブジェクトをmin-api + CMakeで作成する
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Max/MSPのエクスターナルオブジェクトをmin-api + CMakeで作成する
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
| name | max-external |
| description | Max/MSPのエクスターナルオブジェクトをmin-api + CMakeで作成する |
deps/min-api/ に配置済みであることproject/
├── CMakeLists.txt # ルートCMake (templates/CMakeLists.root.txt ベース)
├── cmake/
│ ├── bbb_external.cmake # bbb_add_external() 定義 (共通)
│ └── generate_version.cmake # バージョン生成 (オプション)
├── deps/
│ └── min-api/ # git submodule (max-sdk-base を含む)
├── source/
│ ├── projects/
│ │ └── bbb.xxx.yyy/ # external ごとのディレクトリ
│ │ ├── CMakeLists.txt # bbb_add_external() 呼び出しのみ (1〜5行)
│ │ └── bbb.xxx.yyy.cpp
│ └── bbb/ # 共有ヘッダ (任意)
├── help/ # .maxhelp ファイル (正規の場所)
├── externals/ # ビルド成果物 (.mxo / .mxe64)
└── package-info.json
外部名を NAME (例: bbb.osc.send) とする。
source/projects/<NAME>/<NAME>.cpp
source/projects/<NAME>/CMakeLists.txt
cpp は templates/external.cpp をベースに生成する。
Jitter MOP オブジェクトの場合は templates/external_jitter.cpp をベースにする。
プレースホルダ置換ルール:
| プレースホルダ | 置換値 | 例 |
|---|---|---|
__CLASS_NAME__ | ドットをアンダースコアに | bbb_osc_send |
__EXTERNAL_NAME__ | そのまま | bbb.osc.send |
__DESCRIPTION__ | external の説明 | Send OSC messages over UDP |
__TAGS__ | カンマ区切りタグ | osc, udp, network |
__AUTHOR__ | 作者名 | 2bit |
templates/CMakeLists.project.txt をベースにする。
基本的にコメントアウトを外すだけで動く:
# 依存ライブラリがある場合:
bbb_add_external(
DEPS pthread somelib
INCLUDES ${SOME_DIR}/include
)
# 依存なし (最小構成):
bbb_add_external()
SUBDIRLIST マクロが source/projects/ 以下を自動スキャンする。
新しいディレクトリを追加するだけで認識される。
"filelist": {
"externals/bbb.osc.send.mxo": {}
}
mkdir -p build && cd build
cmake ..
cmake --build .
成果物は externals/<NAME>.mxo (macOS) / externals/<NAME>.mxe64 (Windows) に出力される。
cmake/bbb_external.cmake は min-api の min-pretarget.cmake / min-posttarget.cmake
を include する。pretarget/posttarget は各 external ごとに project() が呼ばれることを
前提としているが、bbb_add_external() はマクロ内でこれらを include した後、
ディレクトリスコープ変数を PARENT_SCOPE で伝播させることで add_subdirectory()
構造でも正しく動作するようにしている。
プラットフォームごとの設定は pretarget/posttarget スクリプト経由で適用される:
BUNDLE True, BUNDLE_EXTENSION "mxo", Universal Binary (x86_64;arm64),
MaxAudioAPI / JitterAPI framework リンク, PkgInfo コピー, ad-hoc codesignSUFFIX ".mxe64", MaxAPI.lib / MaxAudio.lib / jitlib.lib リンク,
RUNTIME_OUTPUT_DIRECTORY 設定, WIN_VERSION 定義CXX_STANDARD 17, PREFIX "", DC74_MIN_API 定義, C74_MIN_API_DIR / C74_MAX_SDK_DIR 自動導出cmake/bbb_external.cmake で定義される共通 function。
bbb_add_external(
[MACOS_ONLY] # macOS のみビルド (Windows ではスキップ)
[WIN32_ONLY] # Windows のみビルド (macOS ではスキップ)
[DEPS lib1 lib2 ...] # target_link_libraries に渡す依存
[INCLUDES dir1 dir2 ...] # target_include_directories に渡す追加パス
[SOURCES file1.cpp ...] # 追加ソース (省略時: *.cpp を自動収集)
[RPATH path] # BUILD_RPATH / INSTALL_RPATH を設定
)
内部で以下を処理する:
C74_MIN_API_DIR の自動探索 (deps/min-api/ or extern/min-api/)add_library(MODULE ...) による .mxo / .mxe64 ビルドx86_64;arm64) の設定.mxe64 サフィックス・lib リンク・出力ディレクトリ設定MACOS_ONLY / WIN32_ONLY オプションによるプラットフォームフィルタリング| レイヤー | 形式 | 例 |
|---|---|---|
| ディレクトリ/ファイル名 | bbb.xxx.yyy (ドット区切り) | bbb.osc.send |
| C++ クラス名 | bbb_xxx_yyy (アンダースコア区切り) | bbb_osc_send |
| MIN_EXTERNAL マクロ引数 | クラス名と同一 | bbb_osc_send |
| .mxo ファイル名 | ディレクトリ名と同一 | bbb.osc.send.mxo |
git commit count から自動生成する。
templates/generate_version.cmake と templates/CMakeLists.root.txt のバージョン生成セクションを参照。
VERSION_MACRO 変数でマクロ名を指定する (例: BBB_OSC_VERSION)。
Jitter MOP オブジェクトを作成する場合は matrix_operator<> を継承し、
templates/external_jitter.cpp をベースにする。
class my_jitter : public c74::min::object<my_jitter>,
public c74::min::matrix_operator<> {
// ...
};
テンプレート引数なし。 matrix_operator<my_jitter> はコンパイルエラー。
calc_cell はピクセル単位で呼ばれる。plane_count は 1, 4, 32 等で複数実体化されるため、
if constexpr でガード必須:
template <class matrix_type, size_t plane_count>
c74::min::cell<matrix_type, plane_count> calc_cell(
c74::min::cell<matrix_type, plane_count> input,
const c74::min::matrix_info& info,
c74::min::matrix_coord& position)
{
if constexpr (plane_count == 4) { /* RGBA */ }
return input;
}
info.m_bip が生ピクセルデータポインタ。position(0,0) で一括キャプチャ。
dimstride を使って行ごとにコピーしパディングに対応。
注意: m_frame_buffer をワーカースレッドと共有する場合は resize() の再確保に注意。
ダブルバッファまたは同期を検討すること。
if (position.x() == 0 && position.y() == 0) {
auto row_bytes = info.width() * info.cellsize();
m_frame_buffer.resize(row_bytes * info.height());
auto src = static_cast<const char*>(info.m_bip);
auto dst = m_frame_buffer.data();
for (long y = 0; y < static_cast<long>(info.height()); ++y) {
std::memcpy(dst + y * row_bytes, src + y * info.dimstride[1], row_bytes);
}
}
入力 matrix なし。calc_cell 内でデコード済みデータをピクセルごとに書き込む。
outlet type は "jit_matrix"。
Jitter MOP の outlet type は "jit_matrix"。メッセージ用 outlet は "":
c74::min::outlet<> matrix_out{this, "(jit_matrix)", "jit_matrix"};
c74::min::outlet<> message_out{this, "(anything)"};
docs/pitfalls.md の #13 (calc_cell テンプレート), #14 (m_bip 生ポインタ) を必ず参照queue<> 経由 (pitfall #2)必ず docs/pitfalls.md を読むこと。 attribute の遅延設定、スレッド制限、enum_map、NIL 衝突等の重要な注意点が記載されている。