I found a bug in the Inline caching system --- and would like to help to fix it:

Here is a trivial little perl program that attempts to access the library libpaper:

use Inline ("C" => <<'END'); # missing:  "LIBS" => '-lpaper'
#include <paper.h>
char* my_papersize() { paperinit(); return defaultpapername(); }
END

Running this script produces an error message because I forgot to refer to
the libpaper library. If I fix the error and try the same program again, I still
get the error message --- even though the program is now correct:

use Inline ("C" => <<'END', "LIBS" => '-lpaper');
#include <paper.h>
char* my_papersize() { paperinit(); return defaultpapername(); }
END

What should happen is that Inline compiles the code with the correct
library and succeeds.

Cause of the problem:
A change in the "LIBS" option doesn't change the identifier of the
compiled C-object; hence the module is not compiled again.

Quick fix:
A quick-and dirty fix is to include the LIBS option in the MD5 hash for the
cache identifier:  In version 0.44, line 420 could be changed from
       $o->{INLINE}{md5} = Digest::MD5::md5_hex($o->{API}{code});
to this fixed version:

       $o->{INLINE}{md5} = Digest::MD5::md5_hex(
           "// LIBS=".($o->{CONFIG}->{LIBS}||"").$o->{API}{code}
       );
After this change, the problem disappears: changing the LIBS attribute
causes Inline to recompile the program.

Alternative solution:
I understand that the .inl file should actually solve problems like this. The following code in Inline.pm (about line 935 in version 0.44)
writes some important information to be checked before using the
compiled module is re-used:

print INL Inline::denter->new()
     ->indent(*md5, $o->{INLINE}{md5},
              *name, $o->{API}{module},
              *version, $o->{CONFIG}{VERSION},
              *language, $o->{API}{language},
              *language_id, $o->{API}{language_id},
              *installed, $o->{CONFIG}{_INSTALL_},
              *date_compiled, scalar localtime,
              *inline_version, $Inline::VERSION,
              *ILSM, { map {($_, $o->{INLINE}{"ILSM_$_"})}
                       (qw( module suffix type ))
                     },
              *Config, { (map {($_,$Config{$_})}
                          (qw( archname osname osvers
                               cc ccflags ld so version
                             ))),
                         (apiversion => $apiversion),
                       },
             );

The LIBS option is missing here --- it could be added here instead of
putting it into the MD5 hash.

Note:
This problem doesn't only apply to the LIBS attribute but to all attributes
that affect the compilation. They all should be added --- either to the MD5 hash or to the .inl file. Because I don't know all details of Inline, I can't suggest a fix
that catches them all.

I would suggest to add all configuration options of the Inline object to the MD5
hash and crucial options to the .inl file.


Best regards,

Yaakov Belch



Reply via email to