rust-lang / libc

Raw bindings to platform APIs for Rust
https://docs.rs/libc
Apache License 2.0
2.07k stars 1.04k forks source link

libc does not seem to respect the CC environment variable #3603

Closed molysgaard closed 1 month ago

molysgaard commented 7 months ago

To reproduce:

error: could not compile libc (build script) due to 1 previous error


Correct behaviour should be that the `build.rs` script should honor the `CC` environment variable
and use that to link.

This is explicitly a problem when trying to get reproducible builds in systems like GUIX or (I presume, NIX).

# Guix example
```scheme
; working-developer-shell.scm
(use-modules (gnu)
             (gnu packages commencement)
         (guix)
         (guix packages)
         (guix build-system trivial)
         (guix licenses)
             )

(define base-manifest (specifications->manifest
  '(
    "rust@1.73.0"
    "rust-cargo@0.74"
    "gcc-toolchain"
    "coreutils"
    )))

(define-public custom-cc
  (package
    (name "custom-cc")
    (version "1.0")
    (source #f)
    (build-system trivial-build-system)
    (arguments
     `(#:modules ((guix build utils))
       #:builder (begin
                   (use-modules (guix build utils))
                   (let* ((out (assoc-ref %outputs "out"))
                          (bin (string-append out "/bin"))
                          ;; Adjust the path to the gcc binary as necessary.
                          (gcc-path (string-append (assoc-ref %build-inputs "gcc-toolchain") "/bin/gcc")))
                     (mkdir-p bin)
                     (symlink gcc-path (string-append bin "/cc"))))))
    (inputs
     `(("gcc-toolchain", gcc-toolchain)))
    (synopsis "Custom package providing a cc symlink to gcc")
    (description "This package installs a symlink named 'cc' in its bin output, which points to the gcc binary in the gcc-toolchain package.")
    (home-page "https://example.com")
    (license gpl3)))

(define custom-cc-manifest (manifest (list (package->manifest-entry custom-cc))))

(concatenate-manifests (list base-manifest custom-cc-manifest))
; broken-developer-shell.scm
(use-modules (gnu)
             (gnu packages commencement)
         (guix)
         (guix packages)
         (guix build-system trivial)
         (guix licenses)
             )

(define base-manifest (specifications->manifest
  '(
    "rust@1.73.0"
    "rust-cargo@0.74"
    "gcc-toolchain"
    "coreutils"
    )))

base-manifest

Broken example using guix

git clone https://github.com/rust-lang/libc.git
cd libc
guix environment -m ../broken-developer-shell.scm --pure
CC=gcc cargo build

Working example using guix

In this example, we add a symlink named cc in our PATH that points to gcc.

git clone https://github.com/rust-lang/libc.git
cd libc
guix environment -m ../working-developer-shell.scm --pure
cargo build
jschwe commented 3 months ago

This is not an issue of the libc crate, but of the rust compiler, since rustc invokes the linker. You should be able to use CARGO_TARGET_<triple>_LINKER to set the linker or alternartively open an issue at rust compiler repository.

tgross35 commented 1 month ago

The cc crate should actually respect these, but @jschwe is correct that rustc does not use CC as the linker. The linker can be specified in a Cargo config file https://doc.rust-lang.org/cargo/reference/config.html?highlight=linker#targettriplelinker, or by passing -Clinker=... to rustc.

I don't think there is anything to do here so I will close this, feel free to follow up if there is more.