I have a problem with changing tcl version from 8.4 to 8.5.12 on RHEL machine. Our product uses TclDevKit components like Tcldom, Tclxml, etc. Also we are using Incr Tcl (Itcl). I am trying to create pkgIndex.tcl file in Itcl in order to find Itcl when that package is required as follown:
package ifneeded Itcl 3.4 [list load [file join $dir "libitcl-O.a"] Itcl ]
but when I use
package require Itcl
Getting report: couldn't load file "/somepath/itcl/lib/libitcl-O.a": /somepath/lib/libitcl-O.a: invalid ELF header
It seems I can't load files with .a extention, but the same is done with previous version of tcl (8.4) and it works fine. I googled a lot, read a lot of documentation, but it doesn't help to go further.
Please help.
Thanks in advance
Libraries come in two general sorts, static libraries and shared libraries. On Linux, static libraries have the extension .a by default, and shared libraries have the extension .so (plus optionally some numbers to indicate the version). Only shared libraries will work with Tcl's load command and even then they have to be designed to work that way (with an appropriate Foobar_Init function, as documented).
When dealing with stub-exporting extensions (fairly rare) or Tcl and Tk themselves, the linking is done in two parts. There's a stub library, normally called somethingstub.a, and there's a main shared library. The main shared library contains the implementation of the code; all that is in the stub library is an ABI/API adaptor so that you can avoid binding your code to an explicit version of the implementation library. By building an extension stub-enabled and linking against the stub library, you gain the ability to have your extension loaded into future versions of Tcl/Tk without any recompilation or relinking steps at all. (You also become able to put the extension inside a starkit for deployment, as those use a rather unusual way of managing shared libraries that the stub mechanism conceals from you.)
Related
Can I use for example std::vector in DriverKit driver in macOs / XCode?
DriverKit has some container class like OSArray
https://developer.apple.com/documentation/driverkit/osarray?language=objc
If I create a new "DriverKit driver" project and include <vector> then I get build errors. Those error comes from including <cstring> and the error is
No member named 'strcpy' in the global namespace
No member named 'strcat' in the global namespace
As far as I can tell, you aren't supposed to. The headers you end up pulling in there aren't from the DriverKit SDK, they're the default ones that come with Xcode's compiler toolchain. They assume a normal macOS build environment, not the dext environment. The DriverKit SDK doesn't include C++ stdlib headers, and only contains some stripped-down headers for a subset of the C standard library. Hence the missing strcpy and strcat.
Linking against libc++ also fails, even the version included in the DriverKit SDK. I don't know why there is a version of that library included with the DriverKit SDK, but it's clearly not intended for being used in dexts.
There's presumably nothing in particular stopping you from including some other container library, or even directly including parts of an STL implementation. You may need to manually wire up memory allocation calls though.
I loaded a package first:
package require Tktable
then i wanted to unload this package. I searched some info, and used "package ifneeded" to get the library path. I tried as below:
unload $path Tktable
but i got error message "cannot be unloaded under a trusted interpreter". How to unload a package?
Most packages do not support unloading at all. (Specifically, Tktable does not; it doesn't define either a Tktable_Unload function or a Tktable_SafeUnload function in its public C API.) Unloading is rare as it requires the author of the C code to take special care to ensure that it is possible at all, and most of the time programmers have other higher-priority concerns.
Unloading is disabled in safe interpreters, as it is considered to be an insecure operation. (load is also not supported, but is often profiled in restricted fashion by the parent master interpreter, such as via package require doing clever things behind the scenes.)
If the problem is that some package is interfering with your code (as seems to be the case from your comments), put your code in a namespace. There's often an easy way to pick the namespace name, typically the name of your application or library works fine. If you're wanting to call your code the same thing as someone else's and their code is more well-known than yours, that's going to cause you trouble anyway.
I am using a commercial tool interfaced with an homebrew tclsh(Synopsys EDA).
In their version, they removed the load command. Thus I cannot use third party libraries (Graphviz library in my case).
I wonder if there is a another way to import binary files (.so files)
The only command in standard Tcl that brings in a dynamic library is load. (OK, package require can do too, but that's because it can call load inside.) Without that command, you only have options like statically linking your own code in and creating the commands in the Tcl_AppInit function, but that's really unlikely to work if you're already using someone else's code that's already done that sort of thing.
The easiest approach might be to run a normal tclsh as a subprocess via exec tclsh script.tcl (run and wait for termination) or open |tclsh r+ (open pipeline). If they've not turned off those capabilities as well; you might be running in a safe interpreter where all those things are systematically disabled. I don't know of any way to break out of a standard safe interpreter (the mechanism for locking them down errs on the side of caution) so if that's the case, you'll just have to save the data you want to a file somewhere (by any mechanism that works; safe interpreters also can't touch the filesystem at all by default though that is often profiled back in in protected ways) and use a completely separate program to work with it.
I have a strange problem I am using fedora 20 and installed tcllib on my system.
But if I use package require uri in example I got an package not found in response.
Does anyone know what the issue here is or how to determine if the tcllib is added in the package index?
Tcl looks up packages in two ways: with auto_path and with tcl::tm::path.
1. The auto_path — the traditional mechanism.
When you do package require, the package manager looks to see if the package is already present, or if instructions for obtaining the package from the filesystem are present. If neither of these is true, it asks the package unknown handler to load it (strictly, it's the handler installed using the package unknown command). The default implementation of that handler loads packages by looking for pkgIndex.tcl files in the directories on your auto_path, and their immediate subdirectories.
auto_path is a global variable holding a Tcl list of directories to search. You can probably just lappend the right place to it. pkgIndex.tcl is a Tcl script that describes how to make the package available, which it does by calling an appropriate package ifneeded command. The actual loading of the
Once a package is required that isn't present but its instructions for obtaining are, Tcl will simply eval those instructions: they're just a plain old script (that usually just calls source and/or load to do the grunt work).
2. Tcl modules — the new (in 8.5) mechanism.
The Tcl module system uses a different search system managed with the tcl::tm::path command. The tcl::tm::path list subcommand will tell you where it looks (a huge list, to be honest) and you can use the tcl::tm::path add subcommand to extend the path with extra locations to search. Tcl modules have the entire package placed into a single file (with the extension .tm) and have a structured name so that they can avoid having a separate pkgIndex.tcl file; the TM loader can synthesise the package ifneeded calls from the filename itself (in all cases, this is done with source; there are some clever ways to package binary code inside files so they can be loaded, but they're far outside the scope of this answer).
At that point, you're back to the source of the file when the package is actually required; that part is the same whether you're using a module or a traditional package.
The module system is much faster than the traditional search mechanism since it doesn't need to open any files to figure out what to do: it just uses glob with the right options. It is, however, less flexible in how things can be packaged: multi-file packages (e.g., almost anything you make yourself) can't be made into modules (well, not without extra work).
We have a C++ Builder application that has lived through many versions of Embarcadero RAD Studio. Now I was trying to get it to compile in XE2 and ran into a problem where a class called TGroup became ambiguos with the TGroup class of Winsock.
To my anger I found that the initial architects of the system didn't use any namespaces, which would have solved this problem. I decided to add all the project code to a single namespace to start with. But pretty soon it dawned on me that I would have to go through about 1400 .h and .cpp files.
Please, for the love of god... Is there a good tool out there to quickly encapsulate an entire project within a namespace?
Most of the files differ a bit in layout. Some have defines after the includes and some do not etc. But to just insert the namespace declaration after the includes should probably work ok to start with and then close it just before the last #endif, which is the inclusion guard #define.
Check if the offending header files already use namespaces. All VCL-based header files DO use namespaces, but they also have using namespace statements at the bottom to dump everything into the global namespace by default. Most versions have special #define values you can set to disable that behavior.