Python module directory (lichtfeld.so/.pyd)
| 100 | |
| 101 | // Python module directory (lichtfeld.so/.pyd) |
| 102 | inline std::filesystem::path getPythonModuleDir() { |
| 103 | const auto exe_dir = getExecutableDir(); |
| 104 | |
| 105 | auto module_exists = [](const std::filesystem::path& dir) { |
| 106 | std::error_code ec; |
| 107 | if (!std::filesystem::exists(dir, ec)) { |
| 108 | return false; |
| 109 | } |
| 110 | |
| 111 | // Check various naming patterns nanobind might produce. |
| 112 | for (const auto& name : { |
| 113 | "lichtfeld.abi3.so", |
| 114 | "lichtfeld.so", |
| 115 | "lichtfeld.pyd", |
| 116 | "lichtfeld.abi3.pyd", |
| 117 | "lichtfeld.cp312-win_amd64.pyd", |
| 118 | "lichtfeld.cp311-win_amd64.pyd"}) { |
| 119 | if (std::filesystem::exists(dir / name, ec)) { |
| 120 | return true; |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | // Match platform-specific CPython suffixes (e.g., lichtfeld.cpython-312-x86_64-linux-gnu.so). |
| 125 | for (std::filesystem::directory_iterator it(dir, ec), end; !ec && it != end; it.increment(ec)) { |
| 126 | std::error_code file_ec; |
| 127 | if (!it->is_regular_file(file_ec) || file_ec) { |
| 128 | continue; |
| 129 | } |
| 130 | const auto filename = it->path().filename().string(); |
| 131 | const auto ext = it->path().extension().string(); |
| 132 | if ((ext == ".so" || ext == ".pyd") && filename.rfind("lichtfeld", 0) == 0) { |
| 133 | return true; |
| 134 | } |
| 135 | } |
| 136 | |
| 137 | return false; |
| 138 | }; |
| 139 | |
| 140 | // Production: exe in bin/, module in ../lib/python/ |
| 141 | if (const auto prod = exe_dir.parent_path() / "lib" / "python"; module_exists(prod)) { |
| 142 | return prod; |
| 143 | } |
| 144 | |
| 145 | // Development: module in src/python/ relative to exe (build dir) |
| 146 | if (const auto dev = exe_dir / "src" / "python"; module_exists(dev)) { |
| 147 | return dev; |
| 148 | } |
| 149 | |
| 150 | // Fallback: module in same directory as exe (Windows dev builds) |
| 151 | if (module_exists(exe_dir)) { |
| 152 | return exe_dir; |
| 153 | } |
| 154 | |
| 155 | return {}; |
| 156 | } |
| 157 | |
| 158 | inline bool isVcpkgPythonPrefix(const std::filesystem::path& triplet_dir) { |
| 159 | std::error_code ec; |
no test coverage detected