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

Use Scratch.jl for GAP root #825

Merged
merged 1 commit into from
Oct 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Scratch = "6c6a2e73-6563-6170-7368-637461726353"

[compat]
GAP_jll = "~400.1192.001"
GAP_lib_jll = "~400.1192.002"
GAP_pkg_juliainterface_jll = "=0.800.000"
MacroTools = "0.5"
Scratch = "1.1"
julia = "1.6"

[extras]
Expand Down
27 changes: 14 additions & 13 deletions src/GAP.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,18 @@ GAP_jll.is_available() ||

include("setup.jl")

# always force regeneration of GAPROOT when precompiling
const GAPROOT = abspath(@__DIR__, "..", "gaproot", "v$(VERSION.major).$(VERSION.minor)")
Setup.regenerate_gaproot(GAPROOT)

import Base: length, finalize
import Libdl
import Markdown
import Random

include("types.jl")
# setup the initial sysinfo dictionary; we'll update this later in __init__
# this also ensures that Setup.regenerate_gaproot gets precompiled, reducing
# the startup time a little bit
const sysinfo = Setup.regenerate_gaproot()


const sysinfo = Setup.read_sysinfo_gap(GAPROOT)
const GAP_VERSION = VersionNumber(sysinfo["GAP_VERSION"])
include("types.jl")

const last_error = Ref{String}("")

Expand Down Expand Up @@ -72,8 +71,8 @@ end
const error_handlerwrap = error_handler

# path to JuliaInterface.so
const real_JuliaInterface_path = Setup.locate_JuliaInterface_so(GAPROOT, sysinfo)
JuliaInterface_path() = real_JuliaInterface_path
const real_JuliaInterface_path = Ref{String}()
JuliaInterface_path() = real_JuliaInterface_path[]

function initialize(argv::Vector{String})
handle_signals = isdefined(Main, :__GAP_ARGS__) # a bit of a hack...
Expand Down Expand Up @@ -212,10 +211,12 @@ function __init__()
windows_error()
end

# regenerate GAPROOT if it was removed
if !isdir(GAPROOT) || isempty(readdir(GAPROOT))
Setup.regenerate_gaproot(GAPROOT)
end
# always regenerate our custom GAP root dir, to accommodate for changes
# in the system configuration (artifact paths, available compilers, ...)
global sysinfo
merge!(sysinfo, Setup.regenerate_gaproot())

real_JuliaInterface_path[] = Setup.locate_JuliaInterface_so(sysinfo)

gaproots = sysinfo["GAPROOTS"]
cmdline_options = ["", "-l", gaproots]
Expand Down
16 changes: 9 additions & 7 deletions src/packages.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ module Packages
using Downloads
import ...GAP: Globals, GapObj, sysinfo

const DEFAULT_PKGDIR = sysinfo["DEFAULT_PKGDIR"]
const DEFAULT_PKGDIR = Ref{String}()

function init_packagemanager()
res = load("PackageManager")
@assert res

global DEFAULT_PKGDIR[] = sysinfo["DEFAULT_PKGDIR"]

# overwrite PKGMAN_DownloadURL
Globals.MakeReadWriteGlobal(GapObj("PKGMAN_DownloadURL"))
Globals.PKGMAN_DownloadURL = function(url)
Expand Down Expand Up @@ -58,7 +60,7 @@ end

"""
install(spec::String; interactive::Bool = true, quiet::Bool = false,
pkgdir::AbstractString = GAP.Packages.DEFAULT_PKGDIR)
pkgdir::AbstractString = GAP.Packages.DEFAULT_PKGDIR[])

Download and install the newest released version of the GAP package
given by `spec` into the `pkgdir` directory.
Expand All @@ -76,7 +78,7 @@ prevent `PackageManager` from prompting the user for input interactively.
For details, please refer to its documentation.
"""
function install(spec::String; interactive::Bool = true, quiet::Bool = false,
pkgdir::AbstractString = DEFAULT_PKGDIR)
pkgdir::AbstractString = DEFAULT_PKGDIR[])
# point PackageManager to the given pkg dir
Globals.PKGMAN_CustomPackageDir = GapObj(pkgdir)
mkpath(pkgdir)
Expand All @@ -101,7 +103,7 @@ end

"""
update(spec::String; interactive::Bool = true, quiet::Bool = false,
pkgdir::AbstractString = GAP.Packages.DEFAULT_PKGDIR)
pkgdir::AbstractString = GAP.Packages.DEFAULT_PKGDIR[])

Update the GAP package given by `spec` that is installed in the
`pkgdir` directory, to the latest version.
Expand All @@ -119,7 +121,7 @@ prevent `PackageManager` from prompting the user for input interactively.
For details, please refer to its documentation.
"""
function update(spec::String; interactive::Bool = true, quiet::Bool = false,
pkgdir::AbstractString = DEFAULT_PKGDIR)
pkgdir::AbstractString = DEFAULT_PKGDIR[])
# point PackageManager to the given pkg dir
Globals.PKGMAN_CustomPackageDir = GapObj(pkgdir)
mkpath(pkgdir)
Expand All @@ -140,7 +142,7 @@ end

"""
remove(spec::String; interactive::Bool = true, quiet::Bool = false,
pkgdir::AbstractString = GAP.Packages.DEFAULT_PKGDIR)
pkgdir::AbstractString = GAP.Packages.DEFAULT_PKGDIR[])

Remove the GAP package with name `spec` that is installed in the
`pkgdir` directory.
Expand All @@ -154,7 +156,7 @@ prevent `PackageManager` from prompting the user for input interactively.
For details, please refer to its documentation.
"""
function remove(spec::String; interactive::Bool = true, quiet::Bool = false,
pkgdir::AbstractString = DEFAULT_PKGDIR)
pkgdir::AbstractString = DEFAULT_PKGDIR[])
# point PackageManager to the given pkg dir
Globals.PKGMAN_CustomPackageDir = GapObj(pkgdir)
mkpath(pkgdir)
Expand Down
38 changes: 17 additions & 21 deletions src/setup.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ using GAP_jll
using GAP_lib_jll
using GAP_pkg_juliainterface_jll
using GMP_jll
using Scratch

# to separate the scratchspaces of different GAP.jl copies and Julia versions
# put the Julia version and the hash of the path to this file into the key
const scratch_key = "gap_$(string(hash(@__FILE__)))_$(VERSION.major).$(VERSION.minor)"

gaproot() = @get_scratch!(scratch_key)

#############################################################################
#
Expand Down Expand Up @@ -85,9 +92,11 @@ function gmp_artifact_dir()
return GMP_jll.find_artifact_dir()
end

function regenerate_gaproot(gaproot_mutable)
function regenerate_gaproot()
gaproot_mutable = gaproot()

gaproot_gapjl = abspath(@__DIR__, "..")
@info "Set up gaproot at $(gaproot_mutable)"
@debug "Set up gaproot at $(gaproot_mutable)"

gap_prefix = GAP_jll.find_artifact_dir()
gmp_prefix = gmp_artifact_dir()
Expand Down Expand Up @@ -238,22 +247,10 @@ function regenerate_gaproot(gaproot_mutable)

end # cd(gaproot_mutable)

# any change to the JuliaInterface source code or build system should
# trigger a rebuild
jipath = joinpath(gaproot_gapjl, "pkg", "JuliaInterface")
include_dependency(joinpath(jipath, "configure"))
include_dependency(joinpath(jipath, "Makefile.in"))
include_dependency(joinpath(jipath, "Makefile.gappkg"))
for (root, dirs, files) in walkdir(joinpath(jipath, "src"))
for file in files
include_dependency(joinpath(root, file))
end
end

return gaproot_mutable
return sysinfo
end

function build_JuliaInterface(gaproot::String, sysinfo::Dict{String, String}, srchash)
function build_JuliaInterface(sysinfo::Dict{String, String})
@info "Compiling JuliaInterface ..."

# run code in julia-config.jl to determine compiler and linker flags for Julia;
Expand All @@ -270,15 +267,15 @@ function build_JuliaInterface(gaproot::String, sysinfo::Dict{String, String}, sr
cd(jipath) do
withenv("CFLAGS" => JULIA_CPPFLAGS,
"LDFLAGS" => JULIA_LDFLAGS * " " * JULIA_LIBS) do
run(pipeline(`./configure $gaproot`, stdout="build.log"))
run(pipeline(`./configure $(gaproot())`, stdout="build.log"))
run(pipeline(`make V=1 -j$(Sys.CPU_THREADS)`, stdout="build.log", append=true))
end
end

return normpath(joinpath(jipath, "bin", sysinfo["GAParch"]))
end

function locate_JuliaInterface_so(gaproot::String, sysinfo::Dict{String, String})
function locate_JuliaInterface_so(sysinfo::Dict{String, String})
# compare the C sources used to build GAP_pkg_juliainterface_jll with bundled copies
# by comparing tree hashes
jll = GAP_pkg_juliainterface_jll.find_artifact_dir()
Expand All @@ -290,9 +287,8 @@ function locate_JuliaInterface_so(gaproot::String, sysinfo::Dict{String, String}
@debug "Use JuliaInterface.so from GAP_pkg_juliainterface_jll"
path = joinpath(jll, "lib", "gap")
else
# tree hashes differ: we must compile the bundled sources (resp. access a
# previously compiled version)
path = build_JuliaInterface(gaproot, sysinfo, bundled_hash)
# tree hashes differ: we must compile the bundled sources
path = build_JuliaInterface(sysinfo)
@debug "Use JuliaInterface.so from $(path)"
end
return joinpath(path, "JuliaInterface.so")
Expand Down