2

I'm using XS to create a Perl Module which uses a C library.

For testing purposes, I've created a test library which has two simple functions:

void kzA()  (does a simple printf)
void kzB(int i, char *str) (does a printf of the received parameters)

I've also created some glue in XS, in order, for now, to access the kzA() function: (I'm only showing the function itself, but the includes are there, too, in the XS)

void
ka()
    CODE:
        printf("Before kzA()\n");
        kzA();
        printf("After kzA()\n");

So, I compiled the test library as fc.so, and it is in the same directory as my xs file, and my Makefile.PL (/workspace/LirePivots)

In my Makefile.PL, I set the LIBS key to ['-L/workspace/LirePivots -l:fc.so'], but when executing it with perl (perl Makefile.PL), it says "Warning (mostly harmless): No library found for -l:fc.so" It then writes a Makefile which does NOT mention said library. And then, after compiling (with "make") and installing (with "sudo make install"), when I run my test script which calls the ka() function from my module, I get the line "before", but the kzA() function isn't called, obviously, because it cannot find the kzA symbol, and the program stops there.

Creating a C test program which I would link with the very same arguments (-l:fc.so -L/workspace/LirePivots) does work, and, as long as I put the path in LD_LIBRARY_PATH, it finds the function and runs it correctly.

I also tried renaming the library libfc.so, and changing the -l part to "-lfc", but it didn't work either. It never manages to find the library.

Does anyone know what I do wrong ?

EDIT: As requested, I created a minimum example: https://github.com/kzwix/xsTest To run it, you'll need to have a Linux with Perl 5, along with XS (package perl-devel, on Redhat). And a C compiler, and make, obviously.

Kzwix
  • 161
  • 7
  • Which OS is this? Can you upload a complete minimal example on e.g. GitHub? – Håkon Hægland Jul 07 '21 at 10:35
  • It's on a Redhat Linux, and it's a container, as the /workspace can let you guess. We use VSCode and Docker for our environments, but I'll have a hard time giving you the full environment, obviously. – Kzwix Jul 07 '21 at 11:06
  • As requested, I created a GitHub repository: https://github.com/kzwix/xsTest – Kzwix Jul 07 '21 at 11:58
  • 1
    I have added [two pull requests](https://github.com/kzwix/xsTest/pulls). Using these PRs I am able to run `xsModule::ka()` via the [`test_module.pl`](https://github.com/kzwix/xsTest/blob/52154f522e177ed3763ba00768831762dc638890/test_module.pl) script. I am on Ubuntu 21.04 – Håkon Hægland Jul 07 '21 at 12:55
  • Why do you pass the -l option *after* the .o file ? – Kzwix Jul 07 '21 at 13:04
  • 1
    See [this](https://stackoverflow.com/a/8640681/2173773) answer – Håkon Hægland Jul 07 '21 at 13:07
  • Also, my problem never was about running the ka() function. It was that the ka() function did not run the kzA() function, because the module's .so library (so, in the GitHub example, "xsModule.so") wasn't properly linked to the fc.so library. Which happens because the Makefile.PL execution doesn't seem to find the library, despite it being in the directory specified by the -L option – Kzwix Jul 07 '21 at 13:13
  • If you run the script I added `test_module.pl`, what output do you get? – Håkon Hægland Jul 07 '21 at 13:15
  • after making sure I copied everything needed to the xsModule directory, and after running "perl Makefile.PL" and "make", running "./test_module.pl" prints the following two lines: "Fonction ka(): Avant appel kzA()" (which is normal, and expected), and "perl: symbol lookup error: /workspace/xsTest/xsModule/blib/arch/auto/xsModule/xsModule.so: undefined symbol: kzA" (because it wasn't properly linked to fc.so) – Kzwix Jul 07 '21 at 13:19
  • Ok great, it works fine here. It prints `Fonction Kzwix A` here and no errors. So it must be something with the setup on your machine that is different from mine – Håkon Hægland Jul 07 '21 at 13:21
  • What is the output of `ldd /workspace/xsTest/xsModule/blib/arch/auto/xsModule/xsModule.so` ? – Håkon Hægland Jul 07 '21 at 13:23
  • linux-vdso.so.1 => (hex value) libc.so.6 => (another hex value) /lib64/ld-linux-x86-64.so.2 => (yet another hex value) - I had already checked with ldd, and during the call to "make", I saw that there are no -L or -l parameters while creating the xsModule.so library – Kzwix Jul 07 '21 at 13:26
  • [Here](https://pastebin.com/i9WL7Jxh) is the output I get. Note that it says *"Warning: -L.. changed to -L/home/hakon/test/perl/xsTest/xsModule/.."* ... And this is the linker command that `make` used: `LD_RUN_PATH="/home/hakon/test/perl/xsTest/xsModule/.." cc -shared -O2 -L/usr/local/lib -fstack-protector-strong xsModule.o -o blib/arch/auto/xsModule/xsModule.so \ -L/home/hakon/test/perl/xsTest/xsModule/.. -l:fc.so` – Håkon Hægland Jul 07 '21 at 13:31
  • I got the "warning: -L.. changed to (...)" line, but that was while running "perl Makefile.PL". The line was followed with "Warning (mostly harmless): No library found for -l:fc.so". My line for linking the library was: "gcc -shared -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -Wl,-z,relro xsModule.o -o blib/arch/auto/xsModule/xsModule.so" – Kzwix Jul 07 '21 at 13:42
  • *"It's on a Redhat Linux, and it's a container"* Can you provide a minimal `Dockerfile` ? Then I can try to reproduce. – Håkon Hægland Jul 07 '21 at 18:31

1 Answers1

1

Ok, I still don't know the reason why it wouldn't find the library. But I found a workaround:

By adding the test library as "libfc.so" to /usr/lib, then running "sudo ldconfig", the library got added to the cache (when named fc.so, even if in /usr/lib, ldconfig would not add it. Also, it wouldn't work with symbolic links, either, I had to really copy it there).

After the library got added to the cache, "perl Makefile.PL" would still not find the library. I had to use "-L/usr/lib" in addition to "-lfc" for it to at long last find the library, and "agree" to add the parameters to the link step of the library.

After this happened, I could compile with "make", and executing the test program did work as originally intended (I saw both the "before" and "after" printf, and I saw the one from the function in the kzA() function from libfc.so)

Thanks Håkon Hægland for helping.

(I can't provide the Dockerfiles, they link to images internal to my organization, which I'm not allowed to share)

Kzwix
  • 161
  • 7