unresolved external symbol
Cyberduc-k opened this issue · 2 comments
I just copied the example code from the readme and I'm getting this error:
error: linking with `C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\bin\HostX64\x64\link.exe` failed: exit code: 1120
= note: libhighlights-6d10d8ef55039a48.rlib(highlights-6d10d8ef55039a48.5ptoq1vovgegxtw.rcgu.o) : error LNK2019: unresolved external symbol tree_sitter_rust referenced in function _ZN10highlights11Highlighter3new17h5a2c4522f1121318E
G:\syntax highlighting\rust\highlights\target\debug\deps\highlights-2195fc3ea40e8e40.exe : fatal error LNK1120: 1 unresolved externals
I'm assuming this is because I do not have the language installed, but there is no documentation on how to do so in rust. If there is a solution for this problem that would be greatly appreciated.
Yeah, that's a linker error. It's happening because you're not including tree_sitter_rust
in your program. Tree-sitter parser libraries like tree_sitter_rust
are written in C, so in order to use them in a rust program, you either need to either:
- Compile them separately as dynamic libraries and then load them dynamically using something like
rust-dlopen
. - Link them into your rust program at build time.
Option 2 is easier; the README assumes that you're doing that. For some general information about including C files in a rust program, see the Build Scripts chapter of the Rust book.
More specifically, you're going to want to use The cc-rs
crate to compile the C code as part of building your crate. In your build.rs
file, you'll compile the two source files of tree_sitter_rust
:
extern crate cc;
use std::path::PathBuf;
fn main() {
let tree_sitter_rust: PathBuf = ["path", "to", "tree_sitter_rust", "src"].iter().collect();
cc::Build::new()
.include(&tree_sitter_rust)
.file(tree_sitter_rust.join("parser.c"))
.file(tree_sitter_rust.join("scanner.cc"))
.compile("some_output_filename");
}
I fix this setting
$ export RUST_TREE_SITTER_TEST=true
Adding this src/main.rs
extern crate tree_sitter;
use tree_sitter::{Parser, Language};
fn main() {
let mut parser = Parser::new();
extern "C" { fn tree_sitter_rust() -> Language; }
let language = unsafe { tree_sitter_rust() };
parser.set_language(language).unwrap();
let source_code = "fn test() {}";
let tree = parser.parse_str(source_code, None).unwrap();
let root_node = tree.root_node();
println!("{}", source_code);
println!("{}", root_node.to_sexp());
assert_eq!(root_node.kind(), "source_file");
assert_eq!(root_node.start_position().column, 0);
assert_eq!(root_node.end_position().column, 12);
}
Notice the unwrap in let tree = parser.parse_str(source_code, None).unwrap();
and running:
$ cargo run