From 30b21e76792d92d83c5f076079be6ad577e50e5a Mon Sep 17 00:00:00 2001 From: Alex Arslan Date: Wed, 23 May 2018 08:01:53 -0700 Subject: [PATCH] Add Sys.glibc_version and Sys.isglibc 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. --- NEWS.md | 5 +++ base/sysinfo.jl | 39 ++++++++++++++++++- doc/src/base/base.md | 2 + .../handling-operating-system-variation.md | 13 +++++-- test/osutils.jl | 6 +++ 5 files changed, 61 insertions(+), 4 deletions(-) diff --git a/NEWS.md b/NEWS.md index bb198b131ee64..233c184fa5f4c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -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 ----------------------------- @@ -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 diff --git a/base/sysinfo.jl b/base/sysinfo.jl index ab19d99998bc7..d695ad56c499e 100644 --- a/base/sysinfo.jl +++ b/base/sysinfo.jl @@ -26,7 +26,9 @@ export BINDIR, isunix, iswindows, isexecutable, - which + which, + glibc_version, + isglibc import ..Base: show @@ -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) diff --git a/doc/src/base/base.md b/doc/src/base/base.md index cea99f480b94d..0fe071979de01 100644 --- a/doc/src/base/base.md +++ b/doc/src/base/base.md @@ -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 ``` diff --git a/doc/src/manual/handling-operating-system-variation.md b/doc/src/manual/handling-operating-system-variation.md index 46ee1ae3a6f70..3ecfd194eb45a 100644 --- a/doc/src/manual/handling-operating-system-variation.md +++ b/doc/src/manual/handling-operating-system-variation.md @@ -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: diff --git a/test/osutils.jl b/test/osutils.jl index 2b9da7a3e67bc..db4435f710691 100644 --- a/test/osutils.jl +++ b/test/osutils.jl @@ -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