Skip to content

Commit

Permalink
Add Sys.glibc_version and Sys.isglibc
Browse files Browse the repository at this point in the history
These functions come in handy when linking to a library that assumes a
particular minimum version of glibc, or for determining whether the
system's libc is musl.

These functions return v0.0.0 and false, respectively, for non-Linux
systems and for Linux systems which do not use glibc.
  • Loading branch information
ararslan committed Jul 8, 2018
1 parent b6f9244 commit 30b21e7
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 4 deletions.
5 changes: 5 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,10 @@ Library improvements
optional keyword argument, as in `reduce(op, itr; init=v0)`. Similarly for `foldl`,
`foldr`, `mapreduce`, `mapfoldl` and `mapfoldr`. ([#27711])

* `Sys.glibc()` determines whether glibc is linked to Julia, and `Sys.glibc_version()`
returns the version of the linked glibc if applicable. ([#27223])


Compiler/Runtime improvements
-----------------------------

Expand Down Expand Up @@ -1640,5 +1644,6 @@ Command-line option changes
[#27164]: https://github.com/JuliaLang/julia/issues/27164
[#27189]: https://github.com/JuliaLang/julia/issues/27189
[#27212]: https://github.com/JuliaLang/julia/issues/27212
[#27223]: https://github.com/JuliaLang/julia/issues/27223
[#27248]: https://github.com/JuliaLang/julia/issues/27248
[#27401]: https://github.com/JuliaLang/julia/issues/27401
39 changes: 38 additions & 1 deletion base/sysinfo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ export BINDIR,
isunix,
iswindows,
isexecutable,
which
which,
glibc_version,
isglibc

import ..Base: show

Expand Down Expand Up @@ -335,6 +337,41 @@ windows_version

const WINDOWS_VISTA_VER = v"6.0"

if islinux()
function glibc_version()
# Proxy for a pointer to libc, since libc is linked into Julia
libc = ccall(:jl_dlopen, Ptr{Cvoid}, (Ptr{Cvoid}, Cuint), C_NULL, 0x0)
@assert libc != C_NULL # We have bigger problems if this is not the case
vers_ptr = ccall(:jl_dlsym_e, Ptr{Cvoid}, (Ptr{Cvoid}, Cstring),
libc, "gnu_get_libc_version")
vers_ptr == C_NULL && return v"0.0.0" # non-glibc
vers_str = unsafe_string(ccall(vers_ptr, Ptr{UInt8}, ()))
occursin(Base.VERSION_REGEX, vers_str) ? VersionNumber(vers_str) : v"0.0.0"
end

isglibc() = glibc_version() > v"0.0.0"
else
glibc_version() = v"0.0.0"
isglibc() = false
end

"""
Sys.glibc_version()
Return the version of glibc linked to Julia on Linux. This is `v"0.0.0"` on
other systems as well as Linux systems which use a libc other than glibc
(e.g. musl).
"""
glibc_version

"""
Sys.isglibc()
Determine whether Julia links to glibc on the current system. This is `false`
on systems other than Linux as well as for Linux systems which do not use glibc.
"""
isglibc

"""
Sys.isexecutable(path::String)
Expand Down
2 changes: 2 additions & 0 deletions doc/src/base/base.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ Base.Sys.islinux
Base.Sys.isbsd
Base.Sys.iswindows
Base.Sys.windows_version
Base.Sys.glibc_version
Base.Sys.isglibc
Base.@static
```

Expand Down
13 changes: 10 additions & 3 deletions doc/src/manual/handling-operating-system-variation.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,16 @@ if Sys.iswindows()
end
```

Note that `islinux` and `isapple` are mutually exclusive subsets of `isunix`. Additionally,
there is a macro `@static` which makes it possible to use these functions to conditionally hide
invalid code, as demonstrated in the following examples.
Note that `islinux` and `isapple` are mutually exclusive subsets of `isunix`.

The `Sys` module also provides functionality for determining the version of glibc, the GNU
C library, on Linux. This is useful for code that relies on a particular version of glibc.
Further, the function `isglibc` reports whether glibc is linked to Julia, which can be
helpful for situations such as determining whether the current system is Alpine Linux, which
uses musl rather than glibc.

Additionally, there is a macro `@static` which makes it possible to use these functions to
conditionally hide invalid code, as demonstrated in the following examples.

Simple blocks:

Expand Down
6 changes: 6 additions & 0 deletions test/osutils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
else
@test Sys.windows_version() >= v"1.0.0-"
end
if !Sys.islinux()
@test Sys.glibc_version() == v"0.0.0"
@test !Sys.isglibc()
else
@test Sys.glibc_version() >= v"0.0.0"
end
end

@testset "@static" begin
Expand Down

0 comments on commit 30b21e7

Please sign in to comment.