高性能 C++ 工具库,通过 pybind11 提供 Python 接口,支持通过 gettool.py 自动下载和编译。
cpp_tools 是一个高性能 C++ 工具库集合,特点:
- ✅ 独立版本控制 - 每个工具通过 Git tags 独立管理版本
- ✅ Python 绑定 - 通过 pybind11 提供 Python 接口
- ✅ 自动化分发 - 通过
gettool.py自动下载、编译、安装 - ✅ 高性能 - C++ 实现,性能优于纯 Python(例如 Butterworth Filter 比 SciPy 快 1.25x)
- ✅ 跨平台 - 支持 macOS、Linux、Windows
- ✅ 自包含配置 - 每个工具都是完全独立的,无需外部依赖
┌─────────────────┐
│ cpp_tools │ GitHub 仓库
│ (本仓库) │ https://github.com/wangyendt/cpp_tools
└────────┬────────┘
│
│ git clone --sparse
│
▼
┌─────────────────┐
│ gettool.py │ 下载和编译工具
│ │ 位于 wayne_algorithm_lib/bin/
└────────┬────────┘
│
│ 1. sparse checkout 指定工具
│ 2. 运行 cmake && make
│ 3. 复制到目标目录
│
▼
┌─────────────────┐
│ bin/dsp/ │ 最终安装位置
│ butterworth_ │ import butterworth_filter
│ filter/ │
└─────────────────┘
gettool.py 通过 name_to_path_map.yaml 找到工具的路径:
# cpp_tools/name_to_path_map.yaml
butterworth_filter: dsp/butterworth_filter
sliding_window_dsp: dsp/sliding_window
apriltag_detection: cv/apriltag_detection
camera_models: cv/camera_models
pangolin_viewer: visualization/pangolin_viewer
adb_logcat_reader: adb# 在 wayne_algorithm_lib/bin/ 目录下
python gettool.py -l # 列出所有可用工具
python gettool.py butterworth_filter # 下载源码
python gettool.py butterworth_filter -b # 下载并编译
python gettool.py butterworth_filter -c # 仅编译(已下载的)| 工具名 | 路径 | 功能 | 性能提升 |
|---|---|---|---|
butterworth_filter |
dsp/butterworth_filter/ |
Butterworth 滤波器 (filtfilt/lfilter) | 1.25x vs SciPy |
sliding_window_dsp |
dsp/sliding_window/ |
滑动窗口统计 (MKAverage, WelfordStd) | 高性能 |
apriltag_detection |
cv/apriltag_detection/ |
AprilTag 检测 | - |
camera_models |
cv/camera_models/ |
相机模型 (Pinhole, Fisheye) | - |
pangolin_viewer |
visualization/pangolin_viewer/ |
Pangolin 可视化 | - |
adb_logcat_reader |
adb/ |
Android Logcat 解析 | - |
# macOS
brew install cmake pybind11 eigen opencv
# Ubuntu
sudo apt install cmake pybind11-dev libeigen3-dev libopencv-dev
# 或使用提供的安装脚本
cd install_scripts/
./install_pybind11.sh
./install_eigen.sh# 方式 1: 通过 gettool.py(推荐)
cd wayne_algorithm_lib/bin/
python gettool.py butterworth_filter -b
# 方式 2: 直接在 cpp_tools 仓库编译
cd cpp_tools/dsp/butterworth_filter/
python example.py # 自动编译并运行import sys
sys.path.append('lib')
import butterworth_filter as bf
# 创建滤波器
filter = bf.ButterworthFilter(order=4, cutoff=0.1)
# 滤波
filtered = filter.filtfilt(signal)your_tool_name/
├── CMakeLists.txt # CMake 配置(自包含版本)
├── your_tool_pybind.cpp # pybind11 绑定代码
├── example.py # 示例和测试代码(必须包含自动编译)
└── src/ # C++ 源代码(必须在此目录)
├── YourClass.h # 头文件
└── YourClass.cpp # 实现文件
cd cpp_tools/
mkdir -p category/your_tool_name/src
cd category/your_tool_name/分类建议:
dsp/- 信号处理cv/- 计算机视觉optimization/- 优化算法ml/- 机器学习utils/- 通用工具
在 src/ 目录下创建头文件和实现:
// src/YourClass.h
#pragma once
#include <vector>
class YourClass {
public:
YourClass(int param);
std::vector<double> process(const std::vector<double>& input);
private:
int param_;
};// src/YourClass.cpp
#include "YourClass.h"
YourClass::YourClass(int param) : param_(param) {}
std::vector<double> YourClass::process(const std::vector<double>& input) {
// 实现你的算法
return input;
}cp ../../cmake/CMakeLists_standalone.txt CMakeLists.txt修改以下 3 处:
# 1. 项目名称(第 13 行)
project(category_your_tool_name) # 例如:dsp_butterworth_filter
# 2. 静态库配置(第 100-120 行)
add_library(
category_your_tool_name # ← 改这里
STATIC
src/YourClass.cpp # ← 改这里:你的源文件
)
target_include_directories(
category_your_tool_name # ← 改这里
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src
)
target_compile_options(category_your_tool_name PRIVATE ${OPTIMIZATION_FLAGS}) # ← 改这里
set_target_properties(
category_your_tool_name # ← 改这里
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib
)
# 3. Python 模块配置(第 122-140 行)
pybind11_add_module(your_tool_name your_tool_pybind.cpp) # ← 改这里:模块名和pybind文件名
target_link_libraries(
your_tool_name # ← 改这里:模块名
PRIVATE category_your_tool_name # ← 改这里:静态库名
)
target_compile_options(your_tool_name PRIVATE ${OPTIMIZATION_FLAGS}) # ← 改这里:模块名
if(NOT MSVC)
target_link_options(your_tool_name PRIVATE ${OPTIMIZATION_LINK_FLAGS}) # ← 改这里:模块名
endif()
set_target_properties(
your_tool_name # ← 改这里:模块名
PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib
)验证配置:
cd ../../
python cmake/cmake_manager.py check创建 your_tool_pybind.cpp:
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "YourClass.h"
namespace py = pybind11;
PYBIND11_MODULE(your_tool_name, m) {
m.doc() = "Your tool description";
py::class_<YourClass>(m, "YourClass")
.def(py::init<int>(), py::arg("param"))
.def("process", &YourClass::process,
py::arg("input"),
"Process input data");
}常用 pybind11 模式:
// 基本类型
.def("method", &Class::method, py::arg("x"), py::arg("y"))
// std::vector
#include <pybind11/stl.h>
std::vector<double> → list[float]
// Eigen
#include <pybind11/eigen.h>
Eigen::MatrixXd → np.ndarray
// NumPy buffer
#include <pybind11/numpy.h>
py::array_t<double> input创建 example.py(必须包含自动编译逻辑):
#!/usr/bin/env python3
"""
your_tool_name 使用示例
功能:
1. 自动编译 C++ 代码
2. 基本功能测试
3. 性能对比(如果有 Python 等价实现)
"""
import os
import sys
import numpy as np
import time
# ============================================================================
# 自动编译(必须包含)
# ============================================================================
def build():
"""自动编译 C++ 模块"""
build_dir = os.path.join(os.path.dirname(__file__), 'build')
os.makedirs(build_dir, exist_ok=True)
print("🔨 编译 C++ 模块...")
ret = os.system(f"cd {build_dir} && cmake .. && make -j$(nproc)")
if ret != 0:
print("❌ 编译失败")
sys.exit(1)
print("✅ 编译成功\n")
# 确保编译
build()
# 添加库路径
sys.path.append(os.path.join(os.path.dirname(__file__), 'lib'))
import your_tool_name
# ============================================================================
# 测试代码
# ============================================================================
print("="*80)
print("测试 your_tool_name")
print("="*80)
# 创建对象
obj = your_tool_name.YourClass(param=10)
# 准备测试数据
data = np.random.randn(1000)
# 测试功能
result = obj.process(data.tolist())
print(f"输入长度: {len(data)}")
print(f"输出长度: {len(result)}")
# 性能测试
n_iter = 100
start = time.perf_counter()
for _ in range(n_iter):
result = obj.process(data.tolist())
end = time.perf_counter()
avg_time = (end - start) / n_iter * 1000
print(f"\n平均耗时: {avg_time:.3f} ms")
print("\n✅ 测试通过")编辑 cpp_tools/name_to_path_map.yaml:
# 添加你的工具
your_tool_name: category/your_tool_name然后运行:
cd cpp_tools/
python generate_name_to_path_map.py # 如果有自动生成脚本# 1. 本地测试
cd category/your_tool_name/
python example.py
# 2. 验证配置
cd ../../
python cmake/cmake_manager.py check
# 3. 提交到 GitHub
git add .
git commit -m "Add your_tool_name"
git push
# 4. 通过 gettool 测试
cd ~/wayne_algorithm_lib/bin/
python gettool.py your_tool_name -b我想在 cpp_tools 仓库中创建一个新的 C++ 工具,并通过 pybind11 提供 Python 接口。
**工具信息:**
- 工具名:<your_tool_name>
- 分类:<dsp/cv/optimization/utils>
- 功能:<简要描述功能>
- 核心算法:<关键算法或公式>
**必须满足的要求:**
1. **目录结构**(必须遵循):
<category>/<your_tool_name>/
├── CMakeLists.txt
├── <your_tool_name>_pybind.cpp
├── example.py
└── src/
├── YourClass.h
└── YourClass.cpp
2. **CMakeLists.txt 配置**:
- 从 `cmake/CMakeLists_standalone.txt` 复制模板
- 修改项目名为 `<category>_<your_tool_name>`
- 修改静态库名为 `<category>_<your_tool_name>`
- 修改 Python 模块名为 `<your_tool_name>`
- 源文件必须在 `src/` 目录下
- 完成后运行 `python cmake/cmake_manager.py check` 验证
3. **C++ 代码**(必须在 src/ 目录):
- 实现高性能算法
- 提供清晰的接口
- 使用 std::vector 或 Eigen 处理数据
4. **pybind11 绑定**:
- 文件名:`<your_tool_name>_pybind.cpp`
- 模块名:`PYBIND11_MODULE(<your_tool_name>, m)`
- 包含必要的 pybind11 头文件(stl.h, eigen.h 等)
- 绑定所有公共接口
5. **example.py**(必须包含以下部分):
- 自动编译逻辑:def build() + os.system()
- 导入模块:sys.path.append('lib') + import
- 功能测试
- 性能对比(与 Python/NumPy/SciPy 等价实现对比)
- 输出结果
6. **注册工具**:
- 在 name_to_path_map.yaml 中添加:<your_tool_name>: <category>/<your_tool_name>
**参考示例:**
请参考 `dsp/butterworth_filter/` 的完整实现,它是一个标准的工具示例。
开始实现吧!
我有一个现有的 C++ 类/库,想集成到 cpp_tools 仓库并提供 Python 接口。
**现有代码:**
<粘贴你的 C++ 代码或描述>
**目标:**
1. 将代码整合到 cpp_tools 的标准结构中
2. 创建 pybind11 绑定
3. 编写 example.py 展示功能
4. 与 Python 等价实现进行性能对比
**必须遵循的规范:**
- 源代码放在 `src/` 目录
- 使用 `cmake/CMakeLists_standalone.txt` 模板
- example.py 包含自动编译逻辑
- 完成后用 `python cmake/cmake_manager.py check` 验证
**参考示例:**
- 完整实现:dsp/butterworth_filter/
- CMakeLists.txt:cmake/CMakeLists_standalone.txt
- pybind11 绑定:butterworth_filter_pybind.cpp
- example.py:包含自动编译、测试、性能对比
开始移植吧!
我想为 cpp_tools 中的现有工具添加新功能。
**工具路径:** `<category>/<tool_name>/`
**新功能:**
<描述要添加的功能>
**任务:**
1. 修改 `src/` 下的 C++ 代码
2. 更新 pybind11 绑定
3. 在 example.py 中添加新功能的测试
4. 确保向后兼容
**验证流程:**
1. cd <category>/<tool_name>/
2. python example.py
3. 确保所有功能测试通过
开始修改吧!
我想优化 cpp_tools 中某个工具的性能。
**工具:** `<category>/<tool_name>/`
**当前性能:** <描述当前性能指标>
**优化目标:**
- [ ] 减少内存分配
- [ ] 使用 SIMD 指令
- [ ] 并行化计算
- [ ] 算法优化
**要求:**
1. 修改 C++ 实现
2. 在 example.py 中添加性能对比
3. 确保正确性(精度测试)
4. 文档化性能提升
开始优化吧!
cpp_tools/
├── cmake/ # CMake 工具和模板
│ ├── CMakeLists_standalone.txt # 新项目模板(必须使用)
│ ├── cmake_manager.py # 自动化管理工具
│ ├── QUICKSTART.md # 快速开始指南
│ └── README.md # CMake 详细文档
│
├── dsp/ # 信号处理工具
│ ├── butterworth_filter/ # 标准示例 ✨
│ │ ├── CMakeLists.txt # 自包含配置
│ │ ├── butterworth_filter_pybind.cpp
│ │ ├── example.py # 自动编译 + 测试
│ │ ├── src/
│ │ │ ├── butterworth_filter.h
│ │ │ └── butterworth_filter.cpp
│ │ └── lib/ # 编译输出(自动生成)
│ │ └── butterworth_filter.cpython-*.so
│ │
│ └── sliding_window/ # 另一个示例
│ ├── CMakeLists.txt
│ ├── sliding_window_dsp_pybind.cpp
│ ├── example.py
│ └── src/
│ ├── MKAverage.h
│ ├── MKAverage.cpp
│ ├── WelfordStd.h
│ └── WelfordStd.cpp
│
├── cv/ # 计算机视觉工具
│ ├── apriltag_detection/
│ └── camera_models/
│
├── visualization/ # 可视化工具
│ └── pangolin_viewer/
│
├── install_scripts/ # 依赖安装脚本
│ ├── install_pybind11.sh
│ ├── install_eigen.sh
│ └── ...
│
├── name_to_path_map.yaml # gettool.py 配置(必须更新)
├── generate_name_to_path_map.py # 自动生成工具
├── README.md # 本文件
└── LICENSE
-
源代码位置 ✅
✅ your_tool/src/YourClass.cpp ❌ your_tool/YourClass.cpp -
CMakeLists.txt ✅
✅ 使用 cmake/CMakeLists_standalone.txt 模板 ❌ 自己手写 CMakeLists.txt -
example.py ✅
✅ 包含自动编译逻辑 def build(): os.system("mkdir -p build && cd build && cmake .. && make") ❌ 手动运行 cmake
-
pybind11 文件名 ✅
✅ butterworth_filter_pybind.cpp ✅ your_tool_name_pybind.cpp ❌ pybind.cpp ❌ bindings.cpp -
name_to_path_map.yaml ✅
✅ your_tool_name: category/your_tool_name ❌ 忘记添加
症状:
CMake Error: Could not find Python
解决:
# 激活正确的 Python 环境
conda activate your_env
# 验证
which python
python --version
# 清理并重新编译
rm -rf build lib/*.so
python example.py症状:
ImportError: dlopen(...): symbol not found
原因: Python 版本不匹配
解决:
# 确保使用同一个 Python
which python # 应该指向你的虚拟环境
# 重新编译
rm -rf build lib
python example.py症状:
Tool 'your_tool' not found
解决:
# 检查 name_to_path_map.yaml
cat name_to_path_map.yaml | grep your_tool
# 如果没有,添加:
echo "your_tool_name: category/your_tool_name" >> name_to_path_map.yaml
# 提交到 GitHub
git add name_to_path_map.yaml
git commit -m "Add your_tool to name_to_path_map"
git push症状:
fatal error: 'YourClass.h' file not found
解决:
# 检查 CMakeLists.txt 中的 target_include_directories
target_include_directories(
your_tool_name
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src # ← 确保包含 src/
)症状: 不确定配置是否正确
解决:
cd cpp_tools/
python cmake/cmake_manager.py check
# 输出示例:
# ✅ 使用自包含配置 dsp/butterworth_filter/CMakeLists.txt
# ⚠️ 使用旧的模块化配置 your_tool/CMakeLists.txt ← 需要更新- cmake/README.md - CMake 详细配置文档
- cmake/QUICKSTART.md - 5 分钟快速开始
- install_scripts/SCRIPT_GUIDELINES.md - 依赖安装指南
- Fork 本仓库
- 创建你的工具(遵循上述规范)
- 运行
python cmake/cmake_manager.py check验证 - 提交 Pull Request
MIT License - 详见 LICENSE
创建新工具时,确保满足以下所有条件:
- 目录结构正确:
category/tool_name/src/ - 从
cmake/CMakeLists_standalone.txt复制并修改 3 处 - C++ 代码在
src/目录下 - 创建了
tool_name_pybind.cpp -
example.py包含自动编译逻辑 -
example.py包含功能测试和性能对比 - 添加到
name_to_path_map.yaml - 运行
python cmake/cmake_manager.py check✅ - 本地测试通过:
python example.py✅ - 通过 gettool 测试:
python gettool.py tool_name -b✅
全部完成后,你的工具就可以被 gettool.py 自动下载和编译了! 🎉