Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cargo failed to run custom build command if strip in m1 mac #11641

Closed
Ylarod opened this issue Jan 28, 2023 · 6 comments
Closed

cargo failed to run custom build command if strip in m1 mac #11641

Ylarod opened this issue Jan 28, 2023 · 6 comments
Labels
C-bug Category: bug

Comments

@Ylarod
Copy link

Ylarod commented Jan 28, 2023

Problem

cargo faild to run custom build command if

[profile.release]
strip = true

command output

$ cargo build --release
   Compiling libc v0.2.139
error: failed to run custom build command for `libc v0.2.139`

Caused by:
  process didn't exit successfully: `/private/tmp/tet/target/release/build/libc-c9b37293d5307b87/build-script-build` (signal: 9, SIGKILL: kill)

Steps

Cargo.toml

[package]
name = "tet"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
libc = "0.2"

[profile.release]
strip = true

main.rs

fn main() {
    println!("Hello, world!");
    unsafe{
        libc::printf("Hello, world!\n".as_ptr() as *const libc::c_char);
    }
}

then just run cargo build --release

Possible Solution(s)

No response

Notes

$ file $(which cargo)
Mach-O 64-bit executable arm64

$ file $(which rustc)
Mach-O 64-bit executable arm64

$ file $(which rustup)
Mach-O 64-bit executable arm64

$ rustup -V
rustup 1.25.1 (bb60b1e89 2022-07-12)
info: This is the version for the rustup toolchain manager, not the rustc compiler.
info: The currently active `rustc` version is `rustc 1.67.0 (fc594f156 2023-01-24)`

$ rustc -V
rustc 1.67.0 (fc594f156 2023-01-24)

$ uname -a
Darwin YlarodMBP 22.1.0 Darwin Kernel Version 22.1.0: Sun Oct  9 20:15:09 PDT 2022; root:xnu-8792.41.9~2/RELEASE_ARM64_T6000 arm64

$ sw_vers
ProductName:		macOS
ProductVersion:		13.0.1
BuildVersion:		22A400

Version

cargo 1.67.0 (8ecd4f20a 2023-01-10)
release: 1.67.0
commit-hash: 8ecd4f20a9efb626975ac18a016d480dc7183d9b
commit-date: 2023-01-10
host: aarch64-apple-darwin
libgit2: 1.5.0 (sys:0.16.0 vendored)
libcurl: 7.84.0 (sys:0.4.59+curl-7.86.0 system ssl:(SecureTransport) LibreSSL/3.3.6)
os: Mac OS 13.0.1 [64-bit]
@Ylarod Ylarod added the C-bug Category: bug label Jan 28, 2023
@ehuss
Copy link
Contributor

ehuss commented Jan 28, 2023

Thanks for the detailed report!

This is likely similar to #8913. There are a few ways to help diagnose the issue:

  • Check the file type of the build script executable and make sure it is arm64.
  • Make sure the terminal you are running from is arm64.
  • Make sure you have the latest xcode (and run xcode-select -p to check which one you are using), and that it is the appropriate arm64.
  • Run the Console app. Open it and "Start Streaming" and then run cargo, then hit pause. There will likely be a large amount of output to sift through, but there might be some messages related to what you just ran.

@Ylarod
Copy link
Author

Ylarod commented Jan 29, 2023

I checked all related issue, including #8913

The build processes successfully if I remove strip = true flag.

In other place, I found that this may be a codesign problem.

$ cp /private/tmp/tet/target/release/build/libc-c9b37293d5307b87/build-script-build libc_build_failed

$ cargo clean

$ cargo build --release

$ cp /private/tmp/tet/target/release/build/libc-d7f7d038737218e5/build-script-build libc_build

$ file libc_build
libc_build: Mach-O 64-bit executable arm64

$ file libc_build_failed
libc_build_failed: Mach-O executable arm64

$ codesign -dvvvvv libc_build
Executable=/private/tmp/tet/libc_build
Identifier=build_script_build-d7f7d038737218e5
Format=Mach-O thin (arm64)
CodeDirectory v=20400 size=4892 flags=0x20002(adhoc,linker-signed) hashes=149+0 location=embedded
VersionPlatform=1
VersionMin=851968
VersionSDK=851968
Hash type=sha256 size=32
CandidateCDHash sha256=ef1cd0170142b675f8fb0f562aa884da64a79e24
CandidateCDHashFull sha256=ef1cd0170142b675f8fb0f562aa884da64a79e24911906eb56b54d91a8b272f1
Hash choices=sha256
CMSDigest=ef1cd0170142b675f8fb0f562aa884da64a79e24911906eb56b54d91a8b272f1
CMSDigestType=2
Executable Segment base=0
Executable Segment limit=344064
Executable Segment flags=0x1
Page size=4096
Launch Constraints:
	None
CDHash=ef1cd0170142b675f8fb0f562aa884da64a79e24
Signature=adhoc
Info.plist=not bound
TeamIdentifier=not set
Sealed Resources=none
Internal requirements=none

$ codesign -dvvvvv libc_build_failed
libc_build_failed: code object is not signed at all

So, it seems that somthing is mistakely striped.

But when I open libc_build_failed in ida64, no code disassembled.

libc_build_failed


binary of build-script-build

libc_build.zip
libc_build_failed.zip


$ cargo build --release --verbose
   Compiling libc v0.2.139
     Running `rustc --crate-name build_script_build /Users/ylarod/.cargo/registry/src/mirrors.ustc.edu.cn-61ef6e0cd06fb9b8/libc-0.2.139/build.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type bin --emit=dep-info,link -C embed-bitcode=no -C debug-assertions=off --cfg 'feature="default"' --cfg 'feature="std"' -C metadata=c9b37293d5307b87 -C extra-filename=-c9b37293d5307b87 --out-dir /private/tmp/tet/target/release/build/libc-c9b37293d5307b87 -C strip=symbols -L dependency=/private/tmp/tet/target/release/deps --cap-lints allow`
     Running `/private/tmp/tet/target/release/build/libc-c9b37293d5307b87/build-script-build`
error: failed to run custom build command for `libc v0.2.139`

Caused by:
  process didn't exit successfully: `/private/tmp/tet/target/release/build/libc-c9b37293d5307b87/build-script-build` (signal: 9, SIGKILL: kill)
$ cargo build --release --verbose
   Compiling libc v0.2.139
     Running `rustc --crate-name build_script_build /Users/ylarod/.cargo/registry/src/mirrors.ustc.edu.cn-61ef6e0cd06fb9b8/libc-0.2.139/build.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type bin --emit=dep-info,link -C embed-bitcode=no -C debug-assertions=off --cfg 'feature="default"' --cfg 'feature="std"' -C metadata=d7f7d038737218e5 -C extra-filename=-d7f7d038737218e5 --out-dir /private/tmp/tet/target/release/build/libc-d7f7d038737218e5 -L dependency=/private/tmp/tet/target/release/deps --cap-lints allow`
     Running `/private/tmp/tet/target/release/build/libc-d7f7d038737218e5/build-script-build`

-C strip=symbols may be the problem

$ cat main.rs
fn main() {
    println!("Hello, world!");
}

$ rustc main.rs

$ ./main
Hello, world!

$ rustc main.rs -C strip=symbols

$ ./main
[1]    41514 killed     ./main

So that this seems a rustc problem.


1



$ cargo build --release
   Compiling libc v0.2.139
error: failed to run custom build c
ommand for `libc v0.2.139`

Caused by:
  process didn't exit successfully: `/private/tmp/tet/target/release/build/libc-c9b37293d5307b87/build-script-build` (signal: 9, SIGKILL: kill)

$ file /private/tmp/tet/target/release/build/libc-c9b37293d5307b87/build-script-build
/private/tmp/tet/target/release/build/libc-c9b37293d5307b87/build-script-build: Mach-O executable arm64

2

$ arch -arm64e sh
sh-3.2$ cargo build --release
   Compiling libc v0.2.139
error: failed to run custom build command for `libc v0.2.139`

Caused by:
  process didn't exit successfully: `/private/tmp/tet/target/release/build/libc-c9b37293d5307b87/build-script-build` (signal: 9, SIGKILL: kill)
sh-3.2$ file /private/tmp/tet/target/release/build/libc-c9b37293d5307b87/build-script-build
/private/tmp/tet/target/release/build/libc-c9b37293d5307b87/build-script-build: Mach-O executable arm64

3

$ xcode-select -p
/Applications/Xcode.app/Contents/Developer

$ file /Applications/Xcode.app/Contents/Developer/usr/bin/ld
/Applications/Xcode.app/Contents/Developer/usr/bin/ld: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64:Mach-O 64-bit executable arm64]
/Applications/Xcode.app/Contents/Developer/usr/bin/ld (for architecture x86_64):	Mach-O 64-bit executable x86_64
/Applications/Xcode.app/Contents/Developer/usr/bin/ld (for architecture arm64):	Mach-O 64-bit executable arm64

4
nothing suspective

@ehuss
Copy link
Contributor

ehuss commented Jan 29, 2023

rustc uses the strip executable to strip the binary. I would check to ensure that /usr/bin/strip is first in your PATH, and that executable maps to /Applications/Xcode.app/Contents/Developer/usr/bin/strip (run strip -? and it will print the path).

@Ylarod
Copy link
Author

Ylarod commented Jan 29, 2023

Sorry, it seems that this is my enviroment problem.

Thanks for your support!

$ which strip
/opt/homebrew/opt/binutils/bin/strip

$ export PATH="/usr/bin:$PATH"

$ which strip
/usr/bin/strip

$ strip -
fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/strip: no files specified

$ rustc main.rs -C strip=symbols

$ ./main
Hello, world!

@Ylarod Ylarod closed this as completed Jan 29, 2023
@brson
Copy link
Contributor

brson commented Aug 29, 2023

I have also run into this problem recently and the error mode is baffling. It was kind of luck that I managed to trace it back to strip = true and then find this issue. cargo and/or rustc could probably do something more helpful here.

@dominix
Copy link

dominix commented Nov 2, 2023

the command strip from MacoS conflict with the one installed by brew from package binutils. that recommended
PATH="/opt/homebrew/opt/binutils/bin:$PATH"
So in my .bash-profile I have changed PATH to be
PATH="$PATH:/opt/homebrew/opt/binutils/bin"
and now cargo stuff compile correctly now.
I mean the issue may not be related to M1 or M2 Mac but to Brew hiding native MacOs commands.

bors added a commit that referenced this issue Jan 15, 2024
Strip debuginfo when debuginfo is not requested

### What does this PR try to resolve?

This PR implements [this proposal](#4122 (comment)). It contains a detailed description of the change.

As a summary, this PR modifies Cargo so that if the user doesn't set `strip` explicitly, and debuginfo is not enabled for any package being compiled, Cargo will implicitly set `strip = "debuginfo"`, to strip pre-existing debuginfo coming from the standard library. This reduces the default size of release binaries considerably (~4.5 MiB => ~450 KiB for helloworld on Linux x64).

Perhaps we could only add the `-Cstrip` option for the leaf/root target (i.e., a binary), but cargo already passes `-Cstrip` to libraries if it's set by `[profile.<...>.package.<lib>]`, so it seems harmless.

Fixes: #4122

### How should we test and review this PR?

Best reviewed commit by commit. There is one commit that fixes an existing related test that was using wrong assertion.

### Additional information

The implementation of the deferred option was inspired by `DebugInfo`, which already uses a similar concept.

### Unresolved questions
Should we also do this on macOS by default? It [seems](#11641) that there can be some issues with `strip` there. If it doesn't work, it basically inhibits compilation in release mode, with no easy way to opt out (unless the user explicitly requests debuginfo, but that's not the same as the previous state).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: bug
Projects
None yet
Development

No branches or pull requests

4 participants