# BinaryBuilder and GCC multi-versioning

**URL:** <https://discourse.julialang.org/t/binarybuilder-and-gcc-multi-versioning/15314>\
**Category:** Tooling\
**Created:** [September 21, 2018, 7:57pm UTC](https://discourse.julialang.org/t/binarybuilder-and-gcc-multi-versioning/15314 "2018-09-21T19:57:28Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![staticfloat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/staticfloat/32/34_2.png) [@staticfloat](https://discourse.julialang.org/u/staticfloat)\
**Post date:** [September 21, 2018, 7:57pm UTC](https://discourse.julialang.org/t/binarybuilder-and-gcc-multi-versioning/15314/1 "2018-09-21T19:57:28Z")

</div>

I have just merged [New RootFS by staticfloat · Pull Request #355 · JuliaPackaging/BinaryBuilder.jl · GitHub](https://github.com/JuliaPackaging/BinaryBuilder.jl/pull/355) . This has some implications for those of you building things that depend on specific versions of GCC. In particular, if anything links against `libgfortran`, you’re going to need to compile GCC-version-specific tarballs. This is denoted through extra abi tags added to the end of triplets; e.g. we can have things like `x86_64-linux-gnu-gcc7` now. The only compiler ABI stuff that we’re tracking right now is GCC major version (with the possible values `gcc4`, `gcc7` and `gcc8`, which link to libgfortran 3, 4 and 5 respectively), although we have the machinery in place to start differentiating on things such as `cxx11` string ABI choice, which may or may not happen in the future.

As builder repository owners, the main change is that I have added a new audit pass that will check to see if any of your binaries link against `libgfortran`. If they do, and the current target is (for instance) `x86_64-linux-gnu` (e.g. no “gcc version tag”) then it will print out a big fat warning. The warning will tell you to update your `build_tarballs.jl` file to include the line `platforms = expand_gcc_versions(platforms)`. What this does is just take a single `Platform` object that looks like `x86_64-linux-gnu` and turn it into `[x86_64-linux-gnu-gcc4, x86_64-linux-gnu-gcc7, x86_64-linux-gnu-gcc8]`. In essence, it will force BinaryBuilder to do the full combinatorial explosion of GCC versions for all of your platforms. [Here’s an example](https://github.com/JuliaLinearAlgebra/OpenBLASBuilder/pull/9/commits/993226fdc9551cf9a99a871d62599bee9033615f) of how simple a change this is for you.

From the BinaryProvider side, `build.jl` for right now the main difference is that `build.jl` files are going to use a `choose_download(download_info, platform_key_abi())` function rather than just try to pull a value out of the dict directly (e.g. `download_info[platform_key_abi()]`). This is because we need the ability to pull out the entry that corresponds to our GCC version precisely, OR pull out the entry that has no GCC version encoded within it. (e…g. for pure-C dependencies, rather than FORTRAN dependencies). This isn’t a big change, and BB will automatically start generating `build.jl` files that conform to this, but it’s a good thing to know. You can see an example of what this looks like in the generated `build.jl` for [OpenblasBuilder](https://github.com/JuliaLinearAlgebra/OpenBLASBuilder/releases/download/v0.3.0-2/build_OpenBLAS.v0.3.0.jl).

This is the critical step we’ve needed in order to have BinaryProvider downloads for things like Arpack.jl that work for from-source builds of Julia and not “just” the official Julia binaries. An incredible amount of work went into this release of BinaryBuilder, and we thank you all for your patience.

---

<div class="post-metadata">

**Author:** ![jstrube](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jstrube/32/525_2.png) [@jstrube](https://discourse.julialang.org/u/jstrube)\
**Post date:** [September 22, 2018, 1:34am UTC](https://discourse.julialang.org/t/binarybuilder-and-gcc-multi-versioning/15314/2 "2018-09-22T01:34:17Z")

</div>

Is there a way to disable specific compiler versions in the expansion? For example, I’m building something that doesn’t work on gcc4, but now, with the expansion, BinaryBuilder tries this and throws an error.

---

<div class="post-metadata">

**Author:** ![jstrube](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jstrube/32/525_2.png) [@jstrube](https://discourse.julialang.org/u/jstrube)\
**Post date:** [September 22, 2018, 3:21am UTC](https://discourse.julialang.org/t/binarybuilder-and-gcc-multi-versioning/15314/3 "2018-09-22T03:21:30Z")

</div>

OK, got it. One can explicitly provide the gcc versions, like in the OpenblasBuilder example.

```julia
platforms = [
    Linux(:aarch64, libc=:glibc, compiler_abi=CompilerABI(:gcc4)), 
    Linux(:aarch64, libc=:glibc, compiler_abi=CompilerABI(:gcc7)),
#and so on
]

```

---

<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:** [September 22, 2018, 4:32pm UTC](https://discourse.julialang.org/t/binarybuilder-and-gcc-multi-versioning/15314/4 "2018-09-22T16:32:03Z")

</div>



---

<div class="post-metadata">

**Author:** ![jstrube](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jstrube/32/525_2.png) [@jstrube](https://discourse.julialang.org/u/jstrube)\
**Post date:** [September 29, 2018, 6:38pm UTC](https://discourse.julialang.org/t/binarybuilder-and-gcc-multi-versioning/15314/5 "2018-09-29T18:38:29Z")

</div>

One more question for clarification:  
How invasive is this change? If I have one dependency that is now versioned, how does that affect the other items in the dependency chain? Do they now all have to be versioned? Or can we mix and match.

---

<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:** [October 1, 2018, 2:01am UTC](https://discourse.julialang.org/t/binarybuilder-and-gcc-multi-versioning/15314/6 "2018-10-01T02:01:39Z")

</div>

What do I do if the library doesn’t support gcc-4.8.5?  
Do I just ignore the fact the build fails while running the wizard, cross my fingers and hope everything magically works out and I get a deps.jl file where I can edit the `platforms` variable, like in your comment?

Or is there a better way?

I want to wrap SLEEF. My plan for now is is, in case of gcc4 or non-x86 architectures, to just default to calling the regular versions.

This comment has been cross-posted from slack.

---

<div class="post-metadata">

**Author:** ![staticfloat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/staticfloat/32/34_2.png) [@staticfloat](https://discourse.julialang.org/u/staticfloat)\
**Post date:** [October 1, 2018, 4:15am UTC](https://discourse.julialang.org/t/binarybuilder-and-gcc-multi-versioning/15314/7 "2018-10-01T04:15:25Z")

</div>

> [@jstrube](#):
>
> If I have one dependency that is now versioned, how does that affect the other items in the dependency chain?

If you have a gfortran library that you build for GCC 4/7/8, then have a pure-C library that is built with only GCC 4, it should be able to link against the gfortran library that was built for GCC 7 or GCC 8. The only ABIs that change are the gfortran and C++ ABIs. So items further on up the dependency chain should only need to be versioned if they themselves require it.

> [@Elrod](#):
>
> What do I do if the library doesn’t support gcc-4.8.5?

If your library cannot be built with GCC-4.8.5, then you should build it against only GCC 7 and 8. You can do this by specifying explicitly which triplets you want to compile for, either on the command line (e.g. `julia --color=yes build_tarballs.jl --verbose x86_64-linux-gnu-gcc7,x86_64-linux-gnu-gcc8,etc...`) or within your build\_tarballs.jl file with something like:

```
platforms = [p for p in supported_platforms() if compiler_abi(p).gcc_version != :gcc4]

```

If your library relies on GCC multiversioning (e.g. it uses gfortran) and it cannot be built with GCC 4, then you will simply have to support the platforms it can be built with. If it can be built with GCC 5 or 6 but not 4, we could conceivably add an escape hatch for you to be able to compile against those versions (Which are ABI-compatible with GCC 4) but that is not supported yet.
