diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 589aa49..85577d9 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -36,3 +36,35 @@ jobs: - uses: codecov/codecov-action@v1 with: file: lcov.info + test-custom-gmsh: + name: Gmsh SDK - Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ github.event_name }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + version: + - '1' + os: + - ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: julia-actions/setup-julia@v1 + with: + version: ${{ matrix.version }} + - uses: julia-actions/julia-buildpkg@v1 + - name: Install Gmsh SDK dependencies + run: sudo apt-get install -y libglu1-mesa + - name: Install Gmsh SDK + run: | + curl -OL https://gmsh.info/bin/Linux/gmsh-4.12.2-Linux64-sdk.tgz + tar xvf gmsh-4.12.2-Linux64-sdk.tgz + mv gmsh-4.12.2-Linux64-sdk /opt/ + - name: Configure Gmsh preferences + shell: julia --color=yes --project=. {0} + run: | + using Gmsh + Gmsh.use_system_gmsh(;gmsh_jl_dir="/opt/gmsh-4.12.2-Linux64-sdk/lib") + - uses: julia-actions/julia-runtest@v1 + - uses: julia-actions/julia-processcoverage@v1 + - uses: codecov/codecov-action@v1 + with: + file: lcov.info diff --git a/Project.toml b/Project.toml index b7179a2..a9fcccb 100644 --- a/Project.toml +++ b/Project.toml @@ -4,9 +4,12 @@ authors = ["Jukka Aho "] version = "0.3.1" [deps] +Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +Preferences = "21216c6a-2e73-6563-6e65-726566657250" gmsh_jll = "630162c2-fc9b-58b3-9910-8442a8a132e6" [compat] +Preferences = "1" gmsh_jll = "4.11" julia = "1" diff --git a/src/Gmsh.jl b/src/Gmsh.jl index 9691051..3c9956e 100644 --- a/src/Gmsh.jl +++ b/src/Gmsh.jl @@ -1,10 +1,141 @@ module Gmsh -import gmsh_jll -include(gmsh_jll.gmsh_api) +@static if VERSION >= v"1.6" + using Preferences +end + +@static if VERSION >= v"1.6" + gmsh_provider = @load_preference("gmsh_provider","gmsh_jll") +else + gmsh_provider = "gmsh_jll" +end + +# The logic behind the preferences is inspired by the one found in PetscCall.jl + +if gmsh_provider ∉ ("gmsh_jll","system") + error("gmsh_provider is either gmsh_jll or system") +end + +@static if gmsh_provider == "gmsh_jll" + import gmsh_jll + const gmsh_api = gmsh_jll.gmsh_api +end + +@static if gmsh_provider == "system" + const gmsh_jl_dir = @load_preference("gmsh_jl_dir","") + if gmsh_jl_dir == "" + error("Using a system gmsh installation but gmsh_jl_dir not found in Preferences.toml file") + end + const gmsh_api = joinpath(gmsh_jl_dir,"gmsh.jl") +end + +include(gmsh_api) import .gmsh export gmsh +@static if gmsh_provider == "system" + using Libdl + function __init__() + # This is just to have a better idea why gmsh.lib is empty + @static if Sys.isunix() + if gmsh.lib == "" + gmsh_lib = joinpath(gmsh_jl_dir,"libgmsh") + Libdl.dlopen(gmsh_lib, Libdl.RTLD_LAZY | Libdl.RTLD_DEEPBIND) + end + end + if gmsh.lib == "" + error("The gmsh.jl API file was not able to find a gmsh libary. Some dependencies are provably not installed in the system.") + end + end +end + +""" + Gmsh.use_gmsh_jll() + +Configure Gmsh to use the binary provided by gmsh_jll. +""" +function use_gmsh_jll() + @static if VERSION >= v"1.6" + gmsh_provider = "gmsh_jll" + @set_preferences!( + "gmsh_provider"=>gmsh_provider, + ) + msg = """ + Gmsh preferences changed! + The new preferences are: + gmsh_provider = $(gmsh_provider) + Restart Julia for these changes to take effect. + """ + @info msg + end + nothing +end + +""" + Gmsh.use_system_gmsh([;gmsh_jl_dir]) + +Configure Gmsh to use the binary provided by a system installation. +Key-word argument `gmsh_jl_dir` contains the path of the directory containing `gmsh.jl`, the file with +the Julia API of gmsh. This file needs to be installed as part of the SDK of gmsh. +If `gmsh_jl_dir` is omitted, this function will look for `gmsh.jl` in `LD_LIBRARY_PATH`. +""" +function use_system_gmsh(;gmsh_jl_dir=nothing) + @static if VERSION >= v"1.6" + function findindir(route,fn) + files = readdir(route,join=false) + for file in files + if file == fn + gmsh_jl_dir = joinpath(route,file) + return gmsh_jl_dir + end + end + nothing + end + if gmsh_jl_dir === nothing + if haskey(ENV,"LD_LIBRARY_PATH") && ENV["LD_LIBRARY_PATH"] != "" + routes = split(ENV["LD_LIBRARY_PATH"],':') + for route in routes + gmsh_jl_dir = findindir(route,"gmsh.jl") + if gmsh_jl_dir !== nothing + @info "Gmsh Julia API found in the system at $(gmsh_jl_dir)." + break + end + end + end + end + if gmsh_jl_dir === nothing + msg = """ + Unable to find a Gmsh installation in the system. + + We looked for the Gmsh Julia API file gmsh.jl in the folders in LD_LIBRARY_PATH. + + You can also manualy specify the route with the key-word argument gmsh_jl_dir. + + Example + ======= + + julia> using Gmsh + julia> using Gmsh.use_system_gmsh(;gmsh_jl_dir="path/to/gmsh.jl") + """ + error(msg) + end + gmsh_provider = "system" + @set_preferences!( + "gmsh_provider"=>gmsh_provider, + "gmsh_jl_dir"=>gmsh_jl_dir, + ) + msg = """ + Gmsh preferences changed! + The new preferences are: + gmsh_provider = $(gmsh_provider) + gmsh_jl_dir = $(gmsh_jl_dir) + Restart Julia for these changes to take effect. + """ + @info msg + end + nothing +end + """ Gmsh.initialize(argv=String[]; finalize_atexit=true) @@ -52,4 +183,4 @@ function finalize() end end -end +end # module