Skip to content
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## v0.24

- Handle version compatibility solely through jlrs-compat.

- Support `TypeEq` in Julia 1.14.

## v0.23

- Implement `Clone` for `Tracked`. Note that this will break your code if the tracked type implements `Clone`, and the tracked handle was used to clone the data; this will now return a cloned handle, instead of the cloned underlying type.
Expand Down
2 changes: 1 addition & 1 deletion crates/build_utils/find_julia/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "find-julia"
version = "0.1.1"
version = "0.2.0"
authors = ["Thomas van Doornmalen <thomas.vandoornmalen@gmail.com>"]
description = """
Finds the installed version of Julia through environment variables
Expand Down
113 changes: 97 additions & 16 deletions crates/build_utils/find_julia/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@

#[cfg(target_os = "windows")]
use std::str::FromStr;
use std::{env, io::Read, path::PathBuf, process::Command};
use std::{
env,
fs::File,
io::{Read, Write},
path::{Path, PathBuf},
process::Command,
};

/// Detected Julia version
#[derive(Clone)]
Expand Down Expand Up @@ -126,7 +132,13 @@ impl Version {
}
}

fn emit_metadata(&self, min_minor_version: u32, max_minor_version: u32) {
fn emit_metadata(
&self,
min_minor_version: u32,
max_minor_version: u32,
nightly_minor_version: u32,
warn: bool,
) {
let major = self.major();
let minor = self.minor();
let patch = self.patch();
Expand All @@ -136,19 +148,49 @@ impl Version {
}

if self.is_dev() {
println!(
"cargo::warning=Detected development version of Julia {major}.{minor}.{patch}, \
bindings may not be up-to-date. Please report any issues you encounter at \
https://www.github.com/Taaitaaiger/jlrs/issues"
);
if warn {
println!(
"cargo::warning=Detected development version of Julia {major}.{minor}.{patch}, \
bindings may not be up-to-date. Please report any issues you encounter at \
https://www.github.com/Taaitaaiger/jlrs/issues"
);
}
}

if minor > max_minor_version {
println!(
"cargo::warning=Detected unsupported version of Julia {major}.{minor}.{patch}, \
assuming compatibility with 1.{max_minor_version}. Please report any issues you \
encounter at https://www.github.com/Taaitaaiger/jlrs/issues"
);
if minor > nightly_minor_version {
if warn {
println!(
"cargo::warning=Detected too recent version of Julia {major}.{minor}.{patch}, \
assuming compatibility with 1.{nightly_minor_version}. Please report any issues you \
encounter at https://www.github.com/Taaitaaiger/jlrs/issues"
);
}

let mut version = self.clone();
version.minor = nightly_minor_version;
version.patch = 0;
version.emit_metadata_unchecked();
} else if minor == nightly_minor_version {
if warn {
println!(
"cargo::warning=Detected nightly version of Julia {major}.{minor}.{patch}. \
Please report any issues you encounter at \
https://www.github.com/Taaitaaiger/jlrs/issues"
);
}

let mut version = self.clone();
version.minor = nightly_minor_version;
version.patch = 0;
version.emit_metadata_unchecked();
} else if minor > max_minor_version {
if warn {
println!(
"cargo::warning=Detected unsupported version of Julia {major}.{minor}.{patch}, \
assuming compatibility with 1.{max_minor_version}. Please report any issues you \
encounter at https://www.github.com/Taaitaaiger/jlrs/issues"
);
}

let mut version = self.clone();
version.minor = max_minor_version;
Expand Down Expand Up @@ -206,6 +248,16 @@ impl JuliaDir {
}
}

pub fn docs(stable_major: u32, stable_minor: u32) -> Self {
JuliaDir {
is_binary_builder: false,
windows: false,
path: PathBuf::new(),
version: Version::new(stable_major, stable_minor, 0, false),
debug: false,
}
}

/// The version of this Julia installation
pub fn version(&self) -> Version {
self.version.clone()
Expand Down Expand Up @@ -258,7 +310,13 @@ impl JuliaDir {
}

/// Emit detected Julia installation metadata.
pub fn emit_metadata(&self, min_minor_version: u32, max_minor_version: u32) {
pub fn emit_metadata(
&self,
min_minor_version: u32,
max_minor_version: u32,
nightly_minor_version: u32,
warn: bool,
) {
println!("cargo::metadata=julia_dir={}", self.path.display());

let is_debug = if self.debug { 1 } else { 0 };
Expand All @@ -267,8 +325,12 @@ impl JuliaDir {
let is_windows = if self.windows { 1 } else { 0 };
println!("cargo::metadata=windows={}", is_windows);

self.version
.emit_metadata(min_minor_version, max_minor_version);
self.version.emit_metadata(
min_minor_version,
max_minor_version,
nightly_minor_version,
warn,
);
}

/// Load the installation detected when jl-sys was built.
Expand Down Expand Up @@ -297,6 +359,25 @@ impl JuliaDir {
})
}
}

pub fn write_version_file(
&self,
path: &Path,
lts_version: u32,
nightly_minor_version: u32,
) -> std::io::Result<()> {
let mut output = File::create(path)?;
write!(
output,
"const MAJOR_VERSION: usize = 1;
const MIN_MINOR_VERSION: usize = {};
const NIGHTLY_MINOR_VERSION: usize = {};
const SELECTED_MINOR_VERSION: usize = {};",
lts_version, nightly_minor_version, self.version.minor
)?;

Ok(())
}
}

/// Enable the `julia_1_x` version configs from `min_version..=max_version`.
Expand Down
4 changes: 2 additions & 2 deletions crates/build_utils/jlrs_compat/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[package]
name = "jlrs-compat"
version = "0.1.0"
version = "0.2.0"
authors = ["Thomas van Doornmalen <thomas.vandoornmalen@gmail.com>"]
description = """
Defines compatible and stable versions of Julia supporte by jlrs
Defines compatible and stable versions of Julia supported by jlrs
"""
documentation = "https://docs.rs/jlrs"
homepage = "https://github.com/Taaitaaiger/jlrs"
Expand Down
14 changes: 10 additions & 4 deletions crates/build_utils/jlrs_compat/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@
//!
//! NB: jlrs docs are currently always built for the stable version.

/// Current stable Julia major version
pub const MAJOR_VERSION: u32 = 1;

/// Minimum supported Julia minor version
pub const MIN_MINOR_VERSION: u32 = 10;

/// Maximum supported Julia minor version
pub const MAX_MINOR_VERSION: u32 = 13;

/// Current stable Julia major version
pub const STABLE_MAJOR_VERSION: u32 = 1;
/// Nightly Julia minor version
///
/// This value is set to `Some(x)` if version 1.x has incompatible changes with respect to
/// 1.`MAX_MINOR_VERSION`
pub const NIGHTLY_MINOR_VERSION: u32 = MAX_MINOR_VERSION + 1;

/// Current stable Julia minor version
pub const STABLE_MINOR_VERSION: u32 = 11;
/// Julia minor version when building documentation for docs.rs
pub const DOCS_MINOR_VERSION: u32 = 12;
6 changes: 3 additions & 3 deletions crates/ffi/jl_sys/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "jl-sys"
version = "0.27.0"
version = "0.28.0"
authors = ["Thomas van Doornmalen <thomas.vandoornmalen@gmail.com>"]
description = """
jl-sys contains the generated bindings for the Julia C API used by jlrs.
Expand All @@ -25,8 +25,8 @@ docs = []
[build-dependencies]
cc = "1"
cfg-if = "1"
find-julia = { path = "../../build_utils/find_julia", version = "0.1" }
jlrs-compat = { path = "../../build_utils/jlrs_compat", version = "0.1" }
find-julia = { path = "../../build_utils/find_julia", version = "0.2" }
jlrs-compat = { path = "../../build_utils/jlrs_compat", version = "0.2" }

[package.metadata.docs.rs]
features = ["docs"]
11 changes: 8 additions & 3 deletions crates/ffi/jl_sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ fn main() {
println!("cargo::rerun-if-env-changed=JLRS_JULIA_DIR");

// Enable julia_1_x configs
enable_version_cfgs(MIN_MINOR_VERSION, MAX_MINOR_VERSION);
enable_version_cfgs(MIN_MINOR_VERSION, NIGHTLY_MINOR_VERSION);

if building_docs() {
// Don't link Julia when building the docs
let version = Version::new(STABLE_MAJOR_VERSION, STABLE_MINOR_VERSION, 0, false);
let version = Version::new(MAJOR_VERSION, DOCS_MINOR_VERSION, 0, false);
version.emit_metadata_unchecked();
} else {
// Detect active version of Julia, emit metadata, and link Julia.
Expand All @@ -26,7 +26,12 @@ fn main() {
let julia_dir = JuliaDir::find(windows_build(), false)
.expect("JLRS_JULIA_DIR is not set and no installed version of Julia can be found");

julia_dir.emit_metadata(MIN_MINOR_VERSION, MAX_MINOR_VERSION);
julia_dir.emit_metadata(
MIN_MINOR_VERSION,
MAX_MINOR_VERSION,
NIGHTLY_MINOR_VERSION,
true,
);
julia_dir.link();
}
}
Expand Down
3 changes: 3 additions & 0 deletions crates/ffi/jl_sys/src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ pub mod globals {
#[cfg(any(julia_1_10, julia_1_11))]
pub static mut jl_kwcall_func: *mut crate::types::jl_value_t;

// Added in Julia 1.14
#[cfg(not(any(julia_1_10, julia_1_11, julia_1_12, julia_1_13)))]
pub static mut jl_typeeq_type: *mut crate::types::jl_datatype_t;
}
}

Expand Down
7 changes: 7 additions & 0 deletions crates/ffi/jl_sys/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,10 @@ pub struct jl_binding_t {
_unused: [u8; 0],
_marker: PhantomData<(*mut u8, PhantomPinned)>,
}

#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct jl_typeeq_t {
_unused: [u8; 0],
_marker: PhantomData<(*mut u8, PhantomPinned)>,
}
6 changes: 3 additions & 3 deletions crates/ffi/jlrs_sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ windows = []
docs = []

[dependencies]
jl-sys = { path = "../jl_sys", version = "0.27"}
jl-sys = { path = "../jl_sys", version = "0.28"}

[build-dependencies]
find-julia = { path = "../../build_utils/find_julia", version = "0.1" }
jlrs-compat = { path = "../../build_utils/jlrs_compat", version = "0.1" }
find-julia = { path = "../../build_utils/find_julia", version = "0.2" }
jlrs-compat = { path = "../../build_utils/jlrs_compat", version = "0.2" }
cc = "1"
cfg-if = "1"

Expand Down
8 changes: 3 additions & 5 deletions crates/ffi/jlrs_sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@ use std::env;

use cfg_if::cfg_if;
use find_julia::{JuliaDir, Version, enable_version_cfgs};
use jlrs_compat::{
MAX_MINOR_VERSION, MIN_MINOR_VERSION, STABLE_MAJOR_VERSION, STABLE_MINOR_VERSION,
};
use jlrs_compat::{DOCS_MINOR_VERSION, MAJOR_VERSION, MIN_MINOR_VERSION, NIGHTLY_MINOR_VERSION};

fn main() {
// Enable julia_1_x configs
enable_version_cfgs(MIN_MINOR_VERSION, MAX_MINOR_VERSION);
enable_version_cfgs(MIN_MINOR_VERSION, NIGHTLY_MINOR_VERSION);

if building_docs() {
let version = Version::new(STABLE_MAJOR_VERSION, STABLE_MINOR_VERSION, 0, false);
let version = Version::new(MAJOR_VERSION, DOCS_MINOR_VERSION, 0, false);
version.emit_metadata_unchecked();
return;
}
Expand Down
3 changes: 3 additions & 0 deletions crates/ffi/jlrs_sys/src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,5 +263,8 @@ pub mod jlrs_cc {
symbol: *const std::ffi::c_char,
value: *mut *mut std::ffi::c_void,
) -> std::ffi::c_int;

#[cfg(not(any(julia_1_10, julia_1_11, julia_1_12, julia_1_13)))]
pub fn jlrs_typeeq_T(v: *mut crate::types::jl_typeeq_t) -> *mut crate::types::jl_value_t;
}
}
6 changes: 6 additions & 0 deletions crates/ffi/jlrs_sys/src/jlrs_cc/jlrs_cc_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,12 @@ extern "C"
return (int)a->flags.how;
#endif
}

#if JULIA_VERSION_MINOR >= 14
jl_value_t *jlrs_typeeq_T(jl_typeeq_t *v) {
return v->T;
}
#endif
#ifdef __cplusplus
}
#endif
4 changes: 4 additions & 0 deletions crates/ffi/jlrs_sys/src/jlrs_cc/jlrs_cc_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ extern "C"
const jl_datatype_layout_t *jl_datatype_layout(jl_datatype_t *t);
#endif

#if JULIA_VERSION_MINOR >= 14
jl_value_t *jlrs_typeeq_T(jl_typeeq_t *v);
#endif

#ifdef __cplusplus
}
#endif // __cplusplus
Expand Down
4 changes: 2 additions & 2 deletions crates/ffi/jlrs_sys/src/jlrs_cc/jlrs_cc_hacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ extern "C"
void jlrs_unlock_value(jl_value_t *v);

#if JULIA_VERSION_MINOR >= 11
jl_genericmemoryref_t jlrs_memoryrefindex(jl_genericmemoryref_t m JL_ROOTING_ARGUMENT, size_t idx);
void jlrs_memoryrefset(jl_genericmemoryref_t m JL_ROOTING_ARGUMENT, jl_value_t *rhs JL_ROOTED_ARGUMENT JL_MAYBE_UNROOTED, int isatomic);
jl_genericmemoryref_t jlrs_memoryrefindex(jl_genericmemoryref_t m, size_t idx);
void jlrs_memoryrefset(jl_genericmemoryref_t m, jl_value_t *rhs, int isatomic);
char *jlrs_genericmemory_typetagdata(jl_genericmemory_t *m);
#endif

Expand Down
8 changes: 4 additions & 4 deletions crates/jlrs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "jlrs"
version = "0.23.0"
version = "0.24.0"
authors = ["Thomas van Doornmalen <thomas.vandoornmalen@gmail.com>"]
description = """
jlrs provides bindings to the Julia C API that enable Julia code to be called from Rust and more.
Expand Down Expand Up @@ -73,7 +73,7 @@ macos = ["jlrs-sys/macos"]
docs = ["jl-sys/docs", "jlrs-sys/docs", "jlrs-macros/docs", "full"]

[dependencies]
jl-sys = { version = "0.27", path = "../ffi/jl_sys" }
jl-sys = { version = "0.28", path = "../ffi/jl_sys" }
jlrs-sys = { version = "0.2", path = "../ffi/jlrs_sys" }
jlrs-macros = { version = "0.6", path = "../jlrs_macros" }
smallvec = {version = "1", features = ["const_generics"]}
Expand All @@ -96,8 +96,8 @@ num-complex = { version = "0.4", optional = true }
tokio = { version = "1", features = ["rt", "time", "sync"]}

[build-dependencies]
jlrs-compat = { path = "../build_utils/jlrs_compat", version = "0.1"}
find-julia = { path = "../build_utils/find_julia", version = "0.1"}
jlrs-compat = { path = "../build_utils/jlrs_compat", version = "0.2"}
find-julia = { path = "../build_utils/find_julia", version = "0.2"}

[package.metadata.docs.rs]
features = ["docs"]
Loading
Loading