Skip to content

Commit d650695

Browse files
committed
fix: use _NSGetExecutablePath on macOS (no /proc/self/exe)
macOS doesn't have /proc/self/exe. Use _NSGetExecutablePath from mach-o/dyld.h to resolve the binary's absolute path. This fixes: - build.ninja mcpp= variable (needed for dyndep) - MCPP_HOME auto-detection from binary location
1 parent 82fa56d commit d650695

2 files changed

Lines changed: 24 additions & 0 deletions

File tree

src/build/ninja_backend.cppm

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
module;
1515
#include <cstdio>
1616
#include <cstdlib>
17+
#if defined(__APPLE__)
18+
#include <mach-o/dyld.h> // _NSGetExecutablePath
19+
#endif
1720

1821
export module mcpp.build.ninja;
1922

@@ -113,9 +116,19 @@ bool dyndep_mode_enabled() {
113116

114117
std::filesystem::path mcpp_exe_path() {
115118
std::error_code ec;
119+
#if defined(__APPLE__)
120+
// macOS: use _NSGetExecutablePath
121+
char buf[4096];
122+
uint32_t size = sizeof(buf);
123+
if (_NSGetExecutablePath(buf, &size) == 0) {
124+
auto p = std::filesystem::canonical(buf, ec);
125+
if (!ec) return p;
126+
}
127+
#else
116128
auto p = std::filesystem::read_symlink("/proc/self/exe", ec);
117129
if (!ec)
118130
return p;
131+
#endif
119132
return "mcpp"; // fall back to PATH lookup
120133
}
121134

src/config.cppm

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
module;
1717
#include <cstdio>
1818
#include <cstdlib>
19+
#if defined(__APPLE__)
20+
#include <mach-o/dyld.h> // _NSGetExecutablePath
21+
#endif
1922

2023
export module mcpp.config;
2124

@@ -161,7 +164,15 @@ std::filesystem::path home_dir() {
161164
return std::filesystem::path(e);
162165

163166
std::error_code ec;
167+
#if defined(__APPLE__)
168+
char _exe_buf[4096];
169+
uint32_t _exe_size = sizeof(_exe_buf);
170+
std::filesystem::path exe;
171+
if (_NSGetExecutablePath(_exe_buf, &_exe_size) == 0)
172+
exe = std::filesystem::canonical(_exe_buf, ec);
173+
#else
164174
auto exe = std::filesystem::canonical("/proc/self/exe", ec);
175+
#endif
165176
if (!ec && exe.parent_path().filename() == "bin") {
166177
// Dev builds emit binaries at target/<triple>/<fp>/bin/<exe>,
167178
// matching the bin/ shape. Any ancestor literally named

0 commit comments

Comments
 (0)