# Building Julia for Nix

**URL:** <https://discourse.julialang.org/t/building-julia-for-nix/115304>\
**Category:** General Usage\
**Tags:** question, nixos\
**Created:** [June 7, 2024, 12:16am UTC](https://discourse.julialang.org/t/building-julia-for-nix/115304 "2024-06-07T00:16:45Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [June 7, 2024, 12:16am UTC](https://discourse.julialang.org/t/building-julia-for-nix/115304/1 "2024-06-07T00:16:45Z")

</div>

[Nix](https://nixos.org/) is this nice tool for reproducible builds on Linux and MacOS that I’ve been trying to learn.

Currently the main [nixpkgs](https://github.com/NixOS/nixpkgs/tree/master) repository only builds Julia on Linux\[1\] (both x86\_64 and aarch64), so I’m trying to add support for MacOS. Here is the Julia build listed in the tree: [nixpkgs/pkgs/development/compilers/julia at dd443d2d10ff7f7f7451f5bd04268f21daceb74d · NixOS/nixpkgs · GitHub](https://github.com/NixOS/nixpkgs/tree/dd443d2d10ff7f7f7451f5bd04268f21daceb74d/pkgs/development/compilers/julia)

I’ve got things like 99% of the way working with just these changes: [https://github.com/NixOS/nixpkgs/compare/master...MilesCranmer:nixpkgs:master](https://github.com/NixOS/nixpkgs/compare/master...MilesCranmer:nixpkgs:master). There is only a single error now. This error is as follows:

```julia-auto
libtool: compile: clang -mmacosx-version-min=11.0 -DHAVE_CONFIG_H -I. -I/private/tmp/nix-build-julia-1.10.4.drv-1/julia-1.10.4/deps/srccache/gmp-6.2.1 -D__GMP_WITHIN_GMP -O2 -pedantic -march=armv8-a -c /private/tmp/nix-build-julia-1.10.4.drv-1/julia-1.10.4/deps/srccache/gmp-6.2.1/tal-reent.c -fno-common -DPIC -o .libs/tal-reent.o
[19%] Building CXX object lib/Remarks/CMakeFiles/LLVMRemarks.dir/RemarkLinker.cpp.o
/private/tmp/nix-build-julia-1.10.4.drv-1/julia-1.10.4/deps/srccache/gmp-6.2.1/tal-reent.c:66:7: error: call to undeclared library function 'abort' with type 'void (void) __attribute__ ((noreturn))'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
      __GMP_ALLOC_OVERFLOW_FUNC ();
      ^
/private/tmp/nix-build-julia-1.10.4.drv-1/julia-1.10.4/deps/srccache/gmp-6.2.1/gmp-impl.h:737:5: note: expanded from macro '__GMP_ALLOC_OVERFLOW_FUNC'
    abort (); \
    ^
/private/tmp/nix-build-julia-1.10.4.drv-1/julia-1.10.4/deps/srccache/gmp-6.2.1/tal-reent.c:66:7: note: include the header <stdlib.h> or explicitly provide a declaration for 'abort'
/private/tmp/nix-build-julia-1.10.4.drv-1/julia-1.10.4/deps/srccache/gmp-6.2.1/gmp-impl.h:737:5: note: expanded from macro '__GMP_ALLOC_OVERFLOW_FUNC'
    abort (); \
    ^
1 error generated.
[20%] Building CXX object lib/MC/CMakeFiles/LLVMMC.dir/SPIRVObjectWriter.cpp.o

```

Does anybody know how to fix this? Is it from some patched version of GMP that Julia is using but isn’t available in Nix or something? (I’m assuming not, because the dependencies are listed in `srccache` which I’m guessing are the ones Julia packages)

* * *

1. Though note there is a `julia-bin` which simply re-packages the binaries.

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [June 7, 2024, 12:58am UTC](https://discourse.julialang.org/t/building-julia-for-nix/115304/2 "2024-06-07T00:58:03Z")

</div>

Got a bit farther with

```julia
  NIX_CFLAGS_COMPILE = [] ++ lib.optionals stdenv.isDarwin [
    "-Wno-error=implicit-function-declaration"
  ];

```

Not sure what is going on with that GMP dependency.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [June 7, 2024, 12:58am UTC](https://discourse.julialang.org/t/building-julia-for-nix/115304/3 "2024-06-07T00:58:20Z")

</div>

The Julia build of GMP is described here:

> **[Yggdrasil/G/GMP at master · JuliaPackaging/Yggdrasil](https://github.com/JuliaPackaging/Yggdrasil/tree/master/G%2FGMP)**
>
> Collection of builder repositories for BinaryBuilder.jl - JuliaPackaging/Yggdrasil

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [June 7, 2024, 1:00am UTC](https://discourse.julialang.org/t/building-julia-for-nix/115304/4 "2024-06-07T01:00:02Z")

</div>

I think those are the ones being used during the nix build? It just executes `make` on the Julia source tree. The only explicit dependencies to the nix build are:

```julia
{ lib
, stdenv
, fetchurl
, which
, python3
, gfortran
, cmake
, perl
, gnum4
, openssl
, libxml2
, unzip

```

---

<div class="post-metadata">

**Author:** ![dilumaluthge](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dilumaluthge/32/29283_2.png) [@dilumaluthge](https://discourse.julialang.org/u/dilumaluthge)\
**Post date:** [June 7, 2024, 1:00am UTC](https://discourse.julialang.org/t/building-julia-for-nix/115304/5 "2024-06-07T01:00:18Z")

</div>

Well, it looks like Miles’s branch is not using the JLL: [nixpkgs/pkgs/development/compilers/julia/generic.nix at 42c55c14c40b767cbbe6e7d636766ff0dd8f1f58 · MilesCranmer/nixpkgs · GitHub](https://github.com/MilesCranmer/nixpkgs/blob/42c55c14c40b767cbbe6e7d636766ff0dd8f1f58/pkgs/development/compilers/julia/generic.nix#L56)

Because of this line (line 56)

```julia
"USE_BINARYBUILDER=0"

```

---

<div class="post-metadata">

**Author:** ![dilumaluthge](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dilumaluthge/32/29283_2.png) [@dilumaluthge](https://discourse.julialang.org/u/dilumaluthge)\
**Post date:** [June 7, 2024, 1:01am UTC](https://discourse.julialang.org/t/building-julia-for-nix/115304/6 "2024-06-07T01:01:42Z")

</div>

Which would mean that Miles’s build is doing a source-build of GMP (with our GMP patches applied).

Looks like we only carry two patches for GMP:

1. [julia/deps/patches/gmp-alloc\_overflow.patch at master · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/blob/master/deps/patches/gmp-alloc_overflow.patch)
2. [julia/deps/patches/gmp-exception.patch at master · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/blob/master/deps/patches/gmp-exception.patch)

---

<div class="post-metadata">

**Author:** ![dilumaluthge](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dilumaluthge/32/29283_2.png) [@dilumaluthge](https://discourse.julialang.org/u/dilumaluthge)\
**Post date:** [June 7, 2024, 1:05am UTC](https://discourse.julialang.org/t/building-julia-for-nix/115304/7 "2024-06-07T01:05:06Z")

</div>

@MilesCranmer Can you reproduce the same error just by doing `make USE_BINARYBUILDER=0` on your macOS machine (not using Nix)?

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [June 7, 2024, 1:15am UTC](https://discourse.julialang.org/t/building-julia-for-nix/115304/8 "2024-06-07T01:15:10Z")

</div>

Thanks, indeed it looks like it’s just building GMP from source. Though there is the “julia-bin” version which is just pre-packaged Julia binaries.

> [@dilumaluthge](#):
>
> Can you reproduce the same error just by doing `make USE_BINARYBUILDER=0` on your macOS machine (not using Nix)?

Sadly I’ve never had much luck building Julia from source on my machine with the standard workflow. I think I’ve tried building it ~20 times and only gotten through on ~3 tries – there seems to be some weird interaction with my environment variables or system clang or brew that always breaks something, and by that point I usually move to Linux instead.

Actually the reason I’m learning Nix is precisely so I can build Julia in a repeatable way on my mac. Once this works it should _always_ work which is nice. (Kind of like Docker, but without needing to run in a virtual machine)

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [June 7, 2024, 1:29am UTC](https://discourse.julialang.org/t/building-julia-for-nix/115304/9 "2024-06-07T01:29:36Z")

</div>

Okay seems to get a bit farther with that `-Wno-error=implicit-function-declaration`. Now stuck at

```julia
configure: error: couldn't find libraries for gethostbyname()

```

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [June 7, 2024, 1:35am UTC](https://discourse.julialang.org/t/building-julia-for-nix/115304/10 "2024-06-07T01:35:20Z")

</div>

Could it be from the Julia makefile forcing xcode on any Darwin-like system?

The Julia Make.inc has `xcrun` hard-coded:

```make
# Note: we're passing *FLAGS here computed based on your system compiler to
# clang. If that causes you problems, you might want to build and/or run
# specific clang-sa-* files with clang explicitly selected:
# make CC=~+/../usr/tools/clang CXX=~+/../usr/tools/clang USECLANG=1 analyzegc
# make USECLANG=1 clang-sa-*
CLANGSA_FLAGS :=
CLANGSA_CXXFLAGS :=
ifeq ($(OS), Darwin) # on new XCode, the files are hidden
 CLANGSA_FLAGS += -isysroot $(shell xcrun --show-sdk-path -sdk macosx)
endif

```

However, the nix docs say:

> Some packages assume xcode is available and use `xcrun` to resolve build tools like `clang`, etc. This causes errors like `xcode-select: error: no developer tools were found at '/Applications/Xcode.app'` while the build doesn’t actually depend on xcode.
> 
> ```nix
> stdenv.mkDerivation {
> name = "libfoo-1.2.3";
> # ...
> prePatch = ''
> substituteInPlace Makefile \
> --replace-fail '/usr/bin/xcrun clang' clang
> '';
> }
> 
> ```
> 
> The package `xcbuild` can be used to build projects that really depend on Xcode. However, this replacement is not 100% compatible with Xcode and can occasionally cause issues.

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [June 7, 2024, 2:20am UTC](https://discourse.julialang.org/t/building-julia-for-nix/115304/11 "2024-06-07T02:20:27Z")

</div>

@sjkelly have you been using nix on your mac?

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [June 7, 2024, 3:14am UTC](https://discourse.julialang.org/t/building-julia-for-nix/115304/12 "2024-06-07T03:14:34Z")

</div>

Got a bit further with some hacks:

```nix
, xcbuild

```

as a dependency (nixpkg that acts like xcode) and

```nix
makeFlags = [
    "USE_BINARYBUILDER=1"
]

```

I think Nix people like to build everything from source, but since the only other option to `USE_BINARYBUILDER=1` is to use the entire prepackaged binary (i.e., `julia-bin`), I think it’s a decent tradeoff for having a source-compiled Julia on mac.

and

```nix
NIX_CFLAGS_COMPILE = [] ++ lib.optionals stdenv.isDarwin [
  "-Wno-error=implicit-function-declaration"
  "-Wno-error=elaborated-enum-base"
];

```

I’m not sure what those errors are for but the dependency didn’t seem too important?

The build error is now just this:

```julia
lld: error: malformed minimum version: 

```

while precompiling SparseArrays.

> **Full error message:**
>
> ```julia
> JULIA stdlib/SparseArrays.release.image
> lld: error: malformed minimum version: 
> lld: error: malformed minimum version: 
> lld: error: malformed minimum version: 
> lld: error: malformed minimum version: 
> lld: error: malformed minimum version: 
> lld: error: malformed minimum version: 
> ERROR: ERROR: ERROR: failed process: failed process: failed process: Process(Process(Process(setenv(setenv(setenv(...
> ...
> make[1]: *** [pkgimage.mk:92: stdlib/libLLVM_jll.release.image] Error 1
> make[1]: *** [pkgimage.mk:89: stdlib/PCRE2_jll.release.image] Error 1
> lld: error: malformed minimum version: 
> lld: error: malformed minimum version: 
> ERROR: failed process: Process(setenv(...
> 
> ...
> mp/nix-build-julia-1.10.4.drv-0/julia-1.10.4/usr/share/julia/stdlib/v1.10", "NIX_ENFORCE_PURITY=1", "propagatedNativeBuildInputmake[1]: *** [pkgimage.mk:79: stdlib/Profile.release.image] Error 1
> s=", "ZERO_AR_DATE=1", "stdenv=/nix/store/q2sr9a4likgf0c0ib3zxxy63vr0dr0w9-stdenv-darwin", "NIX_HARDENING_ENABLE=bindnow format fortify fortify3 pic relro stackprotector strictoverflow", "MAKE_TERMOUT=/dev/ttys004", "JULIA_CPU_TARGET=generic;cortex-a57;thunderx2t99;carmel,clone_all;apple-m1,base(3);neoverse-512tvb,base(3)", "USE_BINARYBUILDER=1", "OPENBLAS_MAIN_FREE=1"]), ProcessExited(1)) [1]
> 
> Stacktrace:
> [1] pipeline_error
> @ ./process.jl:565 [inlined]
> [2] run(::Cmd, ::Base.DevNull, ::Vararg{Any}; wait::Bool)
> @ Base ./process.jl:480
> [3] run
> @ ./process.jl:477 [inlined]
> [4] link_image (repeats 2 times)
> @ ./linking.jl:166 [inlined]
> [5] compilecache(pkg::Base.PkgId, path::String, internal_stderr::IO, internal_stdout::IO, keep_loaded_modules::Bool)
> @ Base ./loading.jl:2379
> [6] compilecache
> @ ./loading.jl:2340 [inlined]
> [7] (::Base.var"#968#969"{Base.PkgId})()
> @ Base ./loading.jl:1974
> [8] mkpidlock(f::Base.var"#968#969"{Base.PkgId}, at::String, pid::Int32; kwopts::@Kwargs{stale_age::Int64, wait::Bool})
> @ FileWatching.Pidfile /private/tmp/nix-build-julia-1.10.4.drv-0/julia-1.10.4/usr/share/julia/stdlib/v1.10/FileWatching/src/pidfile.jl:93
> [9] #mkpidlock#6
> @ /private/tmp/nix-build-julia-1.10.4.drv-0/julia-1.10.4/usr/share/julia/stdlib/v1.10/FileWatching/src/pidfile.jl:88 [inlined]
> [10] trymkpidlock(::Function, ::Vararg{Any}; kwargs::@Kwargs{stale_age::Int64})
> @ FileWatching.Pidfile /private/tmp/nix-build-julia-1.10.4.drv-0/julia-1.10.4/usr/share/julia/stdlib/v1.10/FileWatching/src/pidfile.jl:111
> [11] #invokelatest#2
> @ ./essentials.jl:894 [inlined]
> [12] invokelatest
> @ ./essentials.jl:889 [inlined]
> [13] maybe_cachefile_lock(f::Base.var"#968#969"{Base.PkgId}, pkg::Base.PkgId, srcpath::String; stale_age::Int64)
> @ Base ./loading.jl:2983
> [14] maybe_cachefile_lock
> @ ./loading.jl:2980 [inlined]
> [15] _require(pkg::Base.PkgId, env::String)
> @ Base ./loading.jl:1970
> [16] __require_prelocked(uuidkey::Base.PkgId, env::String)
> @ Base ./loading.jl:1812
> [17] #invoke_in_world#3
> @ ./essentials.jl:926 [inlined]
> [18] invoke_in_world
> @ ./essentials.jl:923 [inlined]
> [19] _require_prelocked(uuidkey::Base.PkgId, env::String)
> @ Base ./loading.jl:1803
> [20] macro expansion
> @ ./loading.jl:1790 [inlined]
> [21] macro expansion
> @ ./lock.jl:267 [inlined]
> [22] __require(into::Module, mod::Symbol)
> @ Base ./loading.jl:1753
> [23] #invoke_in_world#3
> @ ./essentials.jl:926 [inlined]
> [24] invoke_in_world
> @ ./essentials.jl:923 [inlined]
> [25] require(into::Module, mod::Symbol)
> @ Base ./loading.jl:1746
> [26] include(mod::Module, _path::String)
> @ Base ./Base.jl:495
> [27] include(x::String)
> @ SparseArrays /private/tmp/nix-build-julia-1.10.4.drv-0/julia-1.10.4/usr/share/julia/stdlib/v1.10/SparseArrays/src/SparseArrays.jl:6
> [28] top-level scope
> @ /private/tmp/nix-build-julia-1.10.4.drv-0/julia-1.10.4/usr/share/julia/stdlib/v1.10/SparseArrays/src/SparseArrays.jl:77
> [29] include
> @ ./Base.jl:495 [inlined]
> [30] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::Nothing)
> @ Base ./loading.jl:2222
> [31] top-level scope
> @ stdin:3
> in expression starting at /private/tmp/nix-build-julia-1.10.4.drv-0/julia-1.10.4/usr/share/julia/stdlib/v1.10/SparseArrays/src/solvers/LibSuiteSparse.jl:1
> in expression starting at /private/tmp/nix-build-julia-1.10.4.drv-0/julia-1.10.4/usr/share/julia/stdlib/v1.10/SparseArrays/src/SparseArrays.jl:3
> in expression starting at stdin:3
> ERROR: Failed to precompile SparseArrays [2f01184e-e22b-5df5-ae63-d93ebab69eaf] to "/private/tmp/nix-build-julia-1.10.4.drv-0/julia-1.10.4/usr/share/julia/compiled/v1.10/SparseArrays/jl_ihJKs9".
> Stacktrace:
> [1] error(s::String)
> @ Base ./error.jl:35
> [2] compilecache(pkg::Base.PkgId, path::String, internal_stderr::IO, internal_stdout::IO, keep_loaded_modules::Bool)
> @ Base ./loading.jl:2468
> [3] compilecache
> @ ./loading.jl:2340 [inlined]
> [4] compilecache
> @ ./loading.jl:2330 [inlined]
> [5] compilecache(pkg::Base.PkgId)
> @ Base ./loading.jl:2328
> [6] top-level scope
> @ none:1
> make[1]: *** [pkgimage.mk:133: stdlib/SparseArrays.release.image] Error 1
> make: *** [Makefile:112: stdlibs-cache-release] Error 2
> 
> ```

---

<div class="post-metadata">

**Author:** ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)\
**Post date:** [June 7, 2024, 3:20am UTC](https://discourse.julialang.org/t/building-julia-for-nix/115304/13 "2024-06-07T03:20:50Z")

</div>

That’s likely coming from package images

> <https://github.com/JuliaLang/julia/blob/d71441b505473c599a8a3009db92cafd41272197/base/linking.jl#L117>

Which gets this value from [julia/base/Makefile at d71441b505473c599a8a3009db92cafd41272197 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/blob/d71441b505473c599a8a3009db92cafd41272197/base/Makefile#L93)

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [June 7, 2024, 3:31am UTC](https://discourse.julialang.org/t/building-julia-for-nix/115304/14 "2024-06-07T03:31:30Z")

</div>

Awesome, thanks! This patch to `base/Makefile` seems to fix it:

```diff
-	@echo "const MACOS_PRODUCT_VERSION = \"$(shell sw_vers -productVersion)\"" >> $@
-	@echo "const MACOS_PLATFORM_VERSION = \"$(shell xcrun --show-sdk-version)\"" >> $@
+	@echo "const MACOS_PRODUCT_VERSION = \"14.1.2\"" >> $@
+	@echo "const MACOS_PLATFORM_VERSION = \"14.4\"" >> $@

```

I just used my own SDK version; hopefully that won’t break anything on other machines?

It seems like other people often do a similar patch in Nix packages: [Code search results · GitHub](https://github.com/search?q=repo:NixOS/nixpkgs%20sw_vers&type=code)

Last error… (hopefully)

```julia
ERROR: LoadError: failed to clone from https://github.com/JuliaRegistries/General.git, error: GitError(Code:ERROR, Class:SSL, Your Julia is built with a SSL/TLS engine that libgit2 doesn't know how to configure to use a file or directory of certificate authority roots, but your environment specifies one via the SSL_CERT_FILE variable. If you believe your system's root certificates are safe to use, you can `export JULIA_SSL_CA_ROOTS_PATH=""` in your environment to use those instead.)

```

I guess I’ll just put in that SSL patch

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [June 7, 2024, 5:44am UTC](https://discourse.julialang.org/t/building-julia-for-nix/115304/15 "2024-06-07T05:44:06Z")

</div>

Seems to work with those patches. Thanks everyone!

[PR here](https://github.com/NixOS/nixpkgs/pull/317900)
