Beatnik has asked for the wisdom of the Perl Monks concerning the following question:

Hey, Altho this is somewhat off-topic, Inline is still Perl :)
Anyway, on with the question. I've been trying to use gd (GD's daddy), in an Inline C snippet. I passed a few obstacles but now I'm stuck. it seems that -lgd doesn't get included in Makefile.PL nor Makefile.
The code...
#!/usr/bin/perl use Inline Config => FORCE_BUILD => 1, CLEAN_AFTER_BUILD => 0; use Inline C => Config => LIBS => '-L/usr/lib -lgd'; #I tried variations of the above line use Inline C => Config => AUTO_INCLUDE => '#include "gd.h"'; #Apparently can't use #include "gd.h" in the code itself use Inline C => 'DATA'; outtext(); __END__ __C__ int outtext() { gdImagePtr im; FILE *out; im = gdImageCreate(100,100); out = fopen("foo.jpg", "wb"); gdImageJpeg(im, out,-1); fclose(out); gdImageDestroy(im); return 1; }
Error returned is :perl: relocation error: /path/_Inline/lib/auto/gdexample_pl_2120/gdexample_pl_2120.so: undefined symbol: gdImageCreate Needless to say gdImageCreate is a function in the gd lib.
When compiling the regular C code with normal params, it works fine :(
#include <stdio.h> #include "gd.h" int main(void) { gdImagePtr im; FILE *out; im = gdImageCreate(100,100); out = fopen("foo.jpg", "wb"); gdImageJpeg(im, out,-1); fclose(out); gdImageDestroy(im); return 1; }
with gcc -o gdexample gdexample.c -lgd Any help would be appreciated a lot...

Greetz
Beatnik
... Quidquid perl dictum sit, altum viditur.

Replies are listed 'Best First'.
Re: Inline::C and gd
by rob_au (Abbot) on May 26, 2002 at 13:42 UTC
    Your problem here is that you have not compiled JPEG support into your GD library. By default, GD is built with PNG support, but to include JPEG support, you need to include version 6b or later of the JPEG library.

     

    Update

    With a little further experimentation, I have rebuilt the GD library with JPEG support and no longer encounter this error - To rebuild this library with JPEG support, I expanded the JPEG library into a parallel directory and updated to the GD Makefile to include the HAVE_JPEG flag, included the -ljpeg library and altered the include and library paths to include the JPEG source location.

     

      If I run the binary generated by the C source, it works just fine. I used GD for JPG and PNG manipulation in the past, a different pure C based manipulation of JPEG works too :) So I'm pretty sure it should work.
      Thanks for looking into this tho.

      Greetz
      Beatnik
      ... Quidquid perl dictum sit, altum viditur.
Re: Inline::C and gd
by derby (Abbot) on May 26, 2002 at 13:16 UTC
    Beatnik,

    This works for me (you can place the "include" within the code section). Your problem is quite odd since the c example works while the perl does not. If you do a "perl -V" do you see /usr/lib in the linker and libs section? Was your perl compiled with gcc? If it was another compiler/linker, that linker may not know about /usr/lib.

    #!/usr/local/bin/perl use Inline C => DATA => LIBS => '-lgd'; outtext(); __END__ __C__ #include "gd.h" int outtext() { gdImagePtr im; FILE *out; im = gdImageCreate(100,100); out = fopen("foo.jpg", "wb"); gdImageJpeg(im, out,-1); fclose(out); gdImageDestroy(im); return 1; }
    -derby
      a perl -V dump returns something like this :
      Compiler: cc='gcc', ccflags ='-fno-strict-aliasing -I/usr/local/include', Linker and Libraries: ld='gcc', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lnsl -ldl -lm -lc -lcrypt -lutil perllibs=-lnsl -ldl -lm -lc -lcrypt -lutil libc=/lib/libc-2.2.4.so, so=so, useshrplib=false, libperl=libperl. +a Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynami +c' cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib'
      When I run the code you provided, I still get an error :)
      Had problems bootstrapping Inline module 'derby_pl_e0f6' Can't load '/path/derby/_Inline/lib/auto/derby_pl_e0f6/derby_pl_e0f6.s +o' for module derby_pl_e0f6: /home/beatnik/code/cstuff/gd/derby/_Inli +ne/lib/auto/derby_pl_e0f6/derby_pl_e0f6.so: undefined symbol: jpeg_de +stroy at /usr/lib/perl5/5.6.1/i386-linux/DynaLoader.pm line 206. etc
      I'm using Perl 5.6.1 on RH7.2 and Inline 0.43.
      gd.h is at
      /usr/include/gd.h /usr/local/include/gd.h
      and libgd is at
      /usr/lib/libgd.so.1 /usr/lib/libgd.so.1.8 /usr/lib/libgd.so.1.8.4 /usr/lib/libgdk.so.1.0.6 /usr/lib/libgdk.so.1 /usr/lib/libgd.a /usr/lib/libgd.so /usr/local/lib/libgd.a
      If this helps somewhat...

      Greetz
      Beatnik
      ... Quidquid perl dictum sit, altum viditur.
        Okay. That's a different error message (undefined symbol jpeg_destroy). Doing an "nm -a libgd.so | grep jpeg_destroy" on my system shows that libgd.so has an unresolved dependency for that function. jpeg_destory is part of the jpg library. Do you have libjpg.so anywhere in your libpths?

        -derby

Re: Inline::C and gd
by Beatnik (Parson) on May 26, 2002 at 21:56 UTC
    Since I can't edit the root node, here are some updates...
    Someone on inline@perl.org pointed me to some settings (which I also tried ofcourse). They seem correct and the makefile and out.make reflect it (something I failed to check before). I currently have errors on bootstrapping...
    Had problems bootstrapping Inline module 'gdexample2_pl_9960' Can't load '/path/_Inline/lib/auto/gdexample2_pl_9960/gdexample2_pl_99 +60.so' for module gdexample2_pl_9960: /path/_Inline/lib/auto/gdexampl +e2_pl_9960/gdexample2_pl_9960.so: undefined symbol: jpeg_destroy at / +usr/lib/perl5/5.6.1/i386-linux/DynaLoader.pm line 206. DynaLoader::croak('Can\'t load \'/path/_Inline/lib/auto/gdex...') +called at /usr/lib/perl5/5.6.1/i386-linux/DynaLoader.pm line 206 DynaLoader::bootstrap('gdexample2_pl_9960') called at (eval 26) li +ne 9 eval ' package main; push @main::ISA, qw(gdexample2_pl_9960) unless $module eq "main"; local $gdexample2_pl_9960::VERSION = \'0.00\'; package gdexample2_pl_9960; push @gdexample2_pl_9960::ISA, qw(Exporter DynaLoader); sub dl_load_flags { 0x00 } gdexample2_pl_9960::->bootstrap; ;' called at /usr/lib/perl5/site_perl/5.6.1/Inline.pm line 432 Inline::load('Inline::C=HASH(0x8107f58)') called at /usr/lib/perl5 +/site_perl/5.6.1/Inline.pm line 267 Inline::glue('Inline::C=HASH(0 +x8107f58)') called at /usr/lib/perl5/site_perl/5.6.1/Inline.pm line 1 +94 Inline::init called at (eval 1) line 5 Inline::INIT() called at (eval 26) line 0 eval {...} called at (eval 26) line 0 at gdexample2.pl line 0 INIT failed--call queue aborted.
    The tweak is only in the Config line..
    > use Inline 'NOCLEAN'; use Inline 'C' => 'Config' => AUTO_INCLUDE => '#include "gd.h"', 'INC' => '-I/usr/include ', 'LIBS' => '-L/usr/lib -lgd ', ;
    I have no idea what this all means altho I guess it has to do with loading up the XS linked code into the perl module :)

    I DID IT!
    I tried all sorts of things and eventually considered adding libjpeg to the lib list (altho plain C source didnt need it for compiling). This is a complete listing:
    #!/usr/bin/perl use Inline Config => FORCE_BUILD => 1, CLEAN_AFTER_BUILD => 0; use Inline C => Config => LIBS => '-L/usr/lib -lgd -ljpeg', INC => '-I/usr/include', AUTO_INCLUDE => '#include "gd.h"'; use Inline C => 'DATA'; outtext(); __END__ __C__ int outtext() { gdImagePtr im; FILE *out; im = gdImageCreate(100,100); out = fopen("foo.jpg", "wb"); gdImageJpeg(im, out,-1); fclose(out); gdImageDestroy(im); return 1; }
    Now I assume I'll need to include libpng too when I want to do PNG based stuff :)

    Greetz
    Beatnik
    ... Quidquid perl dictum sit, altum viditur.