Skip to content

Commit

Permalink
use BinaryProvider to download binaries
Browse files Browse the repository at this point in the history
  • Loading branch information
KristofferC committed Jun 17, 2018
1 parent b98961c commit a3ac87a
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 117 deletions.
12 changes: 12 additions & 0 deletions .travis.yml
Expand Up @@ -2,9 +2,21 @@ language: julia
os:
- linux
- osx
addons:
apt_packages:
- gfortran
before_install:
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then
brew cask uninstall oclint;
brew install gcc;
fi
julia:
- 0.6
- nightly
env:
matrix:
- JULIA_SPECIALFUNCTIONS_BUILD_SOURCE=true
- JULIA_SPECIALFUNCTIONS_BUILD_SOURCE=false
notifications:
email: false
#script: # the default script is equivalent to the following
Expand Down
1 change: 1 addition & 0 deletions REQUIRE
@@ -1,3 +1,4 @@
julia 0.6
Compat 0.59.0
BinaryProvider 0.3
BinDeps
48 changes: 0 additions & 48 deletions deps/binaries.jl

This file was deleted.

77 changes: 45 additions & 32 deletions deps/build.jl
@@ -1,38 +1,51 @@
using Compat
using Compat.Sys: isapple, islinux, iswindows
using BinaryProvider # requires BinaryProvider 0.3.0 or later
if VERSION < v"0.7.0-DEV.1760"
# No need to build or download anything; openspecfun is part of Julia
else
const forcecompile = get(ENV, "JULIA_SPECIALFUNCTIONS_BUILD_SOURCE", "false") == "true"

if VERSION >= v"0.7.0-DEV.3382"
using Libdl
end
# Parse some basic command-line arguments
const verbose = "--verbose" in ARGS
const prefix = Prefix(get([a for a in ARGS if a != "--verbos"], 1, joinpath(@__DIR__, "usr")))
products = [
LibraryProduct(prefix, String["libopenspecfun"], :openspecfun),
]

did_setup = false
# Download binaries from hosted location
bin_prefix = "https://github.com/JuliaMath/OpenspecfunBuilder/releases/download/v0.5.3-1"

if VERSION < v"0.7.0-DEV.1760"
# No need to build or download anything; openspecfun is part of Julia
elseif get(ENV, "JULIA_SPECIALFUNCTIONS_BUILD_SOURCE", "false") == "true"
# Allow a fast-path for building from source
info("Building openspecfun from source by request")
include("scratch.jl")
elseif isapple() || iswindows()
# Windows and macOS can always use our binaries, and we have no binaries
# for other non-Linux systems (e.g. BSDs)
include("binaries.jl")
elseif !islinux()
include("scratch.jl")
else # linux
# Determine the glibc version. If the check fails, we know we're on a non-glibc
# system, which means we can't use the binaries and need to build from source.
# The glibc version used by the binaries is 2.6, so we need at least that.
libc_ptr = ccall(:jl_dlopen, Ptr{Cvoid}, (Ptr{Cvoid}, UInt32), C_NULL, 0)
glibc_ptr = Libdl.dlsym_e(libc_ptr, :gnu_get_libc_version)
if glibc_ptr == C_NULL
# Listing of files generated by BinaryBuilder:
download_info = Dict(
Linux(:aarch64, :glibc) => ("$bin_prefix/libopenspecfun.aarch64-linux-gnu.tar.gz", "513cd981b1465b92942955369a41c8b65ce6e39ea15d39dda40aa0ecce348581"),
Linux(:aarch64, :musl) => ("$bin_prefix/libopenspecfun.aarch64-linux-musl.tar.gz", "11928ed68eaa3a97d2f59be36d21cff5a8e83decfbbef7b6422775735684abf8"),
Linux(:armv7l, :glibc, :eabihf) => ("$bin_prefix/libopenspecfun.arm-linux-gnueabihf.tar.gz", "5bc5f2f57b4faaed1124b59dd565f67164390ea668d0a35cc58e5dbb7256b883"),
Linux(:armv7l, :musl, :eabihf) => ("$bin_prefix/libopenspecfun.arm-linux-musleabihf.tar.gz", "5d396b66de7200248ecb156e7926d2460b5e06800202a3e181d778665aa8c4cc"),
Linux(:i686, :glibc) => ("$bin_prefix/libopenspecfun.i686-linux-gnu.tar.gz", "e407cab2ceac07680031a710b371e72d0f8ddb95a165969f78a1726e1aa3754e"),
Linux(:i686, :musl) => ("$bin_prefix/libopenspecfun.i686-linux-musl.tar.gz", "87f7419160c299f74c8cd8ef01102adde151824cda569ce5abef3b651ea6fb8e"),
Windows(:i686) => ("$bin_prefix/libopenspecfun.i686-w64-mingw32.tar.gz", "308efa58c6af46eba2ef3a0a93c029dad8f203b84de2f1fee463ea61ac505935"),
Linux(:powerpc64le, :glibc) => ("$bin_prefix/libopenspecfun.powerpc64le-linux-gnu.tar.gz", "6360c407784151e469735018ad01959dba0ebfbb48537bc1ed3b078be1cd2b18"),
MacOS(:x86_64) => ("$bin_prefix/libopenspecfun.x86_64-apple-darwin14.tar.gz", "88712e1a5faa31c633172716f0b27a749c018dc90eb012aa7f457e88a91a8838"),
Linux(:x86_64, :glibc) => ("$bin_prefix/libopenspecfun.x86_64-linux-gnu.tar.gz", "e1e8c04b164de3cd39dde3ad0a20ee87b7ca393cf41345c5f0db270fd680bed0"),
Linux(:x86_64, :musl) => ("$bin_prefix/libopenspecfun.x86_64-linux-musl.tar.gz", "9b9d12e36226689ced304cdbdbf0041982a9c9a4ddd4a62fdd3b43b39f541a47"),
FreeBSD(:x86_64) => ("$bin_prefix/libopenspecfun.x86_64-unknown-freebsd11.1.tar.gz", "9e1c31bf28dee3ac42d9d1f045a4abfcbd98edee3dc645858f6a70b32896022b"),
Windows(:x86_64) => ("$bin_prefix/libopenspecfun.x86_64-w64-mingw32.tar.gz", "05ff98c239f34efe514922301f9d15d1081c8e26851ace91731db468b15f5b40"),
)

# Install unsatisfied or updated dependencies:
unsatisfied = any(!satisfied(p; verbose=verbose) for p in products)
if haskey(download_info, platform_key()) && !forcecompile
url, tarball_hash = download_info[platform_key()]
if !isinstalled(url, tarball_hash; prefix=prefix)
# Download and install binaries
install(url, tarball_hash; prefix=prefix, force=true, verbose=verbose)
unsatisfied = any(!satisfied(p; verbose=verbose) for p in products)
end
end

if unsatisfied || forcecompile
include("scratch.jl")
else
glibc_vers = unsafe_string(ccall(glibc_ptr, Ptr{UInt8}, ()))
if isempty(glibc_vers) || VersionNumber(glibc_vers) < v"2.6.0"
include("scratch.jl")
else
include("binaries.jl")
end
# Write out a deps.jl file that will contain mappings for our products
write_deps_file(joinpath(@__DIR__, "deps.jl"), products)
end
end
end
45 changes: 16 additions & 29 deletions deps/scratch.jl
Expand Up @@ -3,23 +3,24 @@
using BinDeps
using BinDeps: libdir, srcdir, includedir, depsdir, builddir
using Base.Math: libm
import BinaryProvider

if VERSION >= v"0.7.0-DEV.3382"
using Libdl
end

# Don't call setup again if we're being included from binaries.jl
if !did_setup
BinDeps.@setup
const OSF_VERS = v"0.5.3"
openspecfun = library_dependency("libopenspecfun")
end

BinDeps.@setup
const OSF_VERS = v"0.5.3"
openspecfun = library_dependency("libopenspecfun")

# If Julia is built with OpenLibm, we want to build OpenSpecFun with it as well.
# Unfortunately this requires a fair bit more work, as we need to link to the .so
# and to include the headers, which aren't readily available.
if libm == "libopenlibm"
const OLM_VERS = v"0.5.4"
const OLM_HASH = "9a8ae1d17825a4a6a4c013d36a7f4348b27c47eedb6549c521ecc9c79d021c13"
const OLM_URL = "https://github.com/JuliaLang/openlibm/archive/v$OLM_VERS.tar.gz"
use_openlibm = true

if !isdir(libdir(openspecfun))
Expand All @@ -32,27 +33,15 @@ if libm == "libopenlibm"
for lib in readdir(dirname(openlibm_so))
startswith(lib, "libopenlibm") || continue
cp(joinpath(dirname(openlibm_so), lib), joinpath(libdir(openspecfun), lib),
remove_destination=true, follow_symlinks=false)
force=true, follow_symlinks=false)
end

if !isdir(srcdir(openspecfun))
mkpath(srcdir(openspecfun))
end

# Grab and unpack the tarball so we can get the header files
openlibm_tarball = joinpath(srcdir(openspecfun), "openlibm-$OLM_VERS.tar.gz")
run(```
curl -fkL --connect-timeout 15 -y 15
https://github.com/JuliaLang/openlibm/archive/v$OLM_VERS.tar.gz
-o $openlibm_tarball
```)
openlibm_src = joinpath(srcdir(openspecfun), "openlibm")
if !isdir(openlibm_src)
mkpath(openlibm_src)
end
run(`tar -C $openlibm_src --strip-components 1 -xf $openlibm_tarball`)
# Grab and unpack the tarball so we can get the header filesa
BinaryProvider.download_verify_unpack(OLM_URL, OLM_HASH, srcdir(openspecfun); verbose = true)

# Copy over all of the OpenLibm headers
cp(joinpath(srcdir(openspecfun), "openlibm-$OLM_VERS"), joinpath(srcdir(openspecfun), "openlibm"); force=true)
openlibm_src = joinpath(srcdir(openspecfun), "openlibm")
openlibm_include = joinpath(includedir(openspecfun), "openlibm")
if !isdir(openlibm_include)
mkpath(openlibm_include)
Expand Down Expand Up @@ -90,6 +79,8 @@ elseif Sys.ARCH === :x86_64
fc *= " -m64"
end

extra_ld = Sys.is_apple() ? "" : "-Wl,-rpath,'\$\$ORIGIN' -Wl,-z,origin"

provides(Sources, URI("https://github.com/JuliaLang/openspecfun/archive/v$OSF_VERS.tar.gz"),
openspecfun, unpacked_dir="openspecfun-$OSF_VERS")

Expand All @@ -112,7 +103,7 @@ provides(BuildProcess,
USE_OPENLIBM=$(Int(use_openlibm))
CFLAGS="-O3 -std=c99"
FFLAGS="-O2 -fPIC"
LDFLAGS="-L$(libdir(openspecfun)) -Wl,-rpath,'\$\$ORIGIN' -Wl,-z,origin"
LDFLAGS="-L$(libdir(openspecfun)) $extra_ld"
DESTDIR=""
prefix=""
libdir="$(libdir(openspecfun))"
Expand All @@ -123,8 +114,4 @@ provides(BuildProcess,
end
end), openspecfun)

# If we're being included, the installation step happens once we return back
# to binaries.jl
if !did_setup
BinDeps.@install Dict(:libopenspecfun => :openspecfun)
end
BinDeps.@install Dict(:libopenspecfun => :openspecfun)
16 changes: 10 additions & 6 deletions src/SpecialFunctions.jl
Expand Up @@ -3,14 +3,18 @@ module SpecialFunctions

using Compat

logfile = joinpath(@__DIR__, "..", "deps", "build.log")
if isfile(logfile)
println( read(logfile, String) )
end

if VERSION >= v"0.7.0-DEV.1760"
depsfile = joinpath(dirname(@__FILE__), "..", "deps", "deps.jl")
if isfile(depsfile)
include(depsfile)
else
error("SpecialFunctions is not properly installed. Please run " *
"Pkg.build(\"SpecialFunctions\") and restart Julia.")
# Load openspecfun libraries from our deps.jl
const depsjl_path = joinpath(@__DIR__, "..", "deps", "deps.jl")
if !isfile(depsjl_path)
error("SpecialFunctions not installed properly, run Pkg.build(\"SpecialFunctions\"), restart Julia and try again")
end
include(depsjl_path)
else
using Base.Math: openspecfun
end
Expand Down
4 changes: 2 additions & 2 deletions src/bessel.jl
Expand Up @@ -192,7 +192,7 @@ end
function _besseli(nu::Float64, z::Complex{Float64}, kode::Int32)
ai1, ai2 = Ref{Float64}(), Ref{Float64}()
ae1, ae2 = Ref{Int32}(), Ref{Int32}()

ccall((:zbesi_,openspecfun), Cvoid,
(Ref{Float64}, Ref{Float64}, Ref{Float64}, Ref{Int32}, Ref{Int32},
Ref{Float64}, Ref{Float64}, Ref{Int32}, Ref{Int32}),
Expand All @@ -215,7 +215,7 @@ function _besselj(nu::Float64, z::Complex{Float64}, kode::Int32)
Ref{Float64}, Ref{Float64}, Ref{Int32}, Ref{Int32}),
real(z), imag(z), nu, kode, 1,
ai1, ai2, ae1, ae2)

if ae2[] == 0 || ae2[] == 3
return complex(ai1[], ai2[])
else
Expand Down

0 comments on commit a3ac87a

Please sign in to comment.