diff --git a/.travis.yml b/.travis.yml index 2288ff3e..34f84e21 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,22 @@ language: julia os: - linux - - osx +# - osx julia: - 0.6 - nightly +addons: + apt: + packages: + - tree notifications: email: false -#script: # the default script is equivalent to the following -# - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi -# - julia -e 'Pkg.clone(pwd()); Pkg.build("SpecialFunctions"); Pkg.test("SpecialFunctions"; coverage=true)'; +script: # the default script is equivalent to the following + - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi + - julia -e 'Pkg.clone(pwd()); Pkg.build("SpecialFunctions");' + - julia -e 'Pkg.checkout("BinDeps"); using BinDeps; BinDeps.debug("SpecialFunctions")' + - tree $TRAVIS_BUILD_DIR/deps + - julia -e 'Pkg.test("SpecialFunctions"; coverage=true)' after_success: - julia -e 'cd(Pkg.dir("SpecialFunctions")); Pkg.add("Documenter"); include(joinpath("docs", "make.jl"))'; - julia -e 'cd(Pkg.dir("SpecialFunctions")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'; diff --git a/REQUIRE b/REQUIRE index f1081da9..b2cffb82 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,2 +1,3 @@ julia 0.6 Compat 0.30 +BinDeps diff --git a/deps/build.jl b/deps/build.jl new file mode 100644 index 00000000..f1a9891d --- /dev/null +++ b/deps/build.jl @@ -0,0 +1,47 @@ +using BinDeps, Compat +using BinDeps: libdir, srcdir, includedir, depsdir, builddir + +modified_defaults = false +if !in(BinDeps.Binaries, BinDeps.defaults) + unshift!(BinDeps.defaults, BinDeps.Binaries) + modified_defaults = true +end + +BinDeps.@setup + +const OSF_VERS = v"0.5.3" + +openspecfun = library_dependency("libopenspecfun") + +const URL = "https://github.com/ararslan/openspecfun-builder/releases/download/v$OSF_VERS" * + "/libopenspecfun-$OSF_VERS" + +const DOWNLOADS = Dict( + "x86_64-pc-linux-gnu" => ("$URL-linux-x86_64.tar.gz", + "d70a2a391915f64f44da21915bf93ce08d054127028088addca36e16ac53bcb1"), + "i686-pc-linux-gnu" => ("$URL-linux-i686.tar.gz", + "e5418b170b537af2f7f1f1d06eee9be01555404f5d22a47e18bc06a540321478"), + "x86_64-apple-darwin" => ("$URL-osx-x86_64.tar.gz", + "e57f5f84439757a2fd1d3821a6e19a3fa69b5b1e181cc40fec0d1652fbb9efdc"), + "x86_64-w64-mingw32" => ("$URL-win-x86_64.zip", + "7a5f7be4ed46d7f9d6d18a599157075512c50a372da2b2908079a3dcab9a0f25"), + "i686-w64-mingw32" => ("$URL-win-i686.zip", + "2f63a08d80e67964e2c368367f4caef7039080828e217d288669416cd46f4584"), +) + +const MACHINE = Compat.Sys.isapple() ? "x86_64-apple-darwin" : Sys.MACHINE + +if haskey(DOWNLOADS, MACHINE) + url, sha = DOWNLOADS[MACHINE] + provides(Binaries, URI(url), openspecfun, SHA=sha, os=BinDeps.OSNAME, + unpacked_dir=joinpath("usr", "lib"), installed_libpath=libdir(openspecfun)) +else + info("No precompiled binaries found for your system. Building from scratch...") + include("scratch.jl") +end + +BinDeps.@install Dict(:libopenspecfun => :openspecfun) + +if modified_defaults + shift!(BinDeps.defaults) +end diff --git a/deps/scratch.jl b/deps/scratch.jl new file mode 100644 index 00000000..e3211475 --- /dev/null +++ b/deps/scratch.jl @@ -0,0 +1,112 @@ +# Building OpenSpecFun from scratch + +using Base.Math: libm + +# 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" + use_openlibm = true + + if !isdir(libdir(openspecfun)) + mkpath(libdir(openspecfun)) + end + + openlibm_so = Libdl.dlpath(libm) + + # Copy over the OpenLibm .so + cp(openlibm_so, joinpath(libdir(openspecfun), basename(openlibm_so)), + remove_destination=true) + + 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`) + + # Copy over all of the OpenLibm headers + openlibm_include = joinpath(includedir(openspecfun), "openlibm") + if !isdir(openlibm_include) + mkpath(openlibm_include) + end + for f in readdir(joinpath(openlibm_src, "include")) + cp(joinpath(openlibm_src, "include", f), joinpath(openlibm_include, f), + remove_destination=true) + end + for f in readdir(joinpath(openlibm_src, "src")) + if endswith(f, ".h") + cp(joinpath(openlibm_src, "src", f), joinpath(openlibm_include, f), + remove_destination=true) + end + end +else + use_openlibm = false +end + +fc = "gfortran" + +# macOS has precompiled binaries, so it's just FreeBSD that should default to Clang +if Sys.KERNEL === :FreeBSD + cc = "clang" + use_clang = true +else + cc = "gcc" + use_clang = false +end + +if Sys.ARCH in [:i386, :i387, :i486, :i586, :i686] + cc *= " -m32" + fc *= " -m32" +elseif Sys.ARCH === :x86_64 + cc *= " -m64" + fc *= " -m64" +end + +flags = [ + # OpenSpecFun build flags + "ARCH=\"$(Sys.ARCH)\"", + "CC=\"$cc\"", + "FC=\"$fc\"", + "USECLANG=$(Int(use_clang))", + "USEGCC=$(Int(!use_clang))", + "USE_OPENLIBM=$(Int(use_openlibm))", + "CFLAGS=\"-O3 -std=c99\"", + "FFLAGS=\"-O2 -fPIC\"", + "LDFLAGS=\"-L$(libdir(openspecfun)) -Wl,-rpath,'\$\$ORIGIN' -Wl,-z,origin\"", + # Make flags + "DESTDIR=\"\"", + "prefix=$(depsdir(openspecfun))", + "libdir=$(libdir(openspecfun))", + "shlibdir=$(libdir(openspecfun))", + "includedir=$(includedir(openspecfun))", + "O=" +] + +provides(Sources, URI("https://github.com/JuliaLang/openspecfun/archive/v$OSF_VERS.tar.gz"), + openspecfun) + +provides(BuildProcess, + (@build_steps begin + GetSources(openspecfun) + CreateDirectory(builddir(openspecfun)) + @build_steps begin + ChangeDirectory(builddir(openspecfun)) + FileRule(joinpath(libdir(openspecfun), "libopenspecfun." * Libdl.dlext), + @build_steps begin + CreateDirectory(libdir(openspecfun)) + `$MAKE_CMD install $flags` + end) + end + end), openspecfun) diff --git a/src/SpecialFunctions.jl b/src/SpecialFunctions.jl index ef5eca24..3a740d9c 100644 --- a/src/SpecialFunctions.jl +++ b/src/SpecialFunctions.jl @@ -4,6 +4,15 @@ module SpecialFunctions using Compat +let 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.") + end +end + if isdefined(Base, :airyai) && VERSION < v"0.7.0-DEV.986" #22763 import Base: airyai, airyaix, airyaiprime, airyaiprimex, airybi, airybix, airybiprime, airybiprimex, @@ -60,12 +69,6 @@ end export sinint, cosint -if isdefined(Base.Math, :openspecfun) - const openspecfun = Base.Math.openspecfun -else - const openspecfun = "libopenspecfun" -end - include("bessel.jl") include("erf.jl") include("sincosint.jl")