Skip to content

Commit 78b77a6

Browse files
authored
Merge pull request #323 from MediosZ/fix-rs-package
Handle rs crate dependencies.
2 parents 215c456 + a23029b commit 78b77a6

File tree

19 files changed

+633
-15
lines changed

19 files changed

+633
-15
lines changed

source/loaders/rs_loader/rust/compiler/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ rustc_private = true
1010
dlopen = "0.1.8"
1111
libffi = "3.0.0"
1212
cargo_toml = "0.11.5"
13-
lazy_static = "1.4.0"
13+
lazy_static = "1.4.0"
14+
itertools = "0.10.3"

source/loaders/rs_loader/rust/compiler/src/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub fn handle_ty(ty: &rustc_ast::Ty) -> FunctionParameter {
2727
"f32" => result.ty = FunctionType::f32,
2828
"f64" => result.ty = FunctionType::f64,
2929
"bool" => result.ty = FunctionType::bool,
30-
"str" => result.ty = FunctionType::str,
30+
"str" => result.ty = FunctionType::String,
3131
"Vec" => {
3232
result.ty = FunctionType::Array;
3333
if let Some(args) = &segment.args {

source/loaders/rs_loader/rust/compiler/src/lib.rs

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#![feature(box_patterns)]
55
#![feature(let_else)]
66
#![feature(iter_zip)]
7+
// allow us to get file prefix
8+
#![feature(path_file_prefix)]
79
extern crate rustc_ast;
810
extern crate rustc_ast_pretty;
911
extern crate rustc_attr;
@@ -19,13 +21,17 @@ extern crate rustc_session;
1921
extern crate rustc_span;
2022

2123
use dlopen;
24+
use itertools::Itertools;
2225
use rustc_ast::{visit, Impl, Item, ItemKind, VariantData};
2326
use rustc_hir::def::{DefKind, Res};
2427
use rustc_hir::def_id::DefId;
2528
use rustc_interface::{interface::Compiler, Config, Queries};
2629
use rustc_middle::hir::exports::Export;
2730
use rustc_middle::ty::Visibility;
28-
use rustc_session::config::{self, CrateType, ExternEntry, ExternLocation, Externs, Input};
31+
use rustc_session::config::{
32+
self, CrateType, ErrorOutputType, ExternEntry, ExternLocation, Externs, Input,
33+
};
34+
use rustc_session::search_paths::SearchPath;
2935
use rustc_session::utils::CanonicalizedPath;
3036
use rustc_span::source_map;
3137
use std::io::Write;
@@ -393,25 +399,36 @@ impl CompilerCallbacks {
393399
}
394400
fn analyze_metadata<'tcx>(&mut self, queries: &'tcx Queries<'tcx>) {
395401
let mut class_map: HashMap<DefId, Class> = HashMap::new();
396-
let crate_num = queries
402+
let krates = queries
397403
.expansion()
398404
.expect("Unable to get Expansion")
399405
.peek_mut()
400406
.1
401407
.borrow_mut()
402408
.access(|resolver| {
403409
let c_store = resolver.cstore().clone();
404-
c_store
405-
.crates_untracked()
406-
.last()
407-
.cloned()
408-
.expect("Unable to get last element of crates.")
410+
c_store.crates_untracked()
409411
});
410412
queries
411413
.global_ctxt()
412414
.expect("Unable to get global ctxt")
413415
.peek_mut()
414416
.enter(|ctxt| {
417+
// since we are loading a package, input_path should be lib<crate_name>.rlib
418+
let crate_name = &self
419+
.source
420+
.input_path
421+
.file_prefix()
422+
.expect("Unable to get file prefix.")
423+
.to_str()
424+
.expect("Unable to cast OsStr to str")[3..];
425+
// find our krate
426+
let crate_num = krates
427+
.iter()
428+
.find_or_first(|&&x| {
429+
ctxt.crate_name(x) == rustc_span::Symbol::intern(crate_name)
430+
})
431+
.expect("unable to find crate");
415432
// parse public functions and structs
416433
for child in ctxt.item_children(crate_num.as_def_id()) {
417434
let Export {
@@ -466,7 +483,7 @@ impl CompilerCallbacks {
466483
}
467484
}
468485
// after parsing all structs, parse tarit implementations.
469-
for trait_impl in ctxt.all_trait_implementations(crate_num) {
486+
for trait_impl in ctxt.all_trait_implementations(*crate_num) {
470487
use rustc_middle::ty::fast_reject::SimplifiedTypeGen::AdtSimplifiedType;
471488
if let Some(AdtSimplifiedType(def_id)) = trait_impl.1 {
472489
if let Some(class) = class_map.get_mut(&def_id) {
@@ -519,6 +536,19 @@ impl rustc_driver::Callbacks for CompilerCallbacks {
519536
}
520537

521538
config.opts.externs = Externs::new(externs);
539+
// we hardcode the dependency path for now.
540+
let dep_path = self
541+
.source
542+
.input_path
543+
.clone()
544+
.parent()
545+
.expect("Unable to get parent dir")
546+
.join("deps");
547+
// println!("include dep: {}", dep_path.display());
548+
config.opts.search_paths.push(SearchPath::from_cli_opt(
549+
format!("dependency={}", dep_path.display()).as_str(),
550+
ErrorOutputType::default(),
551+
));
522552
// Set up inputs
523553
let wrapped_script_path = self
524554
.source

source/loaders/rs_loader/rust/compiler/src/wrapper/class.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::cell::RefCell;
44
use std::cell::RefMut;
55
use std::collections::HashMap;
66
use std::convert::TryInto;
7-
use std::ffi::CStr;
7+
use std::ffi::{CStr, CString};
88
use std::fmt;
99
use std::sync::Arc;
1010
type Result<T, E = i32> = core::result::Result<T, E>;
@@ -546,7 +546,18 @@ impl ToMetaResult for f64 {
546546

547547
impl ToMetaResult for String {
548548
fn to_meta_result(self) -> Result<MetacallValue> {
549-
Ok(unsafe { metacall_value_create_string(self.as_ptr() as *const i8, self.len()) })
549+
let length = self.len();
550+
let cstring = CString::new(self).expect("Unable to cast String to CString");
551+
let ptr = cstring.as_ptr();
552+
Ok(unsafe { metacall_value_create_string(ptr, length) })
553+
}
554+
}
555+
556+
impl ToMetaResult for &str {
557+
fn to_meta_result(self) -> Result<MetacallValue> {
558+
let cstring = CString::new(self).expect("Unable to cast str to CString");
559+
let ptr = cstring.as_ptr();
560+
Ok(unsafe { metacall_value_create_string(ptr, self.len()) })
550561
}
551562
}
552563

@@ -717,6 +728,17 @@ impl FromMeta for String {
717728
}
718729
}
719730

731+
impl FromMeta for &str {
732+
fn from_meta(val: MetacallValue) -> Result<Self> {
733+
Ok(unsafe {
734+
let s = metacall_value_to_string(val);
735+
CStr::from_ptr(s)
736+
.to_str()
737+
.expect("Unable to cast Cstr to str")
738+
})
739+
}
740+
}
741+
720742
impl<T> FromMeta for Vec<T>
721743
where
722744
T: Clone + FromMeta,

source/loaders/rs_loader/rust/compiler/src/wrapper/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,11 @@ pub fn generate_wrapper(callbacks: CompilerCallbacks) -> std::io::Result<Compile
140140
let source_dir = path.parent().expect("input path has no parent");
141141

142142
// create metacall_class file
143-
println!("create: {:?}", source_dir.join("metacall_class.rs"));
143+
// println!("create: {:?}", source_dir.join("metacall_class.rs"));
144144
let mut class_file = File::create(source_dir.join("metacall_class.rs"))?;
145145
let bytes = include_bytes!("class.rs");
146146
class_file.write_all(bytes)?;
147-
println!("open: {:?}", source_dir.join("metacall_wrapped_package.rs"));
147+
// println!("open: {:?}", source_dir.join("metacall_wrapped_package.rs"));
148148
let mut wrapper_file = std::fs::OpenOptions::new()
149149
.append(true)
150150
.open(source_dir.join("metacall_wrapped_package.rs"))?;

source/loaders/rs_loader/rust/src/lifecycle/initialize.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ pub extern "C" fn rs_loader_impl_initialize(
77
loader_impl: *mut c_void,
88
_config: *mut c_void,
99
) -> *mut c_void {
10-
let boxed_loader_lifecycle_state = Box::new(api::LoaderLifecycleState::new(Vec::new()));
10+
// add current_dir to execution path to allow relative search path
11+
let search_paths = vec![std::env::current_dir().expect("Unable to get current dir")];
12+
let boxed_loader_lifecycle_state = Box::new(api::LoaderLifecycleState::new(search_paths));
1113
compiler::initialize();
1214

1315
api::define_type(

source/ports/py_port/metacall/api.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ def generate_module(handle_name, handle):
164164
'dll': 'cs',
165165
# WebAssembly Loader
166166
'wasm': 'wasm',
167+
# Rust Loader
168+
'rlib': 'rs'
167169
}
168170

169171
# Try to load it as a Python module

source/scripts/rust/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
1010
include(RustProject)
1111

1212
add_subdirectory(basic)
13+
add_subdirectory(melody)

source/scripts/rust/basic/source/basic.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,12 @@ pub fn string_len(s: String) -> usize {
5656
pub fn new_string(idx: i32) -> String {
5757
format!("get number {idx}")
5858
}
59+
60+
pub fn str_slice(s: &str) -> &str {
61+
if s.len() < 4 {
62+
return s;
63+
} else {
64+
println!("{:?}", &s[0..3]);
65+
&s[0..3]
66+
}
67+
}

source/scripts/rust/cmake/RustProject.cmake

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,63 @@ function(rust_package target version script)
116116

117117
endfunction()
118118

119+
function(cargo_package target version)
120+
121+
# Configuration
122+
set(PACKAGE_NAME ${target})
123+
set(PACKAGE_VERSION ${version})
124+
set(PACKAGE_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/build/timestamp")
125+
126+
set(configuration ${RUST_PROJECT_CONFIG_PATH}/RustProject.cmake.in)
127+
set(language "rust")
128+
# Define upper and lower versions of the language
129+
string(TOLOWER ${language} language_lower)
130+
131+
# Define project target name
132+
set(custom_target "${language_lower}-${target}")
133+
134+
# Define target for the configuration
135+
set(PACKAGE_TARGET "${custom_target}")
136+
137+
# Create project file
138+
configure_file(${configuration} ${custom_target}-config.cmake @ONLY)
139+
140+
# Set custom target
141+
add_custom_target(${custom_target} ALL)
142+
143+
#
144+
# Deployment
145+
#
146+
147+
# Install cmake script config
148+
#install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${custom_target}/${custom_target}-config.cmake"
149+
# DESTINATION ${INSTALL_CMAKE}/${custom_target}
150+
# COMPONENT runtime
151+
#)
152+
153+
# CMake config
154+
#install(EXPORT ${custom_target}-export
155+
# NAMESPACE ${META_PROJECT_NAME}::
156+
# DESTINATION ${INSTALL_CMAKE}/${custom_target}
157+
# COMPONENT dev
158+
#)
159+
160+
# Set project properties
161+
set_target_properties(${custom_target}
162+
PROPERTIES
163+
${DEFAULT_PROJECT_OPTIONS}
164+
FOLDER "${IDE_FOLDER}/${language}"
165+
)
166+
167+
# Compile project
168+
add_custom_command(TARGET ${custom_target} PRE_BUILD
169+
# fix the version of rustc
170+
COMMAND ${Rust_RUSTUP_EXECUTABLE} default nightly-2021-12-04
171+
COMMAND ${Rust_CARGO_EXECUTABLE} build
172+
--manifest-path ${CMAKE_CURRENT_SOURCE_DIR}/Cargo.toml
173+
--target-dir ${LOADER_SCRIPT_PATH}
174+
)
175+
176+
# Include generated project file
177+
include(${CMAKE_CURRENT_BINARY_DIR}/${custom_target}-config.cmake)
178+
endfunction()

0 commit comments

Comments
 (0)