Closed felipetesc closed 1 year ago
You also need to add tcl
crate as a dependency. Then it should work.
[dependencies]
tcl = "0.1.5"
tk = "0.1.5"
- cargo run --example add_menus
It happened while executing a tk example inside tk examples folder itself. All imports are ok inside the tcltk folder
Oh, I see.
When I first started a project with tcltk in Rust I got the same error, but adding tcl
as a dependency solved it. The examples work just fine.
Oh, I see. When I first started a project with tcltk in Rust I got the same error, but adding
tcl
as a dependency solved it. The examples work just fine.
Did you clone the repository, or have you created a new proj ? (So, I can test it again.)
I created a new project with cargo.
Would you please show me clib
’s bindings.rs generated in $OUT directory?
Would you please show me
clib
’s bindings.rs generated in $OUT directory?
Here you go:
macro_rules! t {
() => {
eprintln!("The crate clib failed in probing tcl library for the crate tcl, any invocation of Tcl's C API will abort the program.");
std::process::abort();
}
}
pub type ClientData = *mut ::std::os::raw::c_void;
pub fn Tcl_Alloc(size: ::std::os::raw::c_uint) -> *mut ::std::os::raw::c_char {t!();}
pub type Tcl_AppInitProc =
::std::option::Option<unsafe extern "C" fn(interp: *mut Tcl_Interp) -> ::std::os::raw::c_int>;
pub const TCL_APPEND_VALUE: u32 = 4;
pub type Tcl_CmdDeleteProc = ::std::option::Option<unsafe extern "C" fn(clientData: ClientData)>;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Tcl_Command_ {
_unused: [u8; 0],
}
pub type Tcl_Command = *mut Tcl_Command_;
pub fn Tcl_CreateInterp() -> *mut Tcl_Interp {t!();}
pub fn Tcl_CreateObjCommand(
interp: *mut Tcl_Interp,
cmdName: *const ::std::os::raw::c_char,
proc_: Tcl_ObjCmdProc,
clientData: ClientData,
deleteProc: Tcl_CmdDeleteProc,
) -> Tcl_Command {t!();}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Tcl_DString {
pub string: *mut ::std::os::raw::c_char,
pub length: ::std::os::raw::c_int,
pub spaceAvl: ::std::os::raw::c_int,
pub staticSpace: [::std::os::raw::c_char; 200usize],
}
pub fn Tcl_DStringInit(dsPtr: *mut Tcl_DString) {t!();}
pub fn Tcl_DStringAppendElement(
dsPtr: *mut Tcl_DString,
element: *const ::std::os::raw::c_char,
) -> *mut ::std::os::raw::c_char {t!();}
pub fn Tcl_DStringStartSublist(dsPtr: *mut Tcl_DString) {t!();}
pub fn Tcl_DStringEndSublist(dsPtr: *mut Tcl_DString) {t!();}
pub fn Tcl_DStringFree(dsPtr: *mut Tcl_DString) {t!();}
pub fn Tcl_DeleteInterp(interp: *mut Tcl_Interp) {t!();}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Tcl_Dict_ {
_unused: [u8; 0],
}
pub type Tcl_Dict = *mut Tcl_Dict_;
pub fn Tcl_DictObjFirst(
interp: *mut Tcl_Interp,
dictPtr: *mut Tcl_Obj,
searchPtr: *mut Tcl_DictSearch,
keyPtrPtr: *mut *mut Tcl_Obj,
valuePtrPtr: *mut *mut Tcl_Obj,
donePtr: *mut ::std::os::raw::c_int,
) -> ::std::os::raw::c_int {t!();}
pub fn Tcl_DictObjGet(
interp: *mut Tcl_Interp,
dictPtr: *mut Tcl_Obj,
keyPtr: *mut Tcl_Obj,
valuePtrPtr: *mut *mut Tcl_Obj,
) -> ::std::os::raw::c_int {t!();}
pub fn Tcl_DictObjNext(
searchPtr: *mut Tcl_DictSearch,
keyPtrPtr: *mut *mut Tcl_Obj,
valuePtrPtr: *mut *mut Tcl_Obj,
donePtr: *mut ::std::os::raw::c_int,
) {t!();}
pub fn Tcl_DictObjPut(
interp: *mut Tcl_Interp,
dictPtr: *mut Tcl_Obj,
keyPtr: *mut Tcl_Obj,
valuePtr: *mut Tcl_Obj,
) -> ::std::os::raw::c_int {t!();}
pub fn Tcl_DictObjRemove(
interp: *mut Tcl_Interp,
dictPtr: *mut Tcl_Obj,
keyPtr: *mut Tcl_Obj,
) -> ::std::os::raw::c_int {t!();}
pub fn Tcl_DictObjSize(
interp: *mut Tcl_Interp,
dictPtr: *mut Tcl_Obj,
sizePtr: *mut ::std::os::raw::c_int,
) -> ::std::os::raw::c_int {t!();}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Tcl_DictSearch {
pub next: *mut ::std::os::raw::c_void,
pub epoch: ::std::os::raw::c_int,
pub dictionaryPtr: Tcl_Dict,
}
pub fn Tcl_DoOneEvent(flags: ::std::os::raw::c_int) -> ::std::os::raw::c_int {t!();}
pub type Tcl_DupInternalRepProc =
::std::option::Option<unsafe extern "C" fn(srcPtr: *mut Tcl_Obj, dupPtr: *mut Tcl_Obj)>;
pub const TCL_ERROR: u32 = 1;
pub fn Tcl_EvalObjEx(
interp: *mut Tcl_Interp,
objPtr: *mut Tcl_Obj,
flags: ::std::os::raw::c_int,
) -> ::std::os::raw::c_int {t!();}
pub fn Tcl_FindExecutable(argv0: *const ::std::os::raw::c_char) {t!();}
pub type Tcl_FreeInternalRepProc =
::std::option::Option<unsafe extern "C" fn(objPtr: *mut Tcl_Obj)>;
pub fn Tcl_GetBooleanFromObj(
interp: *mut Tcl_Interp,
objPtr: *mut Tcl_Obj,
intPtr: *mut ::std::os::raw::c_int,
) -> ::std::os::raw::c_int {t!();}
pub fn Tcl_GetDoubleFromObj(
interp: *mut Tcl_Interp,
objPtr: *mut Tcl_Obj,
doublePtr: *mut f64,
) -> ::std::os::raw::c_int {t!();}
pub fn Tcl_GetIntFromObj(
interp: *mut Tcl_Interp,
objPtr: *mut Tcl_Obj,
intPtr: *mut ::std::os::raw::c_int,
) -> ::std::os::raw::c_int {t!();}
pub fn Tcl_GetLongFromObj(
interp: *mut Tcl_Interp,
objPtr: *mut Tcl_Obj,
longPtr: *mut ::std::os::raw::c_long,
) -> ::std::os::raw::c_int {t!();}
pub fn Tcl_GetNameOfExecutable() -> *const ::std::os::raw::c_char {t!();}
pub fn Tcl_GetObjResult(interp: *mut Tcl_Interp) -> *mut Tcl_Obj {t!();}
pub fn Tcl_GetObjType(typeName: *const ::std::os::raw::c_char) -> *const Tcl_ObjType {t!();}
pub fn Tcl_GetReturnOptions(
interp: *mut Tcl_Interp,
result: ::std::os::raw::c_int,
) -> *mut Tcl_Obj {t!();}
pub fn Tcl_GetStringFromObj(
objPtr: *mut Tcl_Obj,
lengthPtr: *mut ::std::os::raw::c_int,
) -> *mut ::std::os::raw::c_char {t!();}
pub fn Tcl_GetWideIntFromObj(
interp: *mut Tcl_Interp,
objPtr: *mut Tcl_Obj,
widePtr: *mut Tcl_WideInt,
) -> ::std::os::raw::c_int {t!();}
pub fn Tcl_Init(interp: *mut Tcl_Interp) -> ::std::os::raw::c_int {t!();}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Tcl_Interp {
pub resultDontUse: *mut ::std::os::raw::c_char,
pub freeProcDontUse:
::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_char)>,
pub errorLineDontUse: ::std::os::raw::c_int,
}
pub fn Tcl_InvalidateStringRep(objPtr: *mut Tcl_Obj) {t!();}
pub const TCL_LEAVE_ERR_MSG: u32 = 512;
pub const TCL_LIST_ELEMENT: u32 = 8;
pub fn Tcl_ListObjAppendElement(
interp: *mut Tcl_Interp,
listPtr: *mut Tcl_Obj,
objPtr: *mut Tcl_Obj,
) -> ::std::os::raw::c_int {t!();}
pub fn Tcl_ListObjAppendList(
interp: *mut Tcl_Interp,
listPtr: *mut Tcl_Obj,
elemListPtr: *mut Tcl_Obj,
) -> ::std::os::raw::c_int {t!();}
pub fn Tcl_ListObjGetElements(
interp: *mut Tcl_Interp,
listPtr: *mut Tcl_Obj,
objcPtr: *mut ::std::os::raw::c_int,
objvPtr: *mut *mut *mut Tcl_Obj,
) -> ::std::os::raw::c_int {t!();}
pub fn Tcl_ListObjIndex(
interp: *mut Tcl_Interp,
listPtr: *mut Tcl_Obj,
index: ::std::os::raw::c_int,
objPtrPtr: *mut *mut Tcl_Obj,
) -> ::std::os::raw::c_int {t!();}
pub fn Tcl_ListObjLength(
interp: *mut Tcl_Interp,
listPtr: *mut Tcl_Obj,
lengthPtr: *mut ::std::os::raw::c_int,
) -> ::std::os::raw::c_int {t!();}
pub fn Tcl_ListObjReplace(
interp: *mut Tcl_Interp,
listPtr: *mut Tcl_Obj,
first: ::std::os::raw::c_int,
count: ::std::os::raw::c_int,
objc: ::std::os::raw::c_int,
objv: *const *mut Tcl_Obj,
) -> ::std::os::raw::c_int {t!();}
pub fn Tcl_NewDictObj() -> *mut Tcl_Obj {t!();}
pub fn Tcl_NewDoubleObj(doubleValue: f64) -> *mut Tcl_Obj {t!();}
pub fn Tcl_NewIntObj(intValue: ::std::os::raw::c_int) -> *mut Tcl_Obj {t!();}
pub fn Tcl_NewListObj(objc: ::std::os::raw::c_int, objv: *const *mut Tcl_Obj) -> *mut Tcl_Obj {t!();}
pub fn Tcl_NewObj() -> *mut Tcl_Obj {t!();}
pub fn Tcl_NewStringObj(
bytes: *const ::std::os::raw::c_char,
length: ::std::os::raw::c_int,
) -> *mut Tcl_Obj {t!();}
pub fn Tcl_NewWideIntObj(wideValue: Tcl_WideInt) -> *mut Tcl_Obj {t!();}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct Tcl_Obj {
pub refCount: ::std::os::raw::c_int,
pub bytes: *mut ::std::os::raw::c_char,
pub length: ::std::os::raw::c_int,
pub typePtr: *const Tcl_ObjType,
pub internalRep: Tcl_Obj__bindgen_ty_1,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union Tcl_Obj__bindgen_ty_1 {
pub longValue: ::std::os::raw::c_long,
pub doubleValue: f64,
pub otherValuePtr: *mut ::std::os::raw::c_void,
pub wideValue: Tcl_WideInt,
pub twoPtrValue: Tcl_Obj__bindgen_ty_1__bindgen_ty_1,
pub ptrAndLongRep: Tcl_Obj__bindgen_ty_1__bindgen_ty_2,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Tcl_Obj__bindgen_ty_1__bindgen_ty_1 {
pub ptr1: *mut ::std::os::raw::c_void,
pub ptr2: *mut ::std::os::raw::c_void,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Tcl_Obj__bindgen_ty_1__bindgen_ty_2 {
pub ptr: *mut ::std::os::raw::c_void,
pub value: ::std::os::raw::c_ulong,
}
pub fn Tcl_ObjGetVar2(
interp: *mut Tcl_Interp,
part1Ptr: *mut Tcl_Obj,
part2Ptr: *mut Tcl_Obj,
flags: ::std::os::raw::c_int,
) -> *mut Tcl_Obj {t!();}
pub fn Tcl_ObjSetVar2(
interp: *mut Tcl_Interp,
part1Ptr: *mut Tcl_Obj,
part2Ptr: *mut Tcl_Obj,
newValuePtr: *mut Tcl_Obj,
flags: ::std::os::raw::c_int,
) -> *mut Tcl_Obj {t!();}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Tcl_ObjType {
pub name: *const ::std::os::raw::c_char,
pub freeIntRepProc: Tcl_FreeInternalRepProc,
pub dupIntRepProc: Tcl_DupInternalRepProc,
pub updateStringProc: Tcl_UpdateStringProc,
pub setFromAnyProc: Tcl_SetFromAnyProc,
}
pub const TCL_OK: u32 = 0;
pub fn Tcl_Panic(format: *const ::std::os::raw::c_char) -> ! {t!();}
pub fn Tcl_RegisterObjType(typePtr: *const Tcl_ObjType) {t!();}
pub type Tcl_SetFromAnyProc = ::std::option::Option<
unsafe extern "C" fn(interp: *mut Tcl_Interp, objPtr: *mut Tcl_Obj) -> ::std::os::raw::c_int,
>;
pub fn Tcl_SetListObj(
objPtr: *mut Tcl_Obj,
objc: ::std::os::raw::c_int,
objv: *const *mut Tcl_Obj,
) {t!();}
pub fn Tcl_SetObjErrorCode(interp: *mut Tcl_Interp, errorObjPtr: *mut Tcl_Obj) {t!();}
pub fn Tcl_SetObjResult(interp: *mut Tcl_Interp, resultObjPtr: *mut Tcl_Obj) {t!();}
pub type Tcl_ObjCmdProc = ::std::option::Option<
unsafe extern "C" fn(
clientData: ClientData,
interp: *mut Tcl_Interp,
objc: ::std::os::raw::c_int,
objv: *const *mut Tcl_Obj,
) -> ::std::os::raw::c_int,
>;
pub fn Tcl_UnsetVar(
interp: *mut Tcl_Interp,
varName: *const ::std::os::raw::c_char,
flags: ::std::os::raw::c_int,
) -> ::std::os::raw::c_int {t!();}
pub fn Tcl_UnsetVar2(
interp: *mut Tcl_Interp,
part1: *const ::std::os::raw::c_char,
part2: *const ::std::os::raw::c_char,
flags: ::std::os::raw::c_int,
) -> ::std::os::raw::c_int {t!();}
pub type Tcl_UpdateStringProc = ::std::option::Option<unsafe extern "C" fn(objPtr: *mut Tcl_Obj)>;
pub type Tcl_WideInt = ::std::os::raw::c_longlong;
pub fn Tcl_WrongNumArgs(
interp: *mut Tcl_Interp,
objc: ::std::os::raw::c_int,
objv: *const *mut Tcl_Obj,
message: *const ::std::os::raw::c_char,
) {t!();}
pub fn TclFreeObj(objPtr: *mut Tcl_Obj) {t!();}
So, bindings is missing Tcl_Eval
Oh, I see. When I first started a project with tcltk in Rust I got the same error, but adding
tcl
as a dependency solved it. The examples work just fine.
What version did you use, rustc, and what OS ? Did you clone the repository, because that's what I did.
Its working on Windows 11, I checked bindings.rs on Windows and the method Tcl_Eval is there, but the problem still persists on Ubuntu 22.04 since its missing the method. I'll copy and paste the function on ubuntu and see what happens.
System: Fedora Workstation 38
[dependencies]
tcl = "0.1.5"
tk = "0.1.5"
Created a new project using cargo new demo_tcltk
, added tcl
and tk
crates using cargo add tcl tk
, used cargo run
to run.
src/main.rs
:
use tk::cmd::*;
use tk::*;
fn main() -> TkResult<()> {
let tk = make_tk!()?;
let root = tk.root();
root.add_ttk_label(-text("Foobar"))?.grid(())?;
root.set_wm_geometry(TkGeometry{ w: 400, h: 300, x: 200, y: 100 })?;
Ok(main_loop())
}
After adding at the bottom of bindings.rs the code :
pub fn Tcl_Eval(
interp: *mut Tcl_Interp,
script: *const ::std::os::raw::c_char,
) -> ::std::os::raw::c_int {t!();}
I could compile the example.
System: Fedora Workstation 38
[dependencies] tcl = "0.1.5" tk = "0.1.5"
Created a new project using
cargo new demo_tcltk
, addedtcl
andtk
crates usingcargo add tcl tk
, usedcargo run
to run.
src/main.rs
:use tk::cmd::*; use tk::*; fn main() -> TkResult<()> { let tk = make_tk!()?; let root = tk.root(); root.add_ttk_label(-text("Foobar"))?.grid(())?; root.set_wm_geometry(TkGeometry{ w: 400, h: 300, x: 200, y: 100 })?; Ok(main_loop()) }
Followed exactly the same and I got:
error: /home/ftx10/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tk-0.1.5/src/lib.rs:424: cannot find function, tuple struct or tuple variant `Tcl_Eval` in crate `clib`
error: /home/ftx10/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tk-0.1.5/src/lib.rs:424: Errors occurred in /home/ftx10/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tk-0.1.5/src/lib.rs from external crate
error: /home/ftx10/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tk-0.1.5/src/lib.rs:424: Macro text: if unsafe{ clib::Tcl_Eval( tcl_interp, script )} == clib::TCL_OK as c_int {
error: /home/ftx10/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tk-0.1.5/src/lib.rs:424: not found in `clib`
error: could not compile `tk` (lib) due to 2 previous errors
Fixed. I'm feeling stupid actually. The problem was related to the fact Ubuntu divides its libraries into dev packages and the runtime. So, it could not find probably the c include files. For people which may find the same problem install tk, tcl, tk-dev, tcl-dev, libclang and libclang-dev.
Oh yeah. Those development packages were already installed for me, because I also build Tk extensions in C. I didn't even notice that they were necessary.
Yes, on Debian/Ubuntu "-dev" packages are required. By the way, the binding.rs containing t!()
is a quick fix for forcing docs.rs to generate document pages without the need of installing native tcl/tk packages on their docker machines. If you see it on your disk, that indicates the failure of clib.
Expected Behavior
To be able to run examples
Current Behavior
I can't compile or run a tk example
Possible Solution
Fix clip missing import : clib::Tcl_Eval
Steps to Reproduce
Context (Environment)
Ubuntu 22.04 x86_x64 rustc 1.69.0 (84c898d65 2023-04-16) cargo 1.69.0 (6e9a83356 2023-04-12) tk version = "0.1.5"
Context (Output)