I'm on macOS 10.13.5, learning to program Rust, and I use Nix to control my development environment.
Some actions, such as including the jsonwebtoken
library or installing the cargo-watch
module, cause a build that requires a macOS framework that appears to not be installed. I get this error message:
= note: ld: framework not found CoreServices
clang-5.0: error: linker command failed with exit code 1 (use -v to see invocation)
error: aborting due to previous error
error: failed to compile `cargo-watch v6.0.0`, intermediate artifacts can be found at `/var/folders/13/84dj8yr54_1c_pn0s8n7444h0000gn/T/cargo-install.lYPZaEduUBdu`
Caused by:
Could not compile `cargo-watch`.
This is an abbreviated version of the clang command that fails:
error: linking with `/nix/store/9j864incgjx7kqggbpisdi3nmssy4qm5-clang-wrapper-5.0.2/bin/cc` failed: exit code: 1
|
= note: "/nix/store/9j864incgjx7kqggbpisdi3nmssy4qm5-clang-wrapper-5.0.2/bin/cc" "-m64" "-L" ... "/nix/store/rfp87664xzhl6zv7dx5c1hixasqfxkp4-rustc-1.24.0/lib/rustlib/x86_64-apple-darwin/lib/libcompiler_builtins-ba331b20e371c580.rlib" "-framework" "CoreServices" "-framework" "CoreServices" "-l" "System" "-l" "resolv" "-l" "pthread" "-l" "c" "-l" "m"
The only thing that I have found to try was to add frameworks to my PATH, but either that answer is wrong or the PATH environment variable isn't able to go through cargo all the way to where I'm doing the build in question.
How to specify framework in clang? - Apple Community
Rust: 1.24.0
cargo install cargo-watch
How do I tell clang where to look for the frameworks? Does it involve a change to my working environment, or do I need to be looking into changing the build process for the crates that I want to install?
I discovered the clang -Xlinker -v
command, and the output is quite interesting:
@(#)PROGRAM:ld PROJECT:ld64-274.2
configured to support archs: armv6 armv7 armv7s arm64 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em (tvOS)
Library search paths:
/nix/store/ql6xbmdplca4sjpk0pz647p7djzri03c-libc++-5.0.2/lib
/nix/store/rfp87664xzhl6zv7dx5c1hixasqfxkp4-rustc-1.24.0/lib
/nix/store/ql6xbmdplca4sjpk0pz647p7djzri03c-libc++-5.0.2/lib
/nix/store/rfp87664xzhl6zv7dx5c1hixasqfxkp4-rustc-1.24.0/lib
/nix/store/8ykfqv6jx9jvfhnc4cdygdzg0piy8253-Libsystem-osx-10.11.6/lib
/nix/store/4papfih2r9xlsl9m7hlisparij8k9zaq-clang-5.0.2-lib/lib
Framework search paths:
/nix/store/hc6d711vwlwnn9swmkdpi9nbswbqg6h0-CF-osx-10.10.5/Library/Frameworks
/nix/store/hc6d711vwlwnn9swmkdpi9nbswbqg6h0-CF-osx-10.10.5/Library/Frameworks
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang-5.0: error: linker command failed with exit code 1 (use -v to see invocation)
This seems to point to things missing from my Nix shell and not the operating system or even clang
itself.
Apparently Nix both provides packages for standard Apple frameworks and sandboxes the environment enough that standard frameworks are unavailable.
Most of what I discovered for this solution came from Use proper SDK and command-line tools on OS X 10.11 and then from examining vim-plugins nix derivation.
First step is to actually install the frameworks that my project needs. They all live in nixpkgs.darwin.apple_sdk.frameworks
.
Doing that gets most of the link working, but then _CFURLResourceIsReachable
is an undefined symbol on my platform. I solve that with an updated NIX_LDFLAGS
variable (as suggested in the vim-plugins nix derivation). The end result for my project is this shell.nix
file:
let
pkgs = import <stable> {};
frameworks = pkgs.darwin.apple_sdk.frameworks;
in pkgs.stdenv.mkDerivation {
name = "orizentic";
buildInputs = [ pkgs.rustc
pkgs.cargo
frameworks.Security
frameworks.CoreFoundation
frameworks.CoreServices
];
shellHook = ''
export PS1="[$name] \[$txtgrn\]\u@\h\[$txtwht\]:\[$bldpur\]\w \[$txtcyn\]\$git_branch\[$txtred\]\$git_dirty \[$bldylw\]\$aws_env\[$txtrst\]\$ "
export NIX_LDFLAGS="-F${frameworks.CoreFoundation}/Library/Frameworks -framework CoreFoundation $NIX_LDFLAGS";
'';
}
This gives me the cargo-watch
package (which depends on CoreServices
and CoreFoundation
). It also apparently resolves the dependency jsonwebtoken
has on Security
though I have not managed to validate that yet.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With