From 2b460637c4e8b249822891dae577b0fe1075c1f1 Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Thu, 17 May 2018 14:51:40 -0400 Subject: [PATCH] add build fallback that compiles from source (#178) * add build fallback that compiles from source * fix issue # * use src.tar.gz for all tarballs so that new versions overwrite the old ones --- .travis.yml | 4 ++++ deps/build.jl | 34 ++++++++++++++++++++++++++-------- deps/compile.jl | 28 ++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 deps/compile.jl diff --git a/.travis.yml b/.travis.yml index 2e02b46..7bc80b2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,5 +5,9 @@ os: julia: - 0.6 - nightly +env: + matrix: + - FORCE_COMPILE_ZMQ=yes + - FORCE_COMPILE_ZMQ=no notifications: email: false diff --git a/deps/build.jl b/deps/build.jl index 4fac78d..9332a4e 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -1,7 +1,11 @@ using BinaryProvider # requires BinaryProvider 0.3.0 or later +include("compile.jl") + +# env var to force compilation from source, for testing purposes +const forcecompile = get(ENV, "FORCE_COMPILE_ZMQ", "no") == "yes" # Parse some basic command-line arguments -const verbose = "--verbose" in ARGS +const verbose = "--verbose" in ARGS || forcecompile const prefix = Prefix(get([a for a in ARGS if a != "--verbose"], 1, joinpath(@__DIR__, "usr"))) products = [ LibraryProduct(prefix, String["libzmq"], :libzmq), @@ -26,19 +30,33 @@ download_info = Dict( Windows(:x86_64) => ("$bin_prefix/ZMQ.x86_64-w64-mingw32.tar.gz", "84f8937f65015620ec56cb1ee867217edcfb6b2aec7ea41a2b1d9c32fe616925"), ) +# source code tarball and hash for fallback compilation +source_url = "https://github.com/zeromq/libzmq/releases/download/v4.2.5/zeromq-4.2.5.tar.gz" +source_hash = "cc9090ba35713d59bb2f7d7965f877036c49c5558ea0c290b0dcc6f2a17e489f" + # Install unsatisfied or updated dependencies: unsatisfied = any(!satisfied(p; verbose=verbose) for p in products) -if haskey(download_info, platform_key()) +if haskey(download_info, platform_key()) && !forcecompile url, tarball_hash = download_info[platform_key()] - if unsatisfied || !isinstalled(url, tarball_hash; prefix=prefix) + if !isinstalled(url, tarball_hash; prefix=prefix) # Download and install binaries install(url, tarball_hash; prefix=prefix, force=true, verbose=verbose) + + # check again whether the dependency is satisfied, which + # may not be true if dlopen fails due to a libc++ incompatibility (#176) + unsatisfied = any(!satisfied(p; verbose=verbose) for p in products) + end +end + +if unsatisfied || forcecompile + # Fall back to building from source, giving the library a different name + # so that it is not overwritten by BinaryBuilder downloads or vice-versa. + libname = "libzmq_from_source" + products = [ LibraryProduct(prefix, [libname], :libzmq) ] + source_path = joinpath(prefix, "downloads", "src.tar.gz") + if !isfile(source_path) || !verify(source_path, source_hash; verbose=verbose) || !satisfied(products[1]; verbose=verbose) + compile(libname, source_url, source_hash, prefix=prefix, verbose=verbose) end -elseif unsatisfied - # If we don't have a BinaryProvider-compatible .tar.gz to download, complain. - # Alternatively, you could attempt to install from a separate provider, - # build from source or something even more ambitious here. - error("Your platform $(triplet(platform_key())) is not supported by this package!") end # Write out a deps.jl file that will contain mappings for our products diff --git a/deps/compile.jl b/deps/compile.jl new file mode 100644 index 0000000..f44aa40 --- /dev/null +++ b/deps/compile.jl @@ -0,0 +1,28 @@ +using BinaryProvider, Compat +using Compat.Libdl: dlext + +function compile(libname, tarball_url, hash; prefix=BinaryProvider.global_prefix, verbose=false) + # download to tarball_path + tarball_path = joinpath(prefix, "downloads", "src.tar.gz") + download_verify(tarball_url, hash, tarball_path; force=true, verbose=verbose) + + # unpack into source_path + tarball_dir = joinpath(prefix, "downloads", split(first(list_tarball_files(tarball_path)), '/')[1]) # e.g. "zeromq-4.2.5" + source_path = joinpath(prefix, "downloads", "src") + verbose && Compat.@info("Unpacking $tarball_path into $source_path") + rm(tarball_dir, force=true, recursive=true) + rm(source_path, force=true, recursive=true) + unpack(tarball_path, dirname(tarball_dir); verbose=verbose) + mv(tarball_dir, source_path) + + install_dir = joinpath(source_path, "julia_install") + verbose && Compat.@info("Compiling in $source_path...") + cd(source_path) do + run(`./configure --prefix=$install_dir --without-docs --disable-libunwind --disable-perf --disable-eventfd --without-gcov --disable-curve-keygen`) + run(`make`) + run(`make install`) + mkpath(libdir(prefix)) + cp("$install_dir/lib/libzmq.$dlext", joinpath(libdir(prefix), libname*"."*dlext), + remove_destination=true, follow_symlinks=true) + end +end