Skip to content

Commit 9f204e7

Browse files
authored
Merge pull request #57 from JuliaMath/aa/force-compile
Improve build logic to identify when to build from source
2 parents 380b617 + bd35213 commit 9f204e7

File tree

7 files changed

+129
-45
lines changed

7 files changed

+129
-45
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ Special mathematical functions in Julia, including Bessel, Hankel, Airy, error,
44
eta, zeta, digamma, inverse digamma, trigamma, and polygamma functions.
55
Most of these functions were formerly part of Base.
66

7+
Note: On Julia 0.7, this package downloads and/or builds
8+
[openspecfun](https://github.com/JuliaLang/openspecfun), which is no longer built as part
9+
of Julia.
10+
Binaries are available for macOS, Windows, and Linux (glibc >= 2.6).
11+
To force compilation of the library from source, set an environment variable called
12+
`JULIA_SPECIALFUNCTIONS_BUILD_SOURCE` equal to `true` before running `Pkg.build`.
13+
714
[![Travis](https://travis-ci.org/JuliaMath/SpecialFunctions.jl.svg?branch=master)](https://travis-ci.org/JuliaMath/SpecialFunctions.jl)
815
[![AppVeyor](https://ci.appveyor.com/api/projects/status/ccfgkm2cjcggu158/branch/master?svg=true)](https://ci.appveyor.com/project/ararslan/specialfunctions-jl/branch/master)
916
[![Coverage Status](https://coveralls.io/repos/github/JuliaMath/SpecialFunctions.jl/badge.svg?branch=master)](https://coveralls.io/github/JuliaMath/SpecialFunctions.jl?branch=master)

deps/binaries.jl

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using BinDeps, Compat
2+
using BinDeps: libdir
3+
4+
modified_defaults = false
5+
if !in(BinDeps.Binaries, BinDeps.defaults)
6+
unshift!(BinDeps.defaults, BinDeps.Binaries)
7+
modified_defaults = true
8+
end
9+
10+
BinDeps.@setup
11+
did_setup = true
12+
13+
const OSF_VERS = v"0.5.3"
14+
15+
openspecfun = library_dependency("libopenspecfun")
16+
17+
const URL = "https://github.com/ararslan/openspecfun-builder/releases/download/v$OSF_VERS" *
18+
"/libopenspecfun-$OSF_VERS"
19+
20+
const DOWNLOADS = Dict(
21+
"Linux-x86_64" => ("$URL-linux-x86_64.tar.gz",
22+
"d70a2a391915f64f44da21915bf93ce08d054127028088addca36e16ac53bcb1"),
23+
"Linux-i686" => ("$URL-linux-i686.tar.gz",
24+
"e5418b170b537af2f7f1f1d06eee9be01555404f5d22a47e18bc06a540321478"),
25+
"Darwin-x86_64" => ("$URL-osx-x86_64.tar.gz",
26+
"e57f5f84439757a2fd1d3821a6e19a3fa69b5b1e181cc40fec0d1652fbb9efdc"),
27+
"Windows-x86_64" => ("$URL-win-x86_64.zip",
28+
"7a5f7be4ed46d7f9d6d18a599157075512c50a372da2b2908079a3dcab9a0f25"),
29+
"Windows-i686" => ("$URL-win-i686.zip",
30+
"2f63a08d80e67964e2c368367f4caef7039080828e217d288669416cd46f4584"),
31+
)
32+
33+
const SYSTEM = string(BinDeps.OSNAME, '-', Sys.ARCH)
34+
35+
if haskey(DOWNLOADS, SYSTEM)
36+
url, sha = DOWNLOADS[SYSTEM]
37+
provides(Binaries, URI(url), openspecfun, SHA=sha, os=BinDeps.OSNAME,
38+
unpacked_dir=joinpath("usr", "lib"), installed_libpath=libdir(openspecfun))
39+
else
40+
info("No precompiled binaries found for your system. Building from scratch...")
41+
include("scratch.jl")
42+
end
43+
44+
BinDeps.@install Dict(:libopenspecfun => :openspecfun)
45+
46+
if modified_defaults
47+
shift!(BinDeps.defaults)
48+
end

deps/build.jl

Lines changed: 30 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,34 @@
1-
using BinDeps, Compat
2-
using BinDeps: libdir, srcdir, includedir, depsdir, builddir
1+
using Compat
2+
using Compat.Sys: isapple, islinux, iswindows
33

4-
modified_defaults = false
5-
if !in(BinDeps.Binaries, BinDeps.defaults)
6-
unshift!(BinDeps.defaults, BinDeps.Binaries)
7-
modified_defaults = true
8-
end
9-
10-
BinDeps.@setup
11-
12-
const OSF_VERS = v"0.5.3"
13-
14-
openspecfun = library_dependency("libopenspecfun")
15-
16-
const URL = "https://github.com/ararslan/openspecfun-builder/releases/download/v$OSF_VERS" *
17-
"/libopenspecfun-$OSF_VERS"
18-
19-
const DOWNLOADS = Dict(
20-
"Linux-x86_64" => ("$URL-linux-x86_64.tar.gz",
21-
"d70a2a391915f64f44da21915bf93ce08d054127028088addca36e16ac53bcb1"),
22-
"Linux-i686" => ("$URL-linux-i686.tar.gz",
23-
"e5418b170b537af2f7f1f1d06eee9be01555404f5d22a47e18bc06a540321478"),
24-
"Darwin-x86_64" => ("$URL-osx-x86_64.tar.gz",
25-
"e57f5f84439757a2fd1d3821a6e19a3fa69b5b1e181cc40fec0d1652fbb9efdc"),
26-
"Windows-x86_64" => ("$URL-win-x86_64.zip",
27-
"7a5f7be4ed46d7f9d6d18a599157075512c50a372da2b2908079a3dcab9a0f25"),
28-
"Windows-i686" => ("$URL-win-i686.zip",
29-
"2f63a08d80e67964e2c368367f4caef7039080828e217d288669416cd46f4584"),
30-
)
4+
did_setup = false
315

32-
const SYSTEM = string(BinDeps.OSNAME, '-', Sys.ARCH)
33-
34-
if haskey(DOWNLOADS, SYSTEM)
35-
url, sha = DOWNLOADS[SYSTEM]
36-
provides(Binaries, URI(url), openspecfun, SHA=sha, os=BinDeps.OSNAME,
37-
unpacked_dir=joinpath("usr", "lib"), installed_libpath=libdir(openspecfun))
38-
else
39-
info("No precompiled binaries found for your system. Building from scratch...")
6+
if VERSION < v"0.7.0-DEV.1760"
7+
# No need to build or download anything; openspecfun is part of Julia
8+
elseif get(ENV, "JULIA_SPECIALFUNCTIONS_BUILD_SOURCE", "false") == "true"
9+
# Allow a fast-path for building from source
10+
info("Building openspecfun from source by request")
4011
include("scratch.jl")
41-
end
42-
43-
BinDeps.@install Dict(:libopenspecfun => :openspecfun)
44-
45-
if modified_defaults
46-
shift!(BinDeps.defaults)
12+
elseif isapple() || iswindows()
13+
# Windows and macOS can always use our binaries, and we have no binaries
14+
# for other non-Linux systems (e.g. BSDs)
15+
include("binaries.jl")
16+
elseif !islinux()
17+
include("scratch.jl")
18+
else # linux
19+
# Determine the glibc version. If the check fails, we know we're on a non-glibc
20+
# system, which means we can't use the binaries and need to build from source.
21+
# The glibc version used by the binaries is 2.6, so we need at least that.
22+
libc_ptr = ccall(:jl_dlopen, Ptr{Void}, (Ptr{Void}, UInt32), C_NULL, 0)
23+
glibc_ptr = Libdl.dlsym_e(libc_ptr, :gnu_get_libc_version)
24+
if glibc_ptr == C_NULL
25+
include("scratch.jl")
26+
else
27+
glibc_vers = unsafe_string(ccall(glibc_ptr, Ptr{UInt8}, ()))
28+
if isempty(glibc_vers) || VersionNumber(glibc_vers) < v"2.6.0"
29+
include("scratch.jl")
30+
else
31+
include("binaries.jl")
32+
end
33+
end
4734
end

deps/scratch.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
# Building OpenSpecFun from scratch
22

3+
using BinDeps
4+
using BinDeps: libdir, srcdir, includedir, depsdir, builddir
35
using Base.Math: libm
46

7+
# Don't call setup again if we're being included from binaries.jl
8+
if !did_setup
9+
BinDeps.@setup
10+
const OSF_VERS = v"0.5.3"
11+
openspecfun = library_dependency("libopenspecfun")
12+
end
13+
514
# If Julia is built with OpenLibm, we want to build OpenSpecFun with it as well.
615
# Unfortunately this requires a fair bit more work, as we need to link to the .so
716
# and to include the headers, which aren't readily available.
@@ -110,3 +119,9 @@ provides(BuildProcess,
110119
end)
111120
end
112121
end), openspecfun)
122+
123+
# If we're being included, the installation step happens once we return back
124+
# to binaries.jl
125+
if !did_setup
126+
BinDeps.@install Dict(:libopenspecfun => :openspecfun)
127+
end

docs/src/index.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,22 @@ to avoid name conflicts.
5959
In this case, the symbols will need to be explicitly imported or called
6060
with the prefix `SpecialFunctions`.
6161
This is not necessary for Julia versions 0.6 and later.
62+
63+
On Julia 0.7, [openspecfun](https://github.com/JuliaLang/openspecfun) is not build as
64+
part of Julia.
65+
Thus for Julia versions 0.7 and later, installing this package downloads openspecfun.
66+
Binaries of openspecfun are available for macOS, Windows, and Linux (glibc >= 2.6).
67+
Other systems will need to build the library from source.
68+
You can force a build from source by setting an environment variable called
69+
`JULIA_SPECIALFUNCTIONS_BUILD_SOURCE` equal to `true` before running `Pkg.build`.
70+
This ensures that the library is built locally from source, even if binaries are
71+
available.
72+
Doing this requires a C compiler (Clang on macOS and FreeBSD, GCC elsewhere) and
73+
gfortran.
74+
If you always want to build this library from source, consider adding
75+
76+
```julia
77+
ENV["JULIA_SPECIALFUNCTIONS_BUILD_SOURCE"] = "true"
78+
```
79+
80+
to your .juliarc.jl file.

src/SpecialFunctions.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@ module SpecialFunctions
44

55
using Compat
66

7-
let depsfile = joinpath(dirname(@__FILE__), "..", "deps", "deps.jl")
7+
if VERSION >= v"0.7.0-DEV.1760"
8+
depsfile = joinpath(dirname(@__FILE__), "..", "deps", "deps.jl")
89
if isfile(depsfile)
910
include(depsfile)
1011
else
1112
error("SpecialFunctions is not properly installed. Please run " *
1213
"Pkg.build(\"SpecialFunctions\") and restart Julia.")
1314
end
15+
else
16+
using Base.Math: openspecfun
1417
end
1518

1619
if isdefined(Base, :airyai) && VERSION < v"0.7.0-DEV.986" #22763

test/runtests.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
# This file contains code that was formerly a part of Julia. License is MIT: http://julialang.org/license
22

33
using SpecialFunctions
4-
using Base.Test
4+
5+
if isdefined(Base, :Test) && !Base.isdeprecated(Base, :Test)
6+
using Base.Test
7+
else
8+
using Test
9+
end
510

611
const SF = SpecialFunctions
712

0 commit comments

Comments
 (0)