diff --git a/Manifest.toml b/Manifest.toml index a2872232b..dc7cf9773 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.12.4" manifest_format = "2.0" -project_hash = "fdfadea8426ae4ad040aa36f8a37d6d28b17564f" +project_hash = "0ee92832e5f1b3533f8787c1ef956580dc03292e" [[deps.ADTypes]] git-tree-sha1 = "f7304359109c768cf32dc5fa2d371565bb63b68a" @@ -1094,6 +1094,14 @@ version = "1.29.4" [deps.JuMP.weakdeps] DimensionalData = "0703355e-b756-11e9-17c0-8b28908087d0" +[[deps.JuliaC]] +deps = ["LazyArtifacts", "Libdl", "Mmap", "ObjectFile", "PackageCompiler", "Patchelf_jll", "Pkg", "RelocatableFolders", "StructIO"] +git-tree-sha1 = "95eb12ccaa00c52e376c342a0056a0a5b811caa3" +repo-rev = "default_cpu_target" +repo-url = "https://github.com/visr/JuliaC.jl" +uuid = "acedd4c2-ced6-4a15-accc-2607eb759ba2" +version = "0.3.0" + [[deps.JuliaInterpreter]] deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"] git-tree-sha1 = "80580012d4ed5a3e8b18c7cd86cebe4b816d17a6" @@ -1644,6 +1652,12 @@ weakdeps = ["ForwardDiff"] [deps.NonlinearSolveSpectralMethods.extensions] NonlinearSolveSpectralMethodsForwardDiffExt = "ForwardDiff" +[[deps.ObjectFile]] +deps = ["Reexport", "StructIO"] +git-tree-sha1 = "22faba70c22d2f03e60fbc61da99c4ebfc3eb9ba" +uuid = "d8793406-e978-5875-9003-1fc021f44a92" +version = "0.5.0" + [[deps.OffsetArrays]] git-tree-sha1 = "117432e406b5c023f665fa73dc26e79ec3630151" uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" @@ -1800,6 +1814,12 @@ git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" version = "2.8.3" +[[deps.Patchelf_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "ad1cab3e8273c912f722f40779e20f3e29d58f1f" +uuid = "f2cf89d6-2bfd-5c44-bd2c-068eea195c0c" +version = "0.18.0+0" + [[deps.Pidfile]] deps = ["FileWatching", "Test"] git-tree-sha1 = "2d8aaf8ee10df53d0dfb9b8ee44ae7c04ced2b03" @@ -2401,6 +2421,11 @@ version = "0.7.2" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" +[[deps.StructIO]] +git-tree-sha1 = "c581be48ae1cbf83e899b14c07a807e1787512cc" +uuid = "53d494c1-5632-5724-8f4c-31dff12d585f" +version = "0.3.1" + [[deps.StructTypes]] deps = ["Dates", "UUIDs"] git-tree-sha1 = "159331b30e94d7b11379037feeb9b690950cace8" diff --git a/Project.toml b/Project.toml index f668a7daf..5cc69ba69 100644 --- a/Project.toml +++ b/Project.toml @@ -36,6 +36,7 @@ InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e" JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" JuMP = "4076af6c-e467-56ae-b986-b466b2749572" +JuliaC = "acedd4c2-ced6-4a15-accc-2607eb759ba2" JuliaInterpreter = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" @@ -80,6 +81,7 @@ TestItemRunner = "f8b46487-2199-4994-9208-9a1283c18c0a" TranscodingStreams = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" [sources] +JuliaC = {rev = "default_cpu_target", url = "https://github.com/visr/JuliaC.jl"} PackageCompiler = {rev = "bundle_less_artifacts_v1.12", url = "https://github.com/visr/PackageCompiler.jl"} Ribasim = {path = "core"} diff --git a/build/build.jl b/build/build.jl index ecf177dc5..b53d1c573 100644 --- a/build/build.jl +++ b/build/build.jl @@ -1,27 +1,47 @@ -using Artifacts -using PackageCompiler using TOML using LibGit2 +using JuliaC +using Preferences: set_preferences!, delete_preferences! +using UUIDs: UUID +import Pkg function (@main)(_)::Cint - project_dir = "../core" - license_file = "../LICENSE" - output_dir = "ribasim" - git_repo = ".." - - # change directory to this script's location - cd(@__DIR__) - - create_library( - project_dir, - output_dir; - lib_name = "libribasim", - precompile_execution_file = "precompile.jl", - include_lazy_artifacts = false, - include_transitive_dependencies = false, - include_preferences = true, - force = true, + project_dir = "core" + license_file = "LICENSE" + output_dir = "build/ribasim" + git_repo = "." + + # Set release options in core/LocalPreferences.toml + uuid = UUID("aac5e3d9-0b8f-4d4f-8241-b1a7a9632635") # Ribasim + Pkg.activate("core") + set_preferences!(uuid, "precompile_workload" => true; force = true) + Pkg.activate(".") + + rm(output_dir; force = true, recursive = true) + + image_recipe = ImageRecipe(; + output_type = "--output-lib", + file = "build/libribasim.jl", + project = project_dir, + add_ccallables = true, + verbose = true, + ) + link_recipe = LinkRecipe(; + image_recipe, + outname = "build/ribasim/libribasim", + rpath = "@bundle" ) + bundle_recipe = BundleRecipe(; link_recipe, output_dir) + + compile_products(image_recipe) + link_products(link_recipe) + bundle_products(bundle_recipe) + + # On Windows, remove the import library from the bundle root + if Sys.iswindows() + import_lib_path = joinpath(output_dir, "libribasim.dll.a") + rm(import_lib_path) + end add_metadata(project_dir, license_file, output_dir, git_repo, readme_start) @@ -33,10 +53,16 @@ function (@main)(_)::Cint env["RUSTFLAGS"] = "-C link-args=/STACK:8388608" end - run(Cmd(`cargo build --release`; dir = "cli", env)) + run(Cmd(`cargo build --release`; dir = "build/cli", env)) ribasim = Sys.iswindows() ? "ribasim.exe" : "ribasim" - mkpath("ribasim/bin") - cp("cli/target/release/$ribasim", "ribasim/bin/$ribasim"; force = true) + mkpath("build/ribasim/bin") + cp("build/cli/target/release/$ribasim", "build/ribasim/bin/$ribasim"; force = true) + + # Restore development options in core/LocalPreferences.toml + Pkg.activate("core") + delete_preferences!(uuid, "precompile_workload"; force = true) + Pkg.activate(".") + return 0 end @@ -78,8 +104,7 @@ function add_metadata(project_dir, license_file, output_dir, git_repo, readme) TOML.print(io, dict) end - # a stripped Project.toml is already added in the same location by PackageCompiler - # however it is better to copy the original, since it includes the version and compat + # Copy the Project.toml and Manifest.toml so we can see all dependencies and versions cp( normpath(project_dir, "Project.toml"), normpath(output_dir, "share/julia/Project.toml"); @@ -129,5 +154,5 @@ function add_metadata(project_dir, license_file, output_dir, git_repo, readme) end # Override the Cargo.toml file with the git version - return set_version("cli/Cargo.toml", tag) + return set_version("build/cli/Cargo.toml", tag) end diff --git a/core/src/libribasim.jl b/build/libribasim.jl similarity index 98% rename from core/src/libribasim.jl rename to build/libribasim.jl index 45fdb79d7..ad3677e68 100644 --- a/core/src/libribasim.jl +++ b/build/libribasim.jl @@ -1,7 +1,5 @@ -module libribasim - import BasicModelInterface as BMI -import ..Ribasim +import Ribasim using SciMLBase: successful_retcode # globals @@ -233,5 +231,3 @@ function unsafe_write_to_cstring!(dest::Cstring, src::String)::Nothing unsafe_store!(dest_ptr, '\0', length(src) + 1) return nothing end - -end # module libribasim diff --git a/build/precompile.jl b/build/precompile.jl deleted file mode 100644 index bdb722f92..000000000 --- a/build/precompile.jl +++ /dev/null @@ -1,16 +0,0 @@ -# Workflow that will compile a lot of the code we will need. -# With the purpose of reducing the latency for compiled binaries. - -using Preferences, UUIDs - -uuid = UUID("aac5e3d9-0b8f-4d4f-8241-b1a7a9632635") # Ribasim - -set_preferences!(uuid, "precompile_workload" => true; force = true) -using Ribasim - -toml_path = normpath(@__DIR__, "../generated_testmodels/basic/ribasim.toml") -# This should now only take a second or less -@assert Ribasim.main(toml_path) == 0 - -# Remove preferences to avoid affecting normal Ribasim usage -set_preferences!(uuid, "precompile_workload" => missing; force = true) diff --git a/core/src/Ribasim.jl b/core/src/Ribasim.jl index 3b89d2011..6fff40e10 100644 --- a/core/src/Ribasim.jl +++ b/core/src/Ribasim.jl @@ -169,8 +169,6 @@ using Printf: @sprintf using Base.Threads: nthreads -export libribasim - include("carrays.jl") using .CArrays: CVector, getaxes, getdata include("schema.jl") @@ -193,7 +191,6 @@ include("bmi.jl") include("callback.jl") include("concentration.jl") include("main.jl") -include("libribasim.jl") @setup_workload begin toml_path = normpath(@__DIR__, "../../generated_testmodels/basic/ribasim.toml") diff --git a/core/test/libribasim_test.jl b/core/test/libribasim_test.jl index c26cb019e..aac1d3ccc 100644 --- a/core/test/libribasim_test.jl +++ b/core/test/libribasim_test.jl @@ -1,4 +1,8 @@ -@testitem "libribasim" begin +@testmodule libribasim begin + include("../../build/libribasim.jl") +end + +@testitem "libribasim" setup = [libribasim] begin toml_path = normpath(@__DIR__, "../../generated_testmodels/basic/ribasim.toml") # data from which we create pointers for libribasim diff --git a/pixi.toml b/pixi.toml index 983096e69..d9f8ef51f 100644 --- a/pixi.toml +++ b/pixi.toml @@ -75,7 +75,7 @@ lint = { depends-on = [ "mypy-ribasim-qgis", ] } # Build -build = { "cmd" = "julia --project --check-bounds=yes build.jl", cwd = "build", depends-on = [ +build = { "cmd" = "julia --project --check-bounds=yes build/build.jl", depends-on = [ "generate-testmodels", "initialize-julia", ] }