Open cjwelborn opened 5 years ago
Hmm, seems to work for me:
$ cat test.c
int foo(int n)
{
return n * 2;
}
$ gcc -shared -o foo.so test.c
$ ./src/bic -l ./foo.so
BIC> int foo(int n);
BIC> foo(20);
40
BIC>
@hexagonal-sun, when I try the example you provided it works fine. When I try it on one of my own shared libs it doesn't:
The file is there, but for some reason it wants to search for it as if I typed 'colr'
.
Which, by the way, bic -l colr
doesn't work either, even though there is a file called libcolr.so
in the current directory. I haven't looked at bic
's code because I've been a little busy lately, but maybe I can help with this. I'll see what I can do.
bic -l colr
does work if I copy/symlink the file into /usr/lib
, but it won't work in ~/.local/lib
.
Very strange. Looking at the code it first attempts to open the file as written on the command line here and I would have expected this to work. If you could maybe debug this on your end that would be great.
bic -l colr
does work if I copy/symlink the file into/usr/lib
, but it won't work in~/.local/lib
.
bic doesn't look for libraries in ~/.local/lib
. Is that somewhere that it should maybe look?
Ideally I need to find out how the system does proper library resolution and follow that. It seems as though dlopen
doesn't cover all bases.
I'll take a look and get back to you. If I could load a local library file bic
would be awesome for debugging. I'll check it out when I get home.
@hexagonal-sun, I figured out what the problem is, and it's related to issue #17. I don't have a fix for it right now, but let me tell you what I've found.
The library I am testing with, libcolr.so
, is one of mine. It happens to depend on libm
(which is a linker script pointing to /lib/x86_64-linux-gnu/libm.so.6
on my machine. The reason the first call to dlopen
fails in open_library()
is because it tries to pull-in the libm
dependency and that fails like issue #17.
I made a little program that calls open_library()
like bic
does, except it just prints whether the call succeeded or not. I can make all of this work by manually specifying the dependencies, in order, on the command line. This works for my test program, and in bic
:
bic -l /lib/x86_64-linux-gnu/libm.so.6 -l ./libcolr.so
It's a workaround. I wish bic
could use the linker script, because then -l ./libcolr.so
would be the only thing needed (i think). I know how much work that would be though. I haven't used dlopen
very much. I may look into how it grabs the dependency libraries. The man
page has only this to say:
If the object specified by filename has dependencies on other shared objects, then these are also automatically loaded by the dynamic linker using the same rules. (This process may occur recursively, if those objects in turn have dependencies, and so on.)
This issue, and #17, led me to a couple other features that would be really useful to me, and if I'm able to, I will try to help and make a pull request:
#include "myfile.h"
is currently a parse-error. It would be nice to be able to include local headers.
Edit: I just saw that bic
does accept -I/include/dir
, but it's not in the usage string for --help
.CFILE: Parse, evaluate and call a function called 'main' within the file.
The call a function called main
thing, I can see being really useful. I wish I could just evaluate one or more C files, even if they don't have a main
function (to pull in function definitions). bic
currently throws an error if there is no main()
:
error: Could not resolve identifier main.
That last feature would enable "startup scripts" for bic
, like .pystartup
is for python
, and would also allow using a shebang with bic
(#!/usr/bin/env bic
) on arbitrary C files (they would be like interpreted C scripts).
These two things probably need a new issue, but I've already made two in one day and I don't want to flood you with feature requests (especially with no pull-requests to go with them). The thing is, I have been looking for something like bic
for a long time. I have cling
(REPL for C++), and I've written my own little C-snippet compiler that just compiles arbitrary C code/files with decent defaults, but it's not a REPL. So I really appreciate you putting this out there. I'd like to hear what you think about the two bullet-points above, even if it's just "never gonna happen" or "make a PR or go home".
TLDR: Issue could probably be renamed: -l fails on dependency lib if it's a linker script.
Oh yeh, and I was wrong about the ~/.local/lib
thing anyway. dlopen
knows where to find libraries because of ldconfig
(/etc/ld.so.conf
), and if you wanted to load a library from anywhere else all you would need to do is provide the absolute path to it. I don't think bic
has to mess with custom library paths like -L
for gcc
/clang
.
I just found this, which could possibly help bic
deal with GNU linker scripts. If you knew that libm
was requested, you could get the absolute file path from <gnu/lib-names.h>
. Something like:
#include <dlfcn.h>
#include <gnu/lib-names.h>
int open_library(char* libname) {
if (strcmp(libname, "m") == 0) {
if (dlopen(LIBM_SO, RTLD_NOW | RTLD_GLOBAL)) {
printf("Loaded libm from lib-names.h: %s\n", LIBM_SO);
return 1;
}
}
// ...fallback to normal behavior.
return 0;
}
The gnu/lib-names.h
on my machine pulls in the definitions based on architecture, but it's format looks exactly like this (just macro definitions for file paths that dlopen
can find).
It turns out that the linker-script stuff is specific to the linker program, not dlopen
. Long story short, a parser for the scripts would probably need to be written which is a whole other can of worms to open.
Many thanks for looking at this. I would have thought that dlopen()
would be smart enough to know where to find libm
and open it for you. I've just tried on my machine and it appears to work (I'm running Arch Linux):
$ cat test.c
#include <math.h>
double mysin(double d)
{
return sin(d);
}
$ gcc -lm -shared -o foo.so test.c
$ ./src/bic -l ./foo.so
BIC> double mysin(double d);
BIC> mysin(0.5);
0.479426
So not too sure exactly what is going on.
If you knew that libm was requested, you could get the absolute file path from
<gnu/lib-names.h>
I really like this idea and it's a proper fix for #17. I'll cobble something together and push it today. I'm not too sure if this will help opening libcolr.so
though as dlopen()
doesn't call back into bic
's code to query where to find libm
.
In regards to the other points you've raised, please feel free to raise issues for them. I think they're great ideas and the ability for bic
to parse multiple source files without calling main()
was something that was on my radar anyway. I never thought about using bic
as a scripting engine with a #!/usr/bin/env bic
before that would be really cool! Anyway if you could raise the issues we can talk about them in more depth there and flesh out how this will all work.
Thanks!
I noticed that any library file I use has to be located in the system/global directory. Things like
-l ./libforme.so
are not allowed.-l forme
is not allowed either if the file is in the current directory. It would be nice to at least allow an absolute path to the libraries that are loaded.I'm having other issues with libraries. I'll probably post another report for those.