How to use Cling to tinker with a large C++ library in a REPL? - cling

Cling sounds like a great way to tinker around with a the API of a large library for learning purposes. Unfortunately, there is no documentation or tutorials on how to even get started with this. I kept running into missing symbols, and having to use C++filt and rgrep over the sources over and over again to figure out what library or header to load, until I gave up.
Is the right strategy to JIT the entire library from the sources, or should you link in a pre-built library?

One way to make the link between headers and libraries is generating an autoloading map (http://cling.web.cern.ch/cling/doxygen/classcling_1_1Interpreter.html#ad56b40974d204f85e9fc0a9fa9af1660). One can generate it at built time and add a hook in the library during its static initialization. Thus the user would do:
.L myLib
This in turn would trigger header inclusion. The other way is a bit more trickier. Have a look at https://github.com/vgvassilev/cling/tree/master/test/Autoloading
I hope it helps.

Apologies for the super-late reply. You should link a pre-built library!
You can use the -l flag to load a dynamic library into cling:
$ echo 'extern "C" const char* zlibVersion();
zlibVersion()' | cling -lz
Or use .L lib interactively:
[cling]$ .L libz
[cling]$ #include <zlib.h>
[cling]$ zlibVersion()
(const char * const) "1.2.3.4"

Related

Making custom libraries permanently visible for all future projects in VS2015

I was wondering if there was a way to create my own custom library , that would be visible for all future projects, and not just the current one ?
The library is supposed to be just a simple header file (.h) with all the libraries I need to work with already included in it. I've tried searching the web for a way to do it, but I had no luck in finding such a way. If anyone knows how to, it would be greatly appreciated. Thanks in advance.
In order to make your own library, you can follow these general steps;
Let's say you want to make a library mlib
First of all create an Interface of your library: mylib.h
Implement your library in mylib.c
Compile your c file and your will get object fiile with extention .o in linux that can be linked with programs that want to use our library code
Now you can include your header in your new program where you want to use your library and provide link of your object excuteable to compiler when compiling your program.
#include
// rest of your program
now for compiling
clang -o myprogram myprogram.c -lmylib

Hiding the console from D while linked with C-version SDL2

Basically, I get a console window I don't want to see while writing SDL-windowed applications.
In C, the answer is simple: change your linker SubSystem to Windows; then SDL does the rest. It has a macro that redefines your main to SDL_main, which it calls from inside its own hidden WinMain function. Just make sure you take arguments in your main function and all goes smoothly.
In D, I'm having a little more trouble with it. Upon simply changing the subsystem by passing -L/SUBSYSTEM:WINDOWS to the linker, it informs me that I have declared main, SDL has declared WinMain, and it doesn't know how to deal. I thought changing the signature from void main() to extern(C) int SDL_main(int argc, char*[] argv) would solve the problem, but then the linker says it can't locate any of D's runtime symbols. Might have something to do with the entry point being written in C?
On the other side, my problem might be with how I have set up Derelict. I am working from this repository, which is a live-updated amalgam of all the different Derelict repositories on GitHub. In my VisualD solution, I have three relevant projects: a home-brewed Derelict project containing the source to SDL2 and the Utilities library, and the C-API SDL2 and SDL2main projects as found here. I compile and link to all three resulting libraries -- Derelict and SDL2main are static, SDL2 is dynamic. I am less inclined to say this setup is to blame, because it works just fine save the undying console window.
In the command line passed to DMD, add the linker option -L/SUBSYSTEM:WINDOWS
In case you use dub (which i recommend) and gdc, insert the following into your dub.json file:
"dflags": ["-Wl,--subsystem,windows"]

g-wan: building library outside of /csp, and g++ compilation problems

I am giving Gwan a whirl.
Having made it through example code, I started a small project with more than one source file. I now have two problems:
I got a linking error at server startup:
Linking main.cpp: undefined symbol: _ZN7GwanUrl9concatAllEv
(the main file #includes the two other files; all the files are in the csp directory)
As an alternative to having all the files in the /csp directory, I would like to make a library outside of the /csp directory while still using some of the gwan functions. sadly, a tonne of errors follow -- WHEN I GCC from commandline not via G-WAN Startup.
In file included from /home/ec2-user/gwan/include/gwan.h:22,
from Xbufstream.h:10,
from Xbufstream.cpp:10:
/usr/include/time.h:199: error: ‘size_t’ does not name a type
.....
Anyone knows what the gwan g++ argument string looks like?
(odd the 1. and 1. its 1. and 2. in the editor)
First, this is not a linker issue: you have "undefined symbol" rather than "unresolved symbol" as an error.
This is simply an #include issue.
define the main() function in your script.cpp file.
there's a G-WAN folder dedicated to user-defined include files called /gwan/include but you can as well use /csp/my_include.hpp... if you are using the right syntax:
For example, having #include "toto.hpp" in /csp/hello.cpp lets me reach C++ functions defined and implemented in the gwan/include/toto.hpp file (or defined in toto.hpp and implemented in a pre-compiled library linked to your script with #pragma link).
If you rather use #include <toto.hpp> then the SYSTEM INCLUDE PATH will be searched instead (and this will work providing that your library was correctly installed).
If you want to use #include "toto.hpp" for a custom folder that was not setup in the system, you can use G-WAN's #pragma include "../my_folder" directive to specify its PATH or you can explicitely specify it in each include: #include "../my_folder/toto.hpp".
Nothing fancy there, only C/C++ dependancy rules apply (and G-WAN really helps by providing alternate ways that do not involve system settings).
For libraries (see the G-WAN examples for SQLite, Cairo, mySQL, cURL, etc.) you can either use pre-installed libraries that exported their location in SYSTEM variables... or put your library in the /gwan/libraries folder and their include file in the /gwan/include folder.
When writing your own libraries, remember that they need to be pre-compiled. This means that you obviously cannot use G-WAN symbols since your compiler may #include "gwan.h" (to have the definitions) but your linker will not know from where G-WAN symbols can be found. The way around is to always use the G-WAN API from the G-WAN scripts. Your custom libraries must either be general-purpose or buffer any payload intended to be used by G-WAN. No-double copy is needed since G-WAN provides the set_reply() call to let G-WAN use persistent replies built without the reply xbuffer provided by G-WAN servlets.
Now, a last word about linking (which was not the cause of your trouble but could participate to the confusion). If you mix C and C++, use extern C {} to wrap your C++ prototypes called from C (otherwise you will really have "unresolved symbols").
With all this information, you should be ready to face every possible situation.
the issue of referencing gwan.h symbols inside #include files can also be solved by moving all code into the header file, whether its .h or .hpp
its ungraceful but a fix nevertheless. and good enough for the simple extension i wanted.
looking into the /libraries/sqlite3/sqlite.h helped.
#gil, thanks for your time.

Proper way to link a static library using GCC

Why is it that some static libraries (lib*.a) can be linked in the same way that shared libraries (lib*.so) are linked (ld -l switch), but some can not?
I had always been taught that all libraries, static or not, can be linked with -l..., however I've run into one library so far (GLFW), which does nothing but spew "undefined reference" link errors if I attempt to link it this way.
According to the response on this question, the "proper" way to link static libraries is to include them directly, along with my own object files, rather than using -l. And, in the case of the GLFW library, this certainly solves the issue. But every other static library I'm using works just fine when linked with -l.
So:
What could cause this one library to not work when linked rather than included directly? If I knew the cause, maybe I could edit and recompile the library to fix the issue.
Is it true that you're not supposed to link static libraries the same way you link shared libraries? (And if not, why not?)
Is the linker still able to eliminate unused library functions from the output executable when the library is directly included in this way?
Thanks for the replies! Turns out the problem was due to link order. Apparently, if you use a library which in turn has other library dependencies, those other dependencies must be listed after the library, not before as I had been doing. Learned something new!
Have you cared to indicate to GCC the path of your library (using -L) ? By using -l solely, GCC will only be able to link libraries available in standard directories.
-L[path] -l[lib]
The correct way to link a static library is using -l, but that only works if the library can be found on the search path. If it's not then you can add the directory to the list using -L or name the file by name, as you say.
The same is true for shared libraries, actually, although they're more likely to be found, perhaps.
The reason is historical. The "ar" tool was original the file archive tool on PDP11 unix, though it was later replaced entirely by "tar" for that purpose. It stores files (object files, in this case) in a package. And there's a separate extension containing the symbol table for the linker to use. It's possible if you are manually managing files in the archive that the symbol table can get out of date.
The short answer is that you can use the "ranlib" tool on any archive to recreate the symbol table. Try that. More broadly, try to figure out where the corrupt libraries are coming from and fix that.

#pragma comment(lib, "xxx.lib") equivalent under Linux?

I have a static library file called libunp.a, I do know I could use gcc -lunp xx to link to the library.
I could use #pragma comment(lib,"xxx.lib") to tell the Microsoft C/C++ compiler to include the library; how could I do it under Linux/GCC?
There doesn't seem to be any mention of any equivalent pragmas in the GCC manual's page on pragmas.
One reason I saw for GCC not supporting linking in source code was that sometimes, correct linking depends on link order; and this would require you to make sure that the linking order happens correctly no matter the order of compilation. If you're going to go to that much work, you may as well just pass the linker arguments on the command line (or otherwise), I suppose.
Libraries should be specified during the linking step. Such information simply
doesn't belong inside a translation unit. A translation unit can be preprocessed,
compiled and assembled even without a linking stage.
Simply because #pragma comment(lib,"xxx.lib") is in the source file does not mean the compiler consumes it. In fact, it goes in as a comment and is subsequently used by the linker. Not much different than *nix.
Use this GCC flag to generate an error for unknown pragmas. It will quickly tell you if the compiler understands it.
-Werror=unknown-pragmas

Resources