在命令行执行命令python setup.py develop后具体的执行过程分析完整执行过程这个命令做了两件事编译 C 扩展以开发模式安装 Python 包。核心自定义在于用 CMake 替代了 setuptools 默认的 C 编译流程。阶段 1解析可选参数# 可选自定义参数从 sys.argv 中提取后移除避免干扰 setuptools--CMAKE_PREFIX_PATH/path/to/raisim# 自定义 Raisim 安装路径--Debug# Debug 模式编译默认 Release正常用法不带这些参数直接python setup.py develop。阶段 2setuptools 框架接管setup(nameraisim_gym_torch,packagesfind_packages(),# 自动发现 raisimGymTorch/ 包ext_modules[CMakeExtension(_raisim_gym)],# 注册一个虚拟扩展cmdclassdict(build_extCMakeBuild),# 用自定义 CMakeBuild 替换默认 build_extinstall_requires[ruamel.yaml,numpy,torch,tensorboard],)关键点CMakeExtension(_raisim_gym)— 这个扩展没有源码文件sources[]它只是一个触发器告诉 setuptools有一个 C 扩展需要编译但实际编译逻辑全在自定义的CMakeBuild中。cmdclassdict(build_extCMakeBuild)— 将 setuptools 原生的build_ext命令替换为自定义类由它来调用 CMake。阶段 3develop命令触发build_extdevelop是setuptools内置命令执行流程为python setup.py develop │ ├── ① 运行 build_ext (被替换为 CMakeBuild) │ └── 见阶段 4 │ └── ② 安装 egg-link └── 见阶段 5阶段 4CMakeBuild — 编译 C 扩展4.1run()— 检查 CMake 可用性defrun(self):subprocess.check_output([cmake,--version])# 确认 cmake 已安装forextinself.extensions:self.build_extension(ext)# 遍历每个扩展这里只有1个4.2build_extension()— 两步cmake configure cmake builddefbuild_extension(self,ext):# ext.name _raisim_gym# ext.sourcedir /home/bob/project/dog/rl_locomotion/ (setup.py 所在目录)# ① 确定输出目录extdiros.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name)))# extdir 通常为: .../raisimGymTorch/env/bin/Step 1 — CMake 配置cmake_args[-DCMAKE_LIBRARY_OUTPUT_DIRECTORYextdir,-DPYTHON_EXECUTABLEsys.executable,]# Linux 下追加:cmake_args[-DCMAKE_BUILD_TYPERelease]# 等效于执行:# cd build_temp/# cmake /home/bob/project/dog/rl_locomotion/ \# -DCMAKE_LIBRARY_OUTPUT_DIRECTORY.../raisimGymTorch/env/bin \# -DPYTHON_EXECUTABLE/path/to/conda/envs/cms/bin/python \# -DCMAKE_BUILD_TYPERelease这会执行 CMakeLists.txt生成 Makefile。CMakeLists.txt 内部做的事情找到 pybind11../thirdParty/pybind11找到 Eigen3、OpenMP找到 Raisim../raisim/linux/为rsg_a1_task和dagger_a1两个目标各生成编译规则Step 2 — CMake 编译build_args[--config,Release,--,-j4]# 等效于执行:# cd build_temp/# cmake --build . --config Release -- -j4# ↑ ↑# 调用 make 传给 make: -j4 (4线程并行)这会编译出两个.so文件输出到之前设好的CMAKE_LIBRARY_OUTPUT_DIRECTORYraisimGymTorch/env/bin/ ├── rsg_a1_task.cpython-38-x86_64-linux-gnu.so └── dagger_a1.cpython-38-x86_64-linux-gnu.so编译参数细节env[CXXFLAGS]... -DVERSION_INFO0.0.0实际传递给编译器的 flag来自 CMakeLists.txt 的target_compile_options-mtunenative # 针对本机 CPU 优化指令调度 -fPIC # 生成位置无关代码.so 必需 -O3 # 最高级别优化 -g # 保留调试符号 -mno-avx2 # 禁用 AVX2Raisim 兼容性阶段 5开发模式安装egg-link编译成功后develop命令执行setuptools的标准流程# 在 site-packages 下创建 egg-link 文件 # → 指向项目根目录而不是复制文件 conda_env/lib/python3.8/site-packages/ └── raisim-gym-torch.egg-link # 内容: /path/to/raisimGymTorch/ # . (相对路径)这使得import raisimGymTorch直接从源码目录导入修改 Python 代码后无需重新安装raisimGymTorch/env/bin/下的.so也可以被直接 import注意.so不会自动重新编译——修改Environment.hpp后需要重新运行python setup.py develop完整流程图python setup.py develop │ ├─ 1. 解析可选参数 (--CMAKE_PREFIX_PATH, --Debug) │ ├─ 2. setuptools 解析 setup() 注册 │ packages [raisimGymTorch, raisimGymTorch.env, ...] │ ext_modules [CMakeExtension(_raisim_gym)] │ cmdclass {build_ext: CMakeBuild} │ ├─ 3. develop → build_ext → CMakeBuild.run() │ │ │ ├─ 3.1 检查 cmake --version │ │ │ └─ 3.2 build_extension(ext) │ │ │ ├─ mkdir build_temp/ │ │ │ ├─ cmake sourcedir ← CMake 配置 │ │ -DCMAKE_LIBRARY_OUTPUT_DIRECTORY.../env/bin │ │ -DCMAKE_BUILD_TYPERelease │ │ │ │ │ └─ 解析 CMakeLists.txt │ │ ├─ add_subdirectory(pybind11) │ │ ├─ find_package(Eigen3, OpenMP, raisim) │ │ └─ foreach(subdir: rsg_a1_task, dagger_a1) │ │ pybind11_add_module(subdir, │ │ raisim_gym.cpp, │ │ Yaml.cpp) │ │ -DRAISIMGYM_TORCH_ENV_NAMEsubdir │ │ include: envs/subdir/Environment.hpp │ │ │ └─ cmake --build . -- -j4 ← 编译 │ │ │ ├─ 编译 rsg_a1_task │ │ g raisim_gym.cpp Yaml.cpp → rsg_a1_task.so │ │ include envs/rsg_a1_task/Environment.hpp │ │ link raisim, eigen, openmp │ │ │ └─ 编译 dagger_a1 │ g raisim_gym.cpp Yaml.cpp → dagger_a1.so │ include envs/dagger_a1/Environment.hpp │ link raisim, eigen, openmp │ │ 产物: │ raisimGymTorch/env/bin/ │ ├── rsg_a1_task.cpython-38-x86_64-linux-gnu.so (pybind11 模块) │ └── dagger_a1.cpython-38-x86_64-linux-gnu.so (pybind11 模块) │ └─ 4. egg-link 安装 site-packages/raisim-gym-torch.egg-link → 指向项目根目录何时需要重新运行修改内容是否需要重新python setup.py developEnvironment.hpp(C 环境逻辑)是raisim_gym.cpp(绑定层)是VectorizedEnvironment.hpp是CMakeLists.txt是Python 文件 (.py)否egg-link 直接引用源码cfg.yaml否