Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to using Conda binaries #218

Closed
wants to merge 16 commits into from
6 changes: 1 addition & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
fail-fast: false
matrix:
version: ['1.6', '1'] # Test against LTS and current minor release
os: [windows-latest]
os: [ubuntu-latest, macOS-latest, windows-latest]
arch: [x64]
steps:
- uses: actions/checkout@v2
Expand All @@ -31,10 +31,6 @@ jobs:
${{ runner.os }}-test-
${{ runner.os }}-
- uses: julia-actions/julia-buildpkg@v1
env:
SECRET_XPRS_WIN: ${{ secrets.XPRS_WIN_900 }}
SECRET_XPRL_WIN: ${{ secrets.XPRL_WIN_900 }}
SECRET_XPRA_WIN: ${{ secrets.XPAUTH_XPR }}
- uses: julia-actions/julia-runtest@v1
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v1
Expand Down
42 changes: 42 additions & 0 deletions Artifacts.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# FICO's Conda builds are available at:
# https://anaconda.org/fico-xpress/xpress/files
#
# git-tree-sha1 and sha256 can be updated as follows:
# ```julia
# arch = "win-64"
# filename = "xpress-9.3.0-py310hadc54f4_0.tar.bz2"
# run(`wget https://anaconda.org/fico-xpress/xpress/9.3.0/download/$arch/$filename`)
# using Tar, Inflate, SHA
# println("sha256: ", bytes2hex(open(sha256, filename)))
# println("git-tree-sha1: ", Tar.tree_hash(`gzcat $filename`))
# ```

[[xpresspy]]
git-tree-sha1 = "401f814491e641f375c84ea3bb3051a38bc2fd55"
os = "linux"
arch = "x86_64"
lazy = true

[[xpresspy.download]]
url = "https://anaconda.org/fico-xpress/xpress/9.3.0/download/linux-64/xpress-9.3.0-py310ha14b774_0.tar.bz2"
sha256 = "48fed11b039d260f0ed90bfa1e41f23561f76c71796dc926a000d17151b9f801"

[[xpresspy]]
git-tree-sha1 = "75e700f837add542a01f8b00fa20efb25a16c4f7"
os = "macos"
arch = "x86_64"
lazy = true

[[xpresspy.download]]
url = "https://anaconda.org/fico-xpress/xpress/9.3.0/download/osx-64/xpress-9.3.0-py310h9b76c6a_0.tar.bz2"
sha256 = "e8734d813d3872fe6a6c907ea4767e4b93af55f495e33b8726eb338392a16dc3"

[[xpresspy]]
git-tree-sha1 = "554491bde6b59b4c1a1994ce39ba46cb9342510b"
os = "windows"
arch = "x86_64"
lazy = true

[[xpresspy.download]]
url = "https://anaconda.org/fico-xpress/xpress/9.3.0/download/win-64/xpress-9.3.0-py310hadc54f4_0.tar.bz2"
sha256 = "d44f7db6de16461c428c628217e56cdc51a40a6d662d7db66b7d8a4a414df68f"
9 changes: 8 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,25 @@ url = "https://github.com/jump-dev/Xpress.jl"
version = "0.16.2"

[deps]
LazyArtifacts = "4af54fe1-eca0-43a8-85a7-787d91b784e3"
Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"

[compat]
LazyArtifacts = "<0.0.1, 1.6"
Libdl = "<0.0.1, 1.6"
LinearAlgebra = "<0.0.1, 1.6"
MathOptInterface = "1"
Random = "<0.0.1, 1.6"
SparseArrays = "<0.0.1, 1.6"
Test = "<0.0.1, 1.6"
julia = "1.6"

[extras]
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test", "Random"]
test = ["Random", "Test"]
25 changes: 1 addition & 24 deletions deps/build.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function local_installation()
end
end

if !found
if !found && !(Sys.isapple() || Sys.islinux() || Sys.iswindows())
error("""
Unable to locate Xpress installation.
Please check your enviroment variable XPRESSDIR.
Expand All @@ -68,33 +68,10 @@ function local_installation()
end
end

function ci_installation()
files = if Sys.iswindows()
[
(ENV["SECRET_XPRS_WIN"], "xprs.dll")
(ENV["SECRET_XPRL_WIN"], "xprl.dll")
(ENV["SECRET_XPRA_WIN"], "xpauth.xpr")
]
end
for (url, file) in files
local_filename = joinpath(@__DIR__, file)
my_download(url, local_filename)
end
path = joinpath(@__DIR__, files[1][2])
d = Libdl.dlopen_e(path)
if d != C_NULL
write_depsfile(@__DIR__)
else
error("Could not open xprs.dll")
end
end

if haskey(ENV, "XPRESS_JL_SKIP_LIB_CHECK")
# Skip!
elseif get(ENV, "JULIA_REGISTRYCI_AUTOMERGE", "false") == "true"
write_depsfile("julia_registryci_automerge")
elseif get(ENV, "SECRET_XPRS_WIN", "") != ""
ci_installation()
else
local_installation()
end
140 changes: 86 additions & 54 deletions src/Xpress.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,71 +3,103 @@
# Use of this source code is governed by an MIT-style license that can be found
# in the LICENSE.md file or at https://opensource.org/licenses/MIT.

__precompile__()

module Xpress

using Libdl

# Load in `deps.jl`, complaining if it does not exist
const depsjl_path = joinpath(@__DIR__, "..", "deps", "deps.jl")

if isfile(depsjl_path)
include(depsjl_path)
elseif !haskey(ENV, "XPRESS_JL_NO_DEPS_ERROR")
error("XPRESS cannot be loaded. Please run Pkg.build(\"Xpress\").")
else
const xpressdlpath = ""
end

const libxprs = joinpath(xpressdlpath, string(Sys.iswindows() ? "" : "lib", "xprs", ".", Libdl.dlext))
import LazyArtifacts
import Libdl

### imports
# Load in `deps.jl`, complaining if it does not exist
const depsjl_path = joinpath(@__DIR__, "..", "deps", "deps.jl")

import Base.show, Base.copy

# ### exports

### include source files
module Lib
import ..Xpress
const libxprs = Xpress.libxprs
include("ctypes.jl")
include("common.jl")
include("lib.jl")
end
@static if isfile(depsjl_path)
include(depsjl_path)
const libxprs = joinpath(
xpressdlpath,
(Sys.iswindows() ? "" : "lib") * "xprs.$(Libdl.dlext)",
)
elseif get(ENV, "CI", "") == "true" && Sys.isapple() # Use the artifact instead.
const xpressdlpath = joinpath(
LazyArtifacts.artifact"xpresspy",
"lib/python3.10/site-packages/xpress/lib",
)
const libxprs = joinpath(xpressdlpath, "libxprs.dylib")
elseif get(ENV, "CI", "") == "true" && Sys.islinux() # Use the artifact instead.
const xpressdlpath = joinpath(
LazyArtifacts.artifact"xpresspy",
"lib/python3.10/site-packages/xpress/lib",
)
# Annoyingly, Xpress has the version after extension
const libxprs = joinpath(xpressdlpath, "libxprs.so.42")
elseif get(ENV, "CI", "") == "true" && Sys.iswindows() # Use the artifact instead.
const xpressdlpath = joinpath(
LazyArtifacts.artifact"xpresspy",
joinpath("Lib", "site-packages", "xpress", "lib"),
)
# There is a permission issue with the Windows artifact.
chmod(dirname(xpressdlpath), 0o755; recursive = true)
const libxprs = joinpath(xpressdlpath, "xprs.dll")
elseif haskey(ENV, "XPRESS_JL_NO_DEPS_ERROR")
const xpressdlpath = ""
const libxprs = (Sys.iswindows() ? "" : "lib") * "xprs.$(Libdl.dlext)"
else
error("XPRESS cannot be loaded. Please run Pkg.build(\"Xpress\").")
end

include("utils.jl")
include("helper.jl")
include("attributes_controls.jl")
include("api.jl")
include("xprs_callbacks.jl")
include("license.jl")
import Base.show, Base.copy

const XPRS_ATTRIBUTES = Dict{String, Any}(
replace(string(name), "XPRS_"=>"") => getfield(Lib, name)
for name in names(Lib; all = true)
if startswith(string(name), "XPRS_") && all(isuppercase(c) || isdigit(c) for c in string(name) if c != '_')
)
module Lib
import ..Xpress
const libxprs = Xpress.libxprs
include("ctypes.jl")
include("common.jl")
include("lib.jl")
end

function initialize()
Libdl.dlopen(libxprs)
include("utils.jl")
include("helper.jl")
include("attributes_controls.jl")
include("api.jl")
include("xprs_callbacks.jl")
include("license.jl")

const XPRS_ATTRIBUTES = Dict{String, Any}(
replace(string(name), "XPRS_"=>"") => getfield(Lib, name)
for name in names(Lib; all = true)
if startswith(string(name), "XPRS_") && all(isuppercase(c) || isdigit(c) for c in string(name) if c != '_')
)

function initialize()
Libdl.dlopen(libxprs)
try
userlic()
init() # Call XPRSinit for initialization
# free is not strictly necessary since destroyprob is called
# inthe finalizer.
# the user can call free if needed.
# leaving it uncommented results in many print errors becaus
# it is called prior to finalizers.
# atexit(free) # Call free when process terminates
catch err
license =
joinpath(dirname(xpressdlpath), "license", "community-xpauth.xpr")
try
@assert isfile(license)
userlic(; xpauth_path = license)
catch
rethrow(err)
end
end
init() # Call XPRSinit for initialization
# free is not strictly necessary since destroyprob is called
# inthe finalizer.
# the user can call free if needed.
# leaving it uncommented results in many print errors becaus
# it is called prior to finalizers.
# atexit(free) # Call free when process terminates
return
end

include("MOI/MOI_wrapper.jl")
include("MOI/MOI_wrapper.jl")

function __init__()
if !haskey(ENV, "XPRESS_JL_NO_AUTO_INIT") && get(ENV, "JULIA_REGISTRYCI_AUTOMERGE", "false") != "true"
Xpress.initialize()
end
function __init__()
if !haskey(ENV, "XPRESS_JL_NO_AUTO_INIT") &&
get(ENV, "JULIA_REGISTRYCI_AUTOMERGE", "false") != "true"
Xpress.initialize()
end
return
end

end
4 changes: 2 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ println("Optimizer version: $(Xpress.get_version())")
"xprs_callbacks",
"Derivative",
]
@testset "$(file)" for file in readdir(folder)
include(joinpath(folder, file))
@testset "$(file)" for file in readdir(joinpath(@__DIR__, folder))
include(joinpath(@__DIR__, folder, file))
end
end

Expand Down
Loading