blob: 6465b17d9b60cff5a5c56e3865a4b25ad94c3562 [file]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
use crate::tests::ForeignLibraryModuleRef;
use abi_stable::library::RootModule;
use datafusion::error::{DataFusionError, Result};
use std::path::Path;
/// Compute the path to the library. It would be preferable to simply use
/// abi_stable::library::development_utils::compute_library_path however
/// our current CI pipeline has a `ci` profile that we need to use to
/// find the library.
pub fn compute_library_path<M: RootModule>(
target_path: &Path,
) -> std::io::Result<std::path::PathBuf> {
let debug_dir = target_path.join("debug");
let release_dir = target_path.join("release");
let ci_dir = target_path.join("ci");
let debug_path = M::get_library_path(&debug_dir.join("deps"));
let release_path = M::get_library_path(&release_dir.join("deps"));
let ci_path = M::get_library_path(&ci_dir.join("deps"));
let all_paths = vec![
(debug_dir.clone(), debug_path),
(release_dir, release_path),
(ci_dir, ci_path),
];
let best_path = all_paths
.into_iter()
.filter(|(_, path)| path.exists())
.filter_map(|(dir, path)| path.metadata().map(|m| (dir, m)).ok())
.filter_map(|(dir, meta)| meta.modified().map(|m| (dir, m)).ok())
.max_by_key(|(_, date)| *date)
.map(|(dir, _)| dir)
.unwrap_or(debug_dir);
Ok(best_path)
}
pub fn get_module() -> Result<ForeignLibraryModuleRef> {
let expected_version = crate::version();
let crate_root = Path::new(env!("CARGO_MANIFEST_DIR"));
let target_dir = crate_root
.parent()
.expect("Failed to find crate parent")
.parent()
.expect("Failed to find workspace root")
.join("target");
// Find the location of the library. This is specific to the build environment,
// so you will need to change the approach here based on your use case.
// let target: &std::path::Path = "../../../../target/".as_ref();
let library_path =
compute_library_path::<ForeignLibraryModuleRef>(target_dir.as_path())
.map_err(|e| DataFusionError::External(Box::new(e)))?
.join("deps");
// Load the module
let module = ForeignLibraryModuleRef::load_from_directory(&library_path)
.map_err(|e| DataFusionError::External(Box::new(e)))?;
assert_eq!(
module
.version()
.expect("Unable to call version on FFI module")(),
expected_version
);
Ok(module)
}