When the binary is considerably large, the cargo run takes long time on MacOS even though it has nothing to do.
Example binary -- very quick to run:
$ time ./target/debug/datafusion-cli --version
datafusion-cli 41.0.0
real 0m0.022s
cargo build alone is quick, since there is nothing to do:
$ time cargo build --offline --bin datafusion-cli
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.18s
real 0m0.234s
but cargo run is slow
$ time cargo run --offline --bin datafusion-cli -- --version
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.19s
Running `target/debug/datafusion-cli --version`
datafusion-cli 41.0.0
real 0m2.599s
When the system is under heavy load, a "Verifying 'datafusion-cli'" popup can be seen.
Normally it doesn't show up, but over 2s are spend on something.
The binary is almost 200M in size. It's mtime does not change when running build or run
Those 2 seconds (or more on bigger binary, or when CPU is already busy with something) affect developing experience in an IDE. VS Code and RustRover both invoke cargo run and not the binary directly.
~How to speed up running the binary when it is already built?~
How to speed up running the binary via IDE when it is already built?
Yes, i know I can do that, especially when invoking from terminal.
But my IDE (both i tried) delegates build commands to cargo (which not unwise in general), which then incurs this few sec delay.
Even if i forgo using any IDE and switch over to any other text editor, I would still want to invoke cargo in my flow (either cargo run or cargo build). However running cargo build is enough to "taint" the binary and then the first invocation of it takes more time:
$ time ./target/debug/datafusion-cli --version
datafusion-cli 41.0.0
real 0m0.046s
user 0m0.014s
sys 0m0.017s
$ time cargo build --offline --bin datafusion-cli
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.38s
real 0m0.454s
user 0m0.131s
sys 0m0.121s
$ time ./target/debug/datafusion-cli --version
datafusion-cli 41.0.0
real 0m2.351s
user 0m0.010s
sys 0m0.044s
$ time ./target/debug/datafusion-cli --version
datafusion-cli 41.0.0
real 0m0.045s
user 0m0.013s
sys 0m0.023s
On Linux at least the only thing cargo does with the executable in target/debug when nothing has changed since the last build is opening the file as read-only and running statx on it. (presumably to get the last modified timestamp) It doesn't copy/hardlink the file again.
Maybe you could check if cargo does something different on macOS? I believe dtruss should work on non-system executables like cargo even when SIP is enabled.
you're right that I have SIP enabled. i did try to use dtrace and dtruss, but not successfully. the internet suggests i might run into "apple endpoint security framework". All in all, i couldn't get a strace-equivalent on cargo build (or anything else).
i did an blind experiment -- wrote a C program that opens the binary (r/w + append), and then execve's it. Doing open (even in write mode) didn't trigger the verification though.
Because I had been idly wondering for a while why XprotectService on my Mac kicked in for a second or two every time I tried to run some Rust binary I had just compiled. That had started some time ago, but I wasn't sure whether it came with an OS update or at some unrelated time.
Turns out that I'm using iTerm2 as a terminal, and in the "Developer Tools" section under "Privacy & Security" in the system preferences, Apple Terminal was listed under "Allow the applications below to run software locally that does not meet the system's security policy ", but not iTerm2!
Added iTerm2 to that list, restarted iTerm2 - and hey, no more XprotectService delays when doing cargo test!